Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recognize .NET Framework versions 4.5 and higher #450

Merged
merged 4 commits into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ***********************************************************************
// ***********************************************************************
// Copyright (c) 2016 Charlie Poole, Rob Prouse
//
// Permission is hereby granted, free of charge, to any person obtaining
Expand Down Expand Up @@ -63,6 +63,7 @@ public ModuleDefinition MainModule
#if !NETSTANDARD2_0
public RuntimeFramework TargetFramework
{
// TODO: Construct from CLR Version?
get { return new RuntimeFramework(RuntimeType.Any, _targetFrameworkHelper.TargetRuntimeVersion); }
}
#endif
Expand All @@ -78,4 +79,4 @@ private AssemblyDefinition GetAssemblyDefinition()
}
}
}
#endif
#endif
117 changes: 60 additions & 57 deletions src/TestEngine/nunit.engine.core/RuntimeFramework.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,28 @@ public RuntimeFramework(RuntimeType runtime, Version version)
}

/// <summary>
/// Construct from a runtime type, version and profile. If the version has
/// two parts, it is taken as a framework version. If it has three
/// or more, it is taken as a CLR version. In either case, the other
/// version is deduced based on the runtime type and provided version.
/// Construct from a runtime type, version and profile. The version
/// may be either a framework version or a CLR version. If a CLR
/// version is provided, we try to deduce the framework version but
/// this may not always be successful, in which case a version of
/// 0.0 is used.
/// </summary>
/// <param name="runtime">The runtime type of the framework.</param>
/// <param name="version">The version of the framework.</param>
/// <param name="profile">The profile of the framework. Null if unspecified.</param>
public RuntimeFramework(RuntimeType runtime, Version version, string profile)
{
Runtime = runtime;
FrameworkVersion = ClrVersion = version;

if (version.Build < 0)
InitFromFrameworkVersion(version);
else
InitFromClrVersion(version);
// Version 0.0 means any version so we can't deduce anything
if (version != DefaultVersion)
{
if (IsFrameworkVersion(version))
ClrVersion = GetClrVersionForFramework(version);
else
FrameworkVersion = GetFrameworkVersionForClr(version);
}

Profile = profile;

Expand All @@ -97,62 +103,59 @@ public RuntimeFramework(RuntimeType runtime, Version version, string profile)
}
}

private void InitFromFrameworkVersion(Version version)
private bool IsFrameworkVersion(Version v)
{
this.FrameworkVersion = this.ClrVersion = version;

if (version.Major > 0) // 0 means any version
switch (Runtime)
{
case RuntimeType.Net:
case RuntimeType.Mono:
case RuntimeType.Any:
switch (version.Major)
{
case 1:
switch (version.Minor)
{
case 0:
this.ClrVersion = Runtime == RuntimeType.Mono
? new Version(1, 1, 4322)
: new Version(1, 0, 3705);
break;
case 1:
if (Runtime == RuntimeType.Mono)
this.FrameworkVersion = new Version(1, 0);
this.ClrVersion = new Version(1, 1, 4322);
break;
default:
ThrowInvalidFrameworkVersion(version);
break;
}
break;
case 2:
case 3:
this.ClrVersion = new Version(2, 0, 50727);
break;
case 4:
this.ClrVersion = new Version(4, 0, 30319);
break;
default:
ThrowInvalidFrameworkVersion(version);
break;
}
break;
}
// All known framework versions have either two components or
// three. If three, then the Build is currently less than 3.
return v.Build < 3 && v.Revision == -1;
}

private static void ThrowInvalidFrameworkVersion(Version version)
private Version GetClrVersionForFramework(Version frameworkVersion)
{
throw new ArgumentException("Unknown framework version " + version.ToString(), "version");
switch (Runtime)
{
case RuntimeType.Net:
case RuntimeType.Any:
switch (frameworkVersion.Major)
{
case 1:
switch (frameworkVersion.Minor)
{
case 0:
return new Version(1, 0, 3705);
case 1:
return new Version(1, 1, 4322);
}
break;
case 2:
case 3:
return new Version(2, 0, 50727);
case 4:
return new Version(4, 0, 30319);
}
break;
case RuntimeType.Mono:
switch (frameworkVersion.Major)
{
case 1:
return new Version(1, 1, 4322);
case 2:
case 3:
return new Version(2, 0, 50727);
case 4:
return new Version(4, 0, 30319);
}
break;
}

throw new ArgumentException("Unknown framework version " + frameworkVersion.ToString(), "version");
}

private void InitFromClrVersion(Version version)
private Version GetFrameworkVersionForClr(Version clrVersion)
{
this.FrameworkVersion = new Version(version.Major, version.Minor);
this.ClrVersion = version;
if (Runtime == RuntimeType.Mono && version.Major == 1)
this.FrameworkVersion = new Version(1, 0);
return Runtime == RuntimeType.Mono && clrVersion.Major == 1
? new Version(1, 0)
: new Version(clrVersion.Major, clrVersion.Minor);
}

