// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { public class PlatformHelper { private OperatingSystem os; private RuntimeFramework rt; // Set whenever we fail to support a list of platforms private string reason = string.Empty; // Defined here and used in tests. We can't use PlatformID.Unix // if we are building on .NET 1.0 or 1.1 and the values are different on Mono public static readonly PlatformID UnixPlatformID_Microsoft = (PlatformID) 4; public static readonly PlatformID UnixPlatformID_Mono = (PlatformID)128; /// /// Comma-delimited list of all supported OS platform constants /// public static readonly string OSPlatforms = "Win,Win32,Win32S,Win32NT,Win32Windows,WinCE,Win95,Win98,WinMe,NT3,NT4,NT5,NT6,Win2K,WinXP,Win2003Server,Vista,Win2008Server,Unix,Linux"; /// /// Comma-delimited list of all supported Runtime platform constants /// public static readonly string RuntimePlatforms = "Net,NetCF,SSCLI,Rotor,Mono"; /// /// Default constructor uses the operating system and /// common language runtime of the system. /// public PlatformHelper() { this.os = Environment.OSVersion; this.rt = RuntimeFramework.CurrentFramework; } /// /// Contruct a PlatformHelper for a particular operating /// system and common language runtime. Used in testing. /// /// OperatingSystem to be used public PlatformHelper( OperatingSystem os, RuntimeFramework rt ) { this.os = os; this.rt = rt; } /// /// Test to determine if one of a collection of platforms /// is being used currently. /// /// /// public bool IsPlatformSupported( string[] platforms ) { foreach( string platform in platforms ) if ( IsPlatformSupported( platform ) ) return true; return false; } /// /// Tests to determine if the current platform is supported /// based on a platform attribute. /// /// The attribute to examine /// public bool IsPlatformSupported( Attribute platformAttribute ) { //Use reflection to avoid dependency on a particular framework version string include = (string)Reflect.GetPropertyValue( platformAttribute, "Include", BindingFlags.Public | BindingFlags.Instance ); string exclude = (string)Reflect.GetPropertyValue( platformAttribute, "Exclude", BindingFlags.Public | BindingFlags.Instance ); try { if (include != null && !IsPlatformSupported(include)) { reason = string.Format("Only supported on {0}", include); return false; } if (exclude != null && IsPlatformSupported(exclude)) { reason = string.Format("Not supported on {0}", exclude); return false; } } catch( ArgumentException ex ) { reason = string.Format( "Invalid platform name: {0}", ex.ParamName ); return false; } return true; } /// /// Test to determine if the a particular platform or comma- /// delimited set of platforms is in use. /// /// Name of the platform or comma-separated list of platform names /// True if the platform is in use on the system public bool IsPlatformSupported( string platform ) { if ( platform.IndexOf( ',' ) >= 0 ) return IsPlatformSupported( platform.Split( new char[] { ',' } ) ); string platformName = platform.Trim(); bool nameOK = false; string versionSpecification = null; string[] parts = platformName.Split( new char[] { '-' } ); if ( parts.Length == 2 ) { platformName = parts[0]; versionSpecification = parts[1]; } switch( platformName.ToUpper() ) { case "WIN": case "WIN32": nameOK = os.Platform.ToString().StartsWith( "Win" ); break; case "WIN32S": nameOK = os.Platform == PlatformID.Win32S; break; case "WIN32WINDOWS": nameOK = os.Platform == PlatformID.Win32Windows; break; case "WIN32NT": nameOK = os.Platform == PlatformID.Win32NT; break; case "WINCE": nameOK = (int)os.Platform == 3; // Not defined in .NET 1.0 break; case "WIN95": nameOK = os.Platform == PlatformID.Win32Windows && os.Version.Major == 4 && os.Version.Minor == 0; break; case "WIN98": nameOK = os.Platform == PlatformID.Win32Windows && os.Version.Major == 4 && os.Version.Minor == 10; break; case "WINME": nameOK = os.Platform == PlatformID.Win32Windows && os.Version.Major == 4 && os.Version.Minor == 90; break; case "NT3": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 3; break; case "NT4": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 4; break; case "NT5": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 5; break; case "WIN2K": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 5 && os.Version.Minor == 0; break; case "WINXP": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 5 && os.Version.Minor == 1; break; case "WIN2003SERVER": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 5 && os.Version.Minor == 2; break; case "NT6": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 6; break; // TODO: Distinguish Vista SP1 from Server 2008 case "VISTA": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 6 && os.Version.Minor == 0 && os.Version.Build != 6001; break; case "WIN2008SERVER": nameOK = os.Platform == PlatformID.Win32NT && os.Version.Major == 6 && os.Version.Minor == 0 && os.Version.Build == 6001; break; case "UNIX": case "LINUX": nameOK = os.Platform == UnixPlatformID_Microsoft || os.Platform == UnixPlatformID_Mono; break; case "NET": nameOK = rt.Runtime == RuntimeType.Net; break; case "NETCF": nameOK = rt.Runtime == RuntimeType.NetCF; break; case "SSCLI": case "ROTOR": nameOK = rt.Runtime == RuntimeType.SSCLI; break; case "MONO": nameOK = rt.Runtime == RuntimeType.Mono; // Special handling because Mono 1.0 profile has version 1.1 if ( versionSpecification == "1.0" ) versionSpecification = "1.1"; break; default: throw new ArgumentException( "Invalid platform name", platform.ToString() ); } if ( nameOK ) { if ( versionSpecification == null ) return true; Version version = new Version( versionSpecification ); if ( rt.Version.Major == version.Major && rt.Version.Minor == version.Minor && ( version.Build == -1 || rt.Version.Build == version.Build ) && ( version.Revision == -1 || rt.Version.Revision == version.Revision ) ) return true; } this.reason = "Only supported on " + platform; return false; } /// /// Return the last failure reason. Results are not /// defined if called before IsSupported( Attribute ) /// is called. /// public string Reason { get { return reason; } } } }