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

Add .NET Core 3.1 build of engine to access APIs for loading .NET Core assemblies correctly #778

Merged
merged 8 commits into from Jun 13, 2020
Merged
2 changes: 1 addition & 1 deletion .travis.yml
@@ -1,7 +1,7 @@
language: csharp
sudo: required

dotnet: 2.1.401
dotnet: 3.1.300
mono: 6.6.0

matrix:
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Expand Up @@ -2,7 +2,7 @@ branches:
except:
- /travis-.*/

image: Visual Studio 2017
image: Visual Studio 2019

build_script:
- ps: .\build.ps1 -Target "Appveyor" -Configuration "Release"
Expand Down
10 changes: 9 additions & 1 deletion azure-pipelines.yml
Expand Up @@ -7,9 +7,17 @@ jobs:

- job: Windows
pool:
vmImage: vs2017-win2016
vmImage: windows-2019

steps:

- task: UseDotNet@2
displayName: 'Install .NET Core 1.1.2'
inputs:
packageType: runtime
version: 1.1.2
installationPath: C:/Program Files/dotnet

- powershell: .\build.ps1 -Target Test -Configuration Release
displayName: Build and test

Expand Down
69 changes: 48 additions & 21 deletions build.cake
Expand Up @@ -36,6 +36,7 @@ var BIN_DIR = PROJECT_DIR + "bin/" + configuration + "/";
var NET35_BIN_DIR = BIN_DIR + "net35/";
var NETCOREAPP11_BIN_DIR = BIN_DIR + "netcoreapp1.1/";
var NETCOREAPP21_BIN_DIR = BIN_DIR + "netcoreapp2.1/";
var NETCOREAPP31_BIN_DIR = BIN_DIR + "netcoreapp3.1/";
var CHOCO_DIR = PROJECT_DIR + "choco/";
var TOOLS_DIR = PROJECT_DIR + "tools/";
var IMAGE_DIR = PROJECT_DIR + "images/";
Expand All @@ -54,12 +55,10 @@ var CONSOLE_TESTS_CSPROJ = PROJECT_DIR + "src/NUnitConsole/nunit3-console.tests/
var MOCK_ASSEMBLY_CSPROJ = PROJECT_DIR + "src/NUnitEngine/mock-assembly/mock-assembly.csproj";

var NETFX_FRAMEWORKS = new [] { "net20", "net35" }; //Production code targets net20, tests target nets35
var NETSTANDARD_FRAMEWORKS = new [] { "netstandard1.6", "netstandard2.0" };
var NETCORE_FRAMEWORKS = new [] { "netcoreapp1.1", "netcoreapp2.1" };

// Test Runners
var NET20_CONSOLE = BIN_DIR + "net20/" + "nunit3-console.exe";
var NETCORE21_CONSOLE = BIN_DIR + "netcoreapp2.1/" + "nunit3-console.dll";
var NETCORE31_CONSOLE = BIN_DIR + "netcoreapp3.1/" + "nunit3-console.dll";

// Test Assemblies
var ENGINE_TESTS = "nunit.engine.tests.dll";
Expand Down Expand Up @@ -202,28 +201,28 @@ Task("Build")

Information("Publishing .NET Core & Standard projects so that dependencies are present...");

foreach(var framework in NETSTANDARD_FRAMEWORKS)
foreach(var framework in new [] { "netstandard1.6", "netstandard2.0", "netcoreapp3.1" })
MSBuild(ENGINE_CSPROJ, CreateMSBuildSettings("Publish")
.WithProperty("TargetFramework", framework)
.WithProperty("PublishDir", BIN_DIR + framework));

foreach(var framework in NETSTANDARD_FRAMEWORKS)
foreach(var framework in new [] { "netstandard1.6", "netstandard2.0" })
MSBuild(ENGINE_API_CSPROJ, CreateMSBuildSettings("Publish")
.WithProperty("TargetFramework", framework)
.WithProperty("PublishDir", BIN_DIR + framework));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NUnit Engine API remains targeting netstandard2.0 only - the NuGet packaging ensures the correct Engine version is used.