/// <summary>
Expand Down
23 changes: 12 additions & 11 deletions src/TestEngine/nunit.engine.tests/RuntimeFrameworkTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ public void CanCreateUsingFrameworkVersion(FrameworkData data)
[TestCaseSource(nameof(frameworkData))]
public void CanCreateUsingClrVersion(FrameworkData data)
{
// Versions 3.x and 4.5 or higher can't be created using CLR version
Assume.That(data.frameworkVersion.Major != 3);
Assume.That(data.frameworkVersion.Major != 4 || data.frameworkVersion.Minor == 0);

RuntimeFramework framework = new RuntimeFramework(data.runtime, data.clrVersion);
Assert.That(framework.Runtime, Is.EqualTo(data.runtime));
Expand Down Expand Up @@ -146,10 +148,6 @@ public bool CanLoad(RuntimeFramework f1, RuntimeFramework f2)
new RuntimeFramework(RuntimeType.Net, new Version(2,0,50727)),
new RuntimeFramework(RuntimeType.Net, new Version(2,0,40607)))
.Returns(false),
new TestCaseData(
new RuntimeFramework(RuntimeType.Mono, new Version(1,1)), // non-existent version but it works
new RuntimeFramework(RuntimeType.Mono, new Version(1,0)))
.Returns(true),
new TestCaseData(
new RuntimeFramework(RuntimeType.Mono, new Version(2,0)),
new RuntimeFramework(RuntimeType.Any, new Version(2,0)))
Expand Down Expand Up @@ -231,26 +229,29 @@ public override string ToString()
#pragma warning disable 414
static FrameworkData[] frameworkData = new FrameworkData[] {
new FrameworkData(RuntimeType.Net, new Version(1,0), new Version(1,0,3705), "net-1.0", ".NET 1.0", ".Net Framework,Version=v1.0"),
//new FrameworkData(RuntimeType.Net, new Version(1,0,3705), new Version(1,0,3705), "net-1.0.3705", "Net 1.0.3705"),
//new FrameworkData(RuntimeType.Net, new Version(1,0), new Version(1,0,3705), "net-1.0.3705", "Net 1.0.3705"),
new FrameworkData(RuntimeType.Net, new Version(1,1), new Version(1,1,4322), "net-1.1", ".NET 1.1", ".Net Framework,Version=v1.1"),
//new FrameworkData(RuntimeType.Net, new Version(1,1,4322), new Version(1,1,4322), "net-1.1.4322", "Net 1.1.4322"),
new FrameworkData(RuntimeType.Net, new Version(2,0), new Version(2,0,50727), "net-2.0", ".NET 2.0", ".Net Framework,Version=2.0"),
//new FrameworkData(RuntimeType.Net, new Version(2,0,40607), new Version(2,0,40607), "net-2.0.40607", "Net 2.0.40607"),
//new FrameworkData(RuntimeType.Net, new Version(2,0,50727), new Version(2,0,50727), "net-2.0.50727", "Net 2.0.50727"),
new FrameworkData(RuntimeType.Net, new Version(3,0), new Version(2,0,50727), "net-3.0", ".NET 3.0", ".Net Framework,Version=3.0"),
new FrameworkData(RuntimeType.Net, new Version(3,5), new Version(2,0,50727), "net-3.5", ".NET 3.5", ".Net Framework,Version=3.5"),
new FrameworkData(RuntimeType.Net, new Version(4,0), new Version(4,0,30319), "net-4.0", ".NET 4.0", ".Net Framework,Version=4.0"),
new FrameworkData(RuntimeType.Net, new Version(4,5), new Version(4,0,30319), "net-4.5", ".NET 4.5", ".Net Framework,Version=4.5"),
new FrameworkData(RuntimeType.Net, new Version(4,5,1), new Version(4,0,30319), "net-4.5.1", ".NET 4.5.1", ".Net Framework,Version=4.5.1"),
new FrameworkData(RuntimeType.Net, new Version(4,5,2), new Version(4,0,30319), "net-4.5.2", ".NET 4.5.2", ".Net Framework,Version=4.5.2"),
new FrameworkData(RuntimeType.Net, new Version(4,6), new Version(4,0,30319), "net-4.6", ".NET 4.6", ".Net Framework,Version=4.6"),
new FrameworkData(RuntimeType.Net, new Version(4,6,1), new Version(4,0,30319), "net-4.6.1", ".NET 4.6.1", ".Net Framework,Version=4.6.1"),
new FrameworkData(RuntimeType.Net, new Version(4,6,2), new Version(4,0,30319), "net-4.6.2", ".NET 4.6.2", ".Net Framework,Version=4.6.2"),
new FrameworkData(RuntimeType.Net, new Version(4,7), new Version(4,0,30319), "net-4.7", ".NET 4.7", ".Net Framework,Version=4.7"),
new FrameworkData(RuntimeType.Net, new Version(4,7,1), new Version(4,0,30319), "net-4.7.1", ".NET 4.7.1", ".Net Framework,Version=4.7.1"),
new FrameworkData(RuntimeType.Net, new Version(4,7,2), new Version(4,0,30319), "net-4.7.2", ".NET 4.7.2", ".Net Framework,Version=4.7.2"),
new FrameworkData(RuntimeType.Net, new Version(4,8), new Version(4,0,30319), "net-4.8", ".NET 4.8", ".Net Framework,Version=4.8"),
new FrameworkData(RuntimeType.Net, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "net", ".NET", null),
new FrameworkData(RuntimeType.Mono, new Version(1,0), new Version(1,1,4322), "mono-1.0", "Mono 1.0", ".Net Framework,Version=1.0"),
new FrameworkData(RuntimeType.Mono, new Version(2,0), new Version(2,0,50727), "mono-2.0", "Mono 2.0", ".Net Framework,Version=2.0"),
//new FrameworkData(RuntimeType.Mono, new Version(2,0,50727), new Version(2,0,50727), "mono-2.0.50727", "Mono 2.0.50727"),
new FrameworkData(RuntimeType.Mono, new Version(3,5), new Version(2,0,50727), "mono-3.5", "Mono 3.5", ".Net Framework,Version=3.5"),
new FrameworkData(RuntimeType.Mono, new Version(4,0), new Version(4,0,30319), "mono-4.0", "Mono 4.0", ".Net Framework,Version=4.0"),
new FrameworkData(RuntimeType.Mono, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "mono", "Mono", null),
new FrameworkData(RuntimeType.Any, new Version(1,1), new Version(1,1,4322), "v1.1", "v1.1", null),
new FrameworkData(RuntimeType.Any, new Version(2,0), new Version(2,0,50727), "v2.0", "v2.0", null),
//new FrameworkData(RuntimeType.Any, new Version(2,0,50727), new Version(2,0,50727), "v2.0.50727", "v2.0.50727"),
new FrameworkData(RuntimeType.Any, new Version(3,5), new Version(2,0,50727), "v3.5", "v3.5", null),
new FrameworkData(RuntimeType.Any, new Version(4,0), new Version(4,0,30319), "v4.0", "v4.0", null),
new FrameworkData(RuntimeType.Any, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "any", "Any", null)
Expand Down
36 changes: 32 additions & 4 deletions src/TestEngine/nunit.engine/Services/RuntimeFrameworkService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ private void FindDotNetFrameworks()
}
else if (CheckInstallDword(versionKey))
{
// Versions 1.1 through 3.5
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, new Version(name.Substring(1))));
// Versons 1.1, 2.0, 3.0 and 3.5 are possible here
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, new Version(name.Substring(1, 3))));
}
}
}
Expand All @@ -349,6 +349,33 @@ private void FindExtremelyOldDotNetFrameworkVersions()
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, new Version("1.0." + build)));
}

private struct MinimumRelease
{
public readonly int Release;
public readonly Version Version;

public MinimumRelease(int release, Version version)
{
Release = release;
Version = version;
}
}

private static readonly MinimumRelease[] ReleaseTable = new MinimumRelease[]
{
// TODO: Make 3-component versions work correctly
new MinimumRelease(378389, new Version(4, 5)),
new MinimumRelease(378675, new Version(4, 5, 1)),
new MinimumRelease(379893, new Version(4, 5, 2)),
new MinimumRelease(393295, new Version(4, 6)),
new MinimumRelease(394254, new Version(4, 6, 1)),
new MinimumRelease(394802, new Version(4, 6, 2)),
new MinimumRelease(460798, new Version(4, 7)),
new MinimumRelease(461308, new Version(4, 7, 1)),
new MinimumRelease(461808, new Version(4, 7, 2)),
new MinimumRelease(528040, new Version(4, 8))
};

private void FindDotNetFourFrameworkVersions(RegistryKey versionKey)
{
foreach (string profile in new string[] { "Full", "Client" })
Expand All @@ -361,8 +388,9 @@ private void FindDotNetFourFrameworkVersions(RegistryKey versionKey)
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, new Version(4, 0), profile));

var release = (int)profileKey.GetValue("Release", 0);
if (release > 0) // TODO: Other higher versions?
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, new Version(4, 5)));
foreach (var entry in ReleaseTable)
if (release >= entry.Release)
_availableRuntimes.Add(new RuntimeFramework(RuntimeType.Net, entry.Version));

break; //If full profile found don't check for client profile
}
Expand Down