I think having a .NET Standard assembly make use of a .NET Core assembly is a bit of a code smell, but I also think we have a larger issue to consider re: the API assemblys use of reflection to load the engine.


foreach(var framework in NETCORE_FRAMEWORKS)
foreach(var framework in new [] { "netcoreapp1.1", "netcoreapp2.1", "netcoreapp3.1" })
jnm2 marked this conversation as resolved.
Show resolved Hide resolved
MSBuild(ENGINE_TESTS_CSPROJ, CreateMSBuildSettings("Publish")
.WithProperty("TargetFramework", framework)
.WithProperty("PublishDir", BIN_DIR + framework));

MSBuild(CONSOLE_CSPROJ, CreateMSBuildSettings("Publish")
.WithProperty("TargetFramework", "netcoreapp2.1")
.WithProperty("PublishDir", BIN_DIR + "netcoreapp2.1"));
.WithProperty("TargetFramework", "netcoreapp3.1")
.WithProperty("PublishDir", BIN_DIR + "netcoreapp3.1"));

MSBuild(CONSOLE_TESTS_CSPROJ, CreateMSBuildSettings("Publish")
.WithProperty("TargetFramework", "netcoreapp2.1")
.WithProperty("PublishDir", BIN_DIR + "netcoreapp2.1"));
.WithProperty("TargetFramework", "netcoreapp3.1")
.WithProperty("PublishDir", BIN_DIR + "netcoreapp3.1"));

});

Expand Down Expand Up @@ -280,20 +279,20 @@ Task("TestNet20Console")
});

//////////////////////////////////////////////////////////////////////
// TEST .NET CORE 2.1 CONSOLE
// TEST .NET CORE 3.1 CONSOLE
//////////////////////////////////////////////////////////////////////

Task("TestNetCore21Console")
.Description("Tests the .NET Core 2.1 console runner")
Task("TestNetCore31Console")
.Description("Tests the .NET Core 3.1 console runner")
.IsDependentOn("Build")
.OnError(exception => { ErrorDetail.Add(exception.Message); })
.Does(() =>
{
if (IsDotNetCoreInstalled)
{
RunDotnetCoreTests(
NETCORE21_CONSOLE,
NETCOREAPP21_BIN_DIR,
NETCORE31_CONSOLE,
NETCOREAPP31_BIN_DIR,
CONSOLE_TESTS,
"netcoreapp2.1",
ref ErrorDetail);
Expand All @@ -312,6 +311,7 @@ Task("TestNetCore21Console")
Task("TestNetStandard16Engine")
.Description("Tests the .NET Standard Engine")
.IsDependentOn("Build")
.WithCriteria(!BuildSystem.IsRunningOnAzurePipelines) //Unable to find Azure build supporting both .NET Core 1.1 and .NET Core 3.1
.OnError(exception => { ErrorDetail.Add(exception.Message); })
.Does(() =>
{
Expand Down Expand Up @@ -354,6 +354,32 @@ Task("TestNetStandard20Engine")
});


//////////////////////////////////////////////////////////////////////
// TEST NETCORE 3.1 ENGINE
//////////////////////////////////////////////////////////////////////

Task("TestNetCore31Engine")
.Description("Tests the .NET Core 3.1 Engine")
.IsDependentOn("Build")
.OnError(exception => { ErrorDetail.Add(exception.Message); })
.Does(() =>
{
if (IsDotNetCoreInstalled)
{
RunDotnetCoreTests(
NETCORE31_CONSOLE,
NETCOREAPP31_BIN_DIR,
ENGINE_TESTS,
"netcoreapp3.1",
ref ErrorDetail);
}
else
{
Warning("Skipping .NET Core 3.1 engine tests because .NET Core is not installed");
}
});


//////////////////////////////////////////////////////////////////////
// PACKAGE
//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -633,10 +659,10 @@ bool CheckIfDotNetCoreInstalled()
{
try
{
Information("Checking if .NET Core SDK is installed");
Information("Checking if .NET Core SDK is installed...");
StartProcess("dotnet", new ProcessSettings
{
Arguments = "--version"
Arguments = "--info"
});
}
catch(Exception)
Expand Down Expand Up @@ -667,7 +693,7 @@ FilePath GetResultXmlPath(string testAssembly, string framework)
{
var assemblyName = System.IO.Path.GetFileNameWithoutExtension(testAssembly);

// Workaround for https://github.com/nunit/nunit-console/issues/501
// Required for test suites running under NUnitLite
CreateDirectory($@"test-results\{framework}");

return MakeAbsolute(new FilePath($@"test-results\{framework}\{assemblyName}.xml"));
Expand Down Expand Up @@ -744,13 +770,14 @@ Task("Rebuild")
Task("TestConsole")
.Description("Builds and tests the console runner")
.IsDependentOn("TestNet20Console")
.IsDependentOn("TestNetCore21Console");
.IsDependentOn("TestNetCore31Console");

Task("TestEngine")
.Description("Builds and tests the engine")
.IsDependentOn("TestNet20Engine")
.IsDependentOn("TestNetStandard16Engine")
.IsDependentOn("TestNetStandard20Engine");
.IsDependentOn("TestNetStandard20Engine")
.IsDependentOn("TestNetCore31Engine");

Task("Test")
.Description("Builds and tests the engine")
Expand Down Expand Up @@ -779,7 +806,7 @@ Task("Travis")

Task("Default")
.Description("Builds the engine and console runner")
.IsDependentOn("Build"); // Rebuild?
.IsDependentOn("Build");

//////////////////////////////////////////////////////////////////////
// EXECUTION
Expand Down
13 changes: 13 additions & 0 deletions nuget/engine/nunit.engine.nuspec
Expand Up @@ -36,6 +36,14 @@
<dependency id="System.Diagnostics.Process" version="4.3.0" exclude="compile" />
<dependency id="System.Xml.XPath.XmlDocument" version="4.3.0" exclude="compile" />
</group>
<group targetFramework="netcoreapp3.1">
<dependency id="NETStandard.Library" version="2.0.0" />
<dependency id="Microsoft.DotNet.InternalAbstractions" version="1.0.0" exclude="compile" />
<dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="compile" />
<dependency id="System.Reflection" version="4.3.0" exclude="compile" />
<dependency id="System.Diagnostics.Process" version="4.3.0" exclude="compile" />
<dependency id="System.Xml.XPath.XmlDocument" version="4.3.0" exclude="compile" />
</group>
</dependencies>
<contentFiles>
<files include="**" buildAction="None" copyToOutput="true" />
Expand Down Expand Up @@ -76,6 +84,11 @@
<file src="bin/netstandard2.0/nunit.engine.api.dll" target="lib/netstandard2.0" />
<file src="bin/netstandard2.0/Mono.Cecil.dll" target="lib/netstandard2.0" />
<file src="../../nuget/engine/nunit.engine.nuget.addins" target="contentFiles/any/lib/netstandard2.0"/>
<file src="bin/netcoreapp3.1/nunit.engine.dll" target="lib/netcoreapp3.1" />
<file src="bin/netcoreapp3.1/nunit.engine.core.dll" target="lib/netcoreapp3.1" />
<file src="bin/netcoreapp3.1/Mono.Cecil.dll" target="lib/netcoreapp3.1" />
<file src="bin/netstandard2.0/nunit.engine.api.dll" target="lib/netcoreapp3.1" />
<file src="../../nuget/engine/nunit.engine.nuget.addins" target="contentFiles/any/lib/netcoreapp3.1"/>
<file src="../../nuget/engine/build/**/*" target="build" />
<file src="../../nunit_256.png" target="images" />
</files>
Expand Down
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>NUnit.ConsoleRunner.Tests</RootNamespace>
<TargetFrameworks>net35;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net35;netcoreapp3.1</TargetFrameworks>
<NoWarn>1685</NoWarn>
<DebugType>Full</DebugType>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/NUnitConsole/nunit3-console/nunit3-console.csproj
Expand Up @@ -3,7 +3,7 @@
<OutputType>Exe</OutputType>
<RootNamespace>NUnit.ConsoleRunner</RootNamespace>
<AssemblyName>nunit3-console</AssemblyName>
<TargetFrameworks>net20;netcoreapp2.1</TargetFrameworks>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The console is as-yet unreleased, but will now target .NET Core 3.1 as a minimum. With the long-term aim of making it self-contained anyway, I'm not too worried about this.

<TargetFrameworks>net20;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\..\..\nunit.ico</ApplicationIcon>
Expand Down
2 changes: 1 addition & 1 deletion src/NUnitEngine/mock-assembly/mock-assembly.csproj
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>NUnit.Tests</RootNamespace>
<TargetFrameworks>net20;netcoreapp1.1;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net20;netcoreapp1.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\nunit.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/NUnitEngine/notest-assembly/notest-assembly.csproj
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>notest_assembly</RootNamespace>
<TargetFrameworks>net35;netcoreapp1.1;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net35;netcoreapp1.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.11.0" />
Expand Down
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
Expand Down
2 changes: 1 addition & 1 deletion src/NUnitEngine/nunit.engine.core/CallbackHandler.cs
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
using System;
using System.Web.UI;

Expand Down
4 changes: 2 additions & 2 deletions src/NUnitEngine/nunit.engine.core/CoreEngine.cs
Expand Up @@ -103,9 +103,9 @@ public void InitializeServices()
Services.Add(new DriverService());
#if !NETSTANDARD1_6
Services.Add(new ExtensionService());
#if !NETSTANDARD2_0
Services.Add(new DomainManager());
#endif
#if NETFRAMEWORK
Services.Add(new DomainManager());
#endif
Services.Add(new InProcessTestRunnerFactory());
}
Expand Down
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.Reflection;
Expand Down
Expand Up @@ -42,7 +42,7 @@ public bool IsSupportedTestFramework(AssemblyName reference)
return NUNIT_FRAMEWORK.Equals(reference.Name, StringComparison.OrdinalIgnoreCase) && reference.Version.Major == 3;
}

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
/// <summary>
/// Gets a driver for a given test assembly and a framework
/// which the assembly is already known to reference.
Expand Down
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.IO;
Expand Down
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if NETSTANDARD
#if NETSTANDARD || NETCOREAPP3_1
using System;
using System.Linq;
using System.Collections.Generic;
Expand Down
Expand Up @@ -60,7 +60,7 @@ public ModuleDefinition MainModule
get { return Assembly.MainModule; }
}

#if !NETSTANDARD2_0
#if NETFRAMEWORK
public RuntimeFramework TargetFramework
{
get { return new RuntimeFramework(RuntimeType.Any, _targetFrameworkHelper.TargetRuntimeVersion); }
Expand Down
Expand Up @@ -26,7 +26,7 @@
using System.Collections.Generic;
using System.Reflection;

#if NETSTANDARD2_0
#if !NETFRAMEWORK
using System.Linq;
#endif

Expand Down Expand Up @@ -141,7 +141,7 @@ public object ExtensionObject
/// </summary>
public object CreateExtensionObject(params object[] args)
{
#if NETSTANDARD2_0
#if !NETFRAMEWORK
var assembly = Assembly.LoadFrom(AssemblyPath);
var typeinfo = assembly.DefinedTypes.FirstOrDefault(t => t.FullName == TypeName);
if (typeinfo == null)
Expand Down
Expand Up @@ -61,7 +61,7 @@ public static bool IsBetterVersionOf(this IExtensionAssembly first, IExtensionAs
if (firstVersion < secondVersion)
return false;

#if !NETSTANDARD2_0
#if NETFRAMEWORK
//Look at target runtime
var firstTargetRuntime = first.TargetFramework.FrameworkVersion;
var secondTargetRuntime = second.TargetFramework.FrameworkVersion;
Expand Down
Expand Up @@ -31,7 +31,7 @@ internal interface IExtensionAssembly
bool FromWildCard { get; }
string AssemblyName { get; }
Version AssemblyVersion { get; }
#if !NETSTANDARD2_0
#if NETFRAMEWORK
RuntimeFramework TargetFramework { get; }
#endif
}
Expand Down
Expand Up @@ -21,7 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

#if !NETSTANDARD1_6 && !NETSTANDARD2_0
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using Microsoft.Win32;
Expand Down