diff --git a/NUnitConsole.sln b/NUnitConsole.sln
index 375b8a565..af5116a20 100644
--- a/NUnitConsole.sln
+++ b/NUnitConsole.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29728.190
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{49D441DF-39FD-4F4D-AECA-86CF8EFE23AF}"
ProjectSection(SolutionItems) = preProject
@@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
src\Directory.Build.props = src\Directory.Build.props
GitReleaseManager.yaml = GitReleaseManager.yaml
GitVersion.yml = GitVersion.yml
+ global.json = global.json
header-check.cake = header-check.cake
LICENSE.txt = LICENSE.txt
NetFXTests.nunit = NetFXTests.nunit
diff --git a/appveyor.yml b/appveyor.yml
index 5eefdac67..4779791b4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,6 +5,20 @@ branches:
except:
- /^azure-/
+install:
+ - ps: $urlNet70RC = "https://download.visualstudio.microsoft.com/download/pr/b3b5dce4-d810-4477-a8a3-97cbb0bdf3ea/91d0dd167239cfdfb48ae18166f444d4/dotnet-sdk-7.0.100-rc.1.22431.12-win-x64.zip"
+ - ps: echo "Download from $urlNet70RC"
+ - ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
+ - ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
+ - ps: echo "Created directory $env:DOTNET_INSTALL_DIR"
+ - ps: echo "Starting download"
+ - ps: $tempFileNet70RC = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
+ - ps: (New-Object System.Net.WebClient).DownloadFile($urlNet70RC, $tempFileNet70RC)
+ - ps: Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFileNet70RC, $env:DOTNET_INSTALL_DIR)
+ - ps: echo "Download complete"
+ - ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"
+ - ps: dotnet --info
+
build_script:
- ps: .\build.ps1 --target=Appveyor --configuration=Release
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 0edc93152..53c68f448 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -12,6 +12,12 @@ jobs:
steps:
+ - task: UseDotNet@2
+ displayName: 'Install .NET 7.0'
+ inputs:
+ version: 7.x
+ includePreviewVersions: true
+
- task: UseDotNet@2
displayName: 'Install .NET 6.0'
inputs:
@@ -69,6 +75,12 @@ jobs:
vmImage: ubuntu-20.04
steps:
+ - task: UseDotNet@2
+ displayName: 'Install .NET 7.0'
+ inputs:
+ version: 7.x
+ includePreviewVersions: true
+
- task: UseDotNet@2
displayName: 'Install .NET 6.0'
inputs:
@@ -118,6 +130,12 @@ jobs:
vmImage: macOS-11
steps:
+ - task: UseDotNet@2
+ displayName: 'Install .NET 7.0'
+ inputs:
+ version: 7.x
+ includePreviewVersions: true
+
- task: UseDotNet@2
displayName: 'Install .NET 6.0'
inputs:
diff --git a/build.cake b/build.cake
index 96350d17b..d786c9d8f 100644
--- a/build.cake
+++ b/build.cake
@@ -109,18 +109,25 @@ public void BuildSolution()
.WithProperty("TargetFramework", "netstandard2.0")
.WithProperty("PublishDir", BIN_DIR + "netstandard2.0"));
- DisplayBanner("Publishing ENGINE Project for NETSTANDARD2.0");
- MSBuild(ENGINE_PROJECT, CreateMSBuildSettings("Publish")
- .WithProperty("TargetFramework", "netstandard2.0")
- .WithProperty("PublishDir", BIN_DIR + "netstandard2.0"));
+ DisplayBanner("Publishing ENGINE Project");
+ foreach (var framework in new[] { "netstandard2.0", "netcoreapp3.1" })
+ MSBuild(ENGINE_PROJECT, CreateMSBuildSettings("Publish")
+ .WithProperty("TargetFramework", framework)
+ .WithProperty("PublishDir", BIN_DIR + framework));
- DisplayBanner("Publishing ENGINE TESTS Project for NETCOREAPP2.1");
- MSBuild(ENGINE_TESTS_PROJECT, CreateMSBuildSettings("Publish")
- .WithProperty("TargetFramework", "netcoreapp2.1")
- .WithProperty("PublishDir", BIN_DIR + "netcoreapp2.1"));
+ DisplayBanner("Publishing ENGINE TESTS Project");
+ foreach (var framework in new[] { "netcoreapp2.1", "netcoreapp3.1" })
+ MSBuild(ENGINE_TESTS_PROJECT, CreateMSBuildSettings("Publish")
+ .WithProperty("TargetFramework", framework)
+ .WithProperty("PublishDir", BIN_DIR + framework));
+
+ DisplayBanner("Publishing MOCK ASSEMBLY Project for NET7.0");
+ MSBuild(MOCK_ASSEMBLY_PROJECT, CreateMSBuildSettings("Publish")
+ .WithProperty("TargetFramework", "net7.0")
+ .WithProperty("PublishDir", BIN_DIR + "net7.0"));
// TODO: May not be needed
- foreach (var framework in new[] { "netcoreapp3.1", "net5.0" })
+ foreach (var framework in new[] { "netcoreapp3.1", "net5.0", "net7.0" })
{
DisplayBanner($"Publishing AGENT Project for {framework.ToUpper()}");
MSBuild(AGENT_PROJECT, CreateMSBuildSettings("Publish")
@@ -138,7 +145,7 @@ private void BuildEachProjectSeparately()
BuildProject(AGENT_PROJECT);
BuildProject(AGENT_X86_PROJECT);
- BuildProject(ENGINE_TESTS_PROJECT, "net35", "netcoreapp2.1");
+ BuildProject(ENGINE_TESTS_PROJECT, "net35", "netcoreapp2.1", "netcoreapp3.1");
BuildProject(ENGINE_CORE_TESTS_PROJECT, "net35", "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net6.0");
BuildProject(CONSOLE_TESTS_PROJECT, "net35", "net6.0");
@@ -305,6 +312,19 @@ Task("TestNetStandard20Engine")
RunDotnetNUnitLiteTests(NETCORE_ENGINE_TESTS, "netcoreapp2.1");
});
+//////////////////////////////////////////////////////////////////////
+// TEST NETCORE 3.1 ENGINE
+//////////////////////////////////////////////////////////////////////
+
+Task("TestNetCore31Engine")
+ .Description("Tests the .NET Core 3.1 Engine")
+ .IsDependentOn("Build")
+ .OnError(exception => { UnreportedErrors.Add(exception.Message); })
+ .Does(() =>
+ {
+ RunDotnetNUnitLiteTests(NETCORE_ENGINE_TESTS, "netcoreapp3.1");
+ });
+
//////////////////////////////////////////////////////////////////////
// TEST .NET 2.0 CONSOLE
//////////////////////////////////////////////////////////////////////
@@ -739,7 +759,8 @@ Task("TestEngineCore")
Task("TestEngine")
.Description("Builds and tests the engine assembly")
.IsDependentOn("TestNet20Engine")
- .IsDependentOn("TestNetStandard20Engine");
+ .IsDependentOn("TestNetStandard20Engine")
+ .IsDependentOn("TestNetCore31Engine");
Task("Test")
.Description("Builds and tests the engine and console runner")
diff --git a/cake/package-definitions.cake b/cake/package-definitions.cake
index 93db0d309..6265ffb87 100644
--- a/cake/package-definitions.cake
+++ b/cake/package-definitions.cake
@@ -28,6 +28,7 @@ public void InitializePackageDefinitions(ICakeContext context)
NetCore31Test,
Net50Test,
Net60Test,
+ Net70Test,
NetCore21PlusNetCore31Test,
NetCore21PlusNetCore31PlusNet50PlusNet60Test,
Net40PlusNet60Test
@@ -71,7 +72,8 @@ public void InitializePackageDefinitions(ICakeContext context)
HasDirectory("tools/agents/net40").WithFiles(AGENT_FILES).AndFile("nunit.agent.addins"),
HasDirectory("tools/agents/netcoreapp3.1").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
HasDirectory("tools/agents/net5.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
- HasDirectory("tools/agents/net6.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins")
+ HasDirectory("tools/agents/net6.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
+ HasDirectory("tools/agents/net7.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins")
},
symbols: new PackageCheck[] {
HasDirectory("tools").WithFiles(ENGINE_PDB_FILES).AndFile("nunit3-console.pdb"),
@@ -79,7 +81,8 @@ public void InitializePackageDefinitions(ICakeContext context)
HasDirectory("tools/agents/net40").WithFiles(AGENT_PDB_FILES),
HasDirectory("tools/agents/netcoreapp3.1").WithFiles(AGENT_PDB_FILES_NETCORE),
HasDirectory("tools/agents/net5.0").WithFiles(AGENT_PDB_FILES_NETCORE),
- HasDirectory("tools/agents/net6.0").WithFiles(AGENT_PDB_FILES_NETCORE)
+ HasDirectory("tools/agents/net6.0").WithFiles(AGENT_PDB_FILES_NETCORE),
+ HasDirectory("tools/agents/net7.0").WithFiles(AGENT_PDB_FILES_NETCORE)
},
executable: "tools/nunit3-console.exe",
tests: StandardRunnerTests),
@@ -110,7 +113,8 @@ public void InitializePackageDefinitions(ICakeContext context)
HasDirectory("tools/agents/net40").WithFiles(AGENT_FILES).AndFile("nunit.agent.addins"),
HasDirectory("tools/agents/netcoreapp3.1").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
HasDirectory("tools/agents/net5.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
- HasDirectory("tools/agents/net6.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins")
+ HasDirectory("tools/agents/net6.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins"),
+ HasDirectory("tools/agents/net7.0").WithFiles(AGENT_FILES_NETCORE).AndFile("nunit.agent.addins")
},
executable: "tools/nunit3-console.exe",
tests: StandardRunnerTests),
@@ -123,6 +127,12 @@ public void InitializePackageDefinitions(ICakeContext context)
checks: new PackageCheck[] {
HasDirectory("NUnit.org").WithFiles("LICENSE.txt", "NOTICES.txt", "nunit.ico"),
HasDirectory("NUnit.org/nunit-console").WithFiles(CONSOLE_FILES).AndFiles(ENGINE_FILES).AndFile("nunit.bundle.addins"),
+ HasDirectory("NUnit.org/nunit-console/agents/net20").WithFiles("nunit-agent.exe", "nunit-agent.exe.config"),
+ HasDirectory("NUnit.org/nunit-console/agents/net40").WithFiles("nunit-agent.exe", "nunit-agent.exe.config"),
+ HasDirectory("NUnit.org/nunit-console/agents/netcoreapp3.1").WithFile("nunit-agent.dll"),
+ HasDirectory("NUnit.org/nunit-console/agents/net5.0").WithFile("nunit-agent.dll"),
+ HasDirectory("NUnit.org/nunit-console/agents/net6.0").WithFile("nunit-agent.dll"),
+ //HasDirectory("NUnit.org/nunit-console/agents/net7.0").WithFile("nunit-agent.dll"),
HasDirectory("Nunit.org/nunit-console/addins").WithFiles("nunit.core.dll", "nunit.core.interfaces.dll", "nunit.v2.driver.dll", "nunit-project-loader.dll", "vs-project-loader.dll", "nunit-v2-result-writer.dll", "teamcity-event-listener.dll")
},
executable: "NUnit.org/nunit-console/nunit3-console.exe",
@@ -139,7 +149,7 @@ public void InitializePackageDefinitions(ICakeContext context)
HasDirectory("bin/net35").WithFiles(CONSOLE_FILES).AndFiles(ENGINE_FILES).AndFile("nunit3-console.pdb").AndFiles(ENGINE_PDB_FILES),
HasDirectory("bin/netstandard2.0").WithFiles(ENGINE_FILES).AndFiles(ENGINE_PDB_FILES),
HasDirectory("bin/netcoreapp2.1").WithFiles(ENGINE_FILES).AndFiles(ENGINE_PDB_FILES),
- HasDirectory("bin/netcoreapp3.1").WithFiles(ENGINE_CORE_FILES).AndFiles(ENGINE_CORE_PDB_FILES),
+ HasDirectory("bin/netcoreapp3.1").WithFiles(ENGINE_FILES).AndFiles(ENGINE_PDB_FILES),
//HasDirectory("bin/net5.0").WithFiles(ENGINE_FILES).AndFiles(ENGINE_PDB_FILES),
HasDirectory("bin/agents/net20").WithFiles(AGENT_FILES).AndFiles(AGENT_PDB_FILES),
HasDirectory("bin/agents/net40").WithFiles(AGENT_FILES).AndFiles(AGENT_PDB_FILES),
@@ -160,14 +170,17 @@ public void InitializePackageDefinitions(ICakeContext context)
HasFiles("LICENSE.txt", "NOTICES.txt"),
HasDirectory("lib/net20").WithFiles(ENGINE_FILES),
HasDirectory("lib/netstandard2.0").WithFiles(ENGINE_FILES),
+ HasDirectory("lib/netcoreapp3.1").WithFiles(ENGINE_FILES),
HasDirectory("contentFiles/any/lib/net20").WithFile("nunit.engine.nuget.addins"),
HasDirectory("contentFiles/any/lib/netstandard2.0").WithFile("nunit.engine.nuget.addins"),
+ HasDirectory("contentFiles/any/lib/netcoreapp3.1").WithFile("nunit.engine.nuget.addins"),
HasDirectory("contentFiles/any/agents/net20").WithFiles(AGENT_FILES).AndFile("nunit.agent.addins"),
HasDirectory("contentFiles/any/agents/net40").WithFiles(AGENT_FILES).AndFile("nunit.agent.addins")
},
symbols: new PackageCheck[] {
HasDirectory("lib/net20").WithFiles(ENGINE_PDB_FILES),
HasDirectory("lib/netstandard2.0").WithFiles(ENGINE_PDB_FILES),
+ HasDirectory("lib/netcoreapp3.1").WithFiles(ENGINE_PDB_FILES),
HasDirectory("contentFiles/any/agents/net20").WithFiles(AGENT_PDB_FILES),
HasDirectory("contentFiles/any/agents/net40").WithFiles(AGENT_PDB_FILES)
}),
diff --git a/cake/package-tests.cake b/cake/package-tests.cake
index e28e90434..ccdb4e864 100644
--- a/cake/package-tests.cake
+++ b/cake/package-tests.cake
@@ -48,6 +48,12 @@ static PackageTest Net60Test = new PackageTest(
"net6.0/mock-assembly.dll",
MockAssemblyExpectedResult(1));
+static PackageTest Net70Test = new PackageTest(
+ "Net70Test",
+ "Run mock-assembly.dll under .NET 7.0",
+ "net7.0/mock-assembly.dll",
+ MockAssemblyExpectedResult(1));
+
static PackageTest Net50Test = new PackageTest(
"Net50Test",
"Run mock-assembly.dll under .NET 5.0",
diff --git a/cake/versioning.cake b/cake/versioning.cake
index 12f0c9813..aded97410 100644
--- a/cake/versioning.cake
+++ b/cake/versioning.cake
@@ -77,6 +77,10 @@ public class BuildVersion
string branchName = _gitVersion.BranchName;
+ // Treat version3 branch as an alternate "main"
+ if (branchName == "version3")
+ label = "dev";
+
// We don't currently use this pattern, but check in case we do later.
if (branchName.StartsWith("feature/"))
branchName = branchName.Substring(8);
diff --git a/choco/nunit-console-runner.nuspec b/choco/nunit-console-runner.nuspec
index f8f321b5e..2739816f6 100644
--- a/choco/nunit-console-runner.nuspec
+++ b/choco/nunit-console-runner.nuspec
@@ -92,5 +92,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/global.json b/global.json
index 69d60238d..c18e8aeca 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "6.0.101",
- "rollForward": "patch"
+ "version": "7.0.100-rc.1.22431.12",
+ "rollForward": "feature"
}
}
\ No newline at end of file
diff --git a/msi/nunit/engine-files.wxi b/msi/nunit/engine-files.wxi
index 457244bd6..c8791fcdc 100644
--- a/msi/nunit/engine-files.wxi
+++ b/msi/nunit/engine-files.wxi
@@ -49,6 +49,7 @@
+
@@ -174,5 +175,34 @@
Source="$(var.InstallImage)bin/net6.0/testcentric.engine.metadata.dll" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/msi/nunit/runner-directories.wxi b/msi/nunit/runner-directories.wxi
index 1f4eab58e..c3483e20e 100644
--- a/msi/nunit/runner-directories.wxi
+++ b/msi/nunit/runner-directories.wxi
@@ -16,6 +16,7 @@
+
diff --git a/nuget/engine/nunit.engine.nuspec b/nuget/engine/nunit.engine.nuspec
index 271016e96..60c86602d 100644
--- a/nuget/engine/nunit.engine.nuspec
+++ b/nuget/engine/nunit.engine.nuspec
@@ -92,6 +92,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/nuget/runners/nunit.console-runner.nuspec b/nuget/runners/nunit.console-runner.nuspec
index 032d4d088..2d58e7123 100644
--- a/nuget/runners/nunit.console-runner.nuspec
+++ b/nuget/runners/nunit.console-runner.nuspec
@@ -93,6 +93,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NUnitConsole/nunit3-console/Program.cs b/src/NUnitConsole/nunit3-console/Program.cs
index c9c5d6d3e..c0c8a4d10 100644
--- a/src/NUnitConsole/nunit3-console/Program.cs
+++ b/src/NUnitConsole/nunit3-console/Program.cs
@@ -106,8 +106,9 @@ public static int Main(string[] args)
if (Options.WorkDirectory != null)
engine.WorkDirectory = Options.WorkDirectory;
- if (Options.InternalTraceLevel != null)
- engine.InternalTraceLevel = (InternalTraceLevel)Enum.Parse(typeof(InternalTraceLevel), Options.InternalTraceLevel);
+ engine.InternalTraceLevel = Options.InternalTraceLevel != null
+ ? (InternalTraceLevel)Enum.Parse(typeof(InternalTraceLevel), Options.InternalTraceLevel)
+ : InternalTraceLevel.Off;
try
{
diff --git a/src/NUnitEngine/mock-assembly/mock-assembly.csproj b/src/NUnitEngine/mock-assembly/mock-assembly.csproj
index f60671084..aef70f591 100644
--- a/src/NUnitEngine/mock-assembly/mock-assembly.csproj
+++ b/src/NUnitEngine/mock-assembly/mock-assembly.csproj
@@ -2,7 +2,7 @@
NUnit.Tests
- net35;net40;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0
+ net35;net40;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
true
..\..\nunit.snk
false
diff --git a/src/NUnitEngine/nunit-agent/Program.cs b/src/NUnitEngine/nunit-agent/Program.cs
index 4c98c0591..f66171d31 100644
--- a/src/NUnitEngine/nunit-agent/Program.cs
+++ b/src/NUnitEngine/nunit-agent/Program.cs
@@ -61,7 +61,6 @@ public static void Main(string[] args)
}
var logName = $"nunit-agent_{pid}.log";
- InternalTrace.Initialize(Path.Combine(workDirectory, logName), traceLevel);
log = InternalTrace.GetLogger(typeof(NUnitTestAgent));
log.Info("Agent process {0} starting", pid);
@@ -71,7 +70,13 @@ public static void Main(string[] args)
LocateAgencyProcess(agencyPid);
-#if NETCOREAPP3_1
+#if NET7_0
+ log.Info($"Running .NET 7.0 agent under {RuntimeInformation.FrameworkDescription}");
+#elif NET6_0
+ log.Info($"Running .NET 6.0 agent under {RuntimeInformation.FrameworkDescription}");
+#elif NET5_0
+ log.Info($"Running .NET 5.0 agent under {RuntimeInformation.FrameworkDescription}");
+#elif NETCOREAPP3_1
log.Info($"Running .NET Core 3.1 agent under {RuntimeInformation.FrameworkDescription}");
#elif NET40
log.Info($"Running .NET 4.0 agent under {RuntimeFramework.CurrentFramework.DisplayName}");
diff --git a/src/NUnitEngine/nunit-agent/nunit-agent.csproj b/src/NUnitEngine/nunit-agent/nunit-agent.csproj
index aeca8e54a..317315028 100644
--- a/src/NUnitEngine/nunit-agent/nunit-agent.csproj
+++ b/src/NUnitEngine/nunit-agent/nunit-agent.csproj
@@ -3,7 +3,7 @@
Exe
nunit.agent
- net20;net40;netcoreapp3.1;net5.0;net6.0
+ net20;net40;netcoreapp3.1;net5.0;net6.0;net7.0
app.manifest
..\..\..\nunit.ico
false
diff --git a/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetCoreFrameworkLocator.cs b/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetCoreFrameworkLocator.cs
new file mode 100644
index 000000000..420dd4a6a
--- /dev/null
+++ b/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetCoreFrameworkLocator.cs
@@ -0,0 +1,127 @@
+// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
+
+#if NETFRAMEWORK
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+
+namespace NUnit.Engine.Internal.RuntimeFrameworks
+{
+ internal static class NetCoreFrameworkLocator
+ {
+ static Logger log = InternalTrace.GetLogger(typeof(NetCoreFrameworkLocator));
+
+ public static IEnumerable FindDotNetCoreFrameworks()
+ {
+ List alreadyFound = new List();
+
+ foreach (string dirName in GetRuntimeDirectories())
+ {
+ Version newVersion;
+ if (TryGetVersionFromString(dirName, out newVersion) && !alreadyFound.Contains(newVersion))
+ {
+ alreadyFound.Add(newVersion);
+ // HACK: Avoid Exception for an unknown version - see issue #1223
+ // Requires change in RuntimeFramework.GetClrVersionForFramework()
+ if (newVersion.Major <= 7)
+ yield return new RuntimeFramework(RuntimeType.NetCore, newVersion);
+ else
+ log.Error($"Found .NET {newVersion.ToString(2)}, which is not yet supported.");
+ }
+ }
+
+ foreach (string line in GetRuntimeList())
+ {
+ Version newVersion;
+ if (TryGetVersionFromString(line, out newVersion) && !alreadyFound.Contains(newVersion))
+ {
+ alreadyFound.Add(newVersion);
+ yield return new RuntimeFramework(RuntimeType.NetCore, newVersion);
+ }
+ }
+ }
+
+ private static IEnumerable GetRuntimeDirectories()
+ {
+ string installDir = GetDotNetInstallDirectory();
+
+ if (installDir != null && Directory.Exists(installDir) &&
+ File.Exists(Path.Combine(installDir, "dotnet.exe")))
+ {
+ string runtimeDir = Path.Combine(installDir, Path.Combine("shared", "Microsoft.NETCore.App"));
+ if (Directory.Exists(runtimeDir))
+ foreach (var dir in new DirectoryInfo(runtimeDir).GetDirectories())
+ yield return dir.Name;
+ }
+ }
+
+ private static IEnumerable GetRuntimeList()
+ {
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "dotnet",
+ Arguments = "--list-runtimes",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ CreateNoWindow = true
+ }
+ };
+
+ process.Start();
+
+ const string PREFIX = "Microsoft.NETCore.App ";
+ const int VERSION_START = 22;
+
+ while (!process.StandardOutput.EndOfStream)
+ {
+ var line = process.StandardOutput.ReadLine();
+ if (line.StartsWith(PREFIX))
+ yield return line.Substring(VERSION_START);
+ }
+ }
+
+ private static string GetDotNetInstallDirectory()
+ {
+ if (Path.DirectorySeparatorChar == '\\')
+ {
+ // Running on Windows so use registry
+ RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\dotnet\SetUp\InstalledVersions\x64\sharedHost\");
+ return (string)key?.GetValue("Path");
+ }
+ else
+ return "/usr/shared/dotnet/";
+ }
+
+ private static bool TryGetVersionFromString(string text, out Version newVersion)
+ {
+ const string VERSION_CHARS = ".0123456789";
+
+ int len = 0;
+ foreach (char c in text)
+ {
+ if (VERSION_CHARS.IndexOf(c) >= 0)
+ len++;
+ else
+ break;
+ }
+
+ try
+ {
+ var fullVersion = new Version(text.Substring(0, len));
+ newVersion = new Version(fullVersion.Major, fullVersion.Minor);
+ return true;
+ }
+ catch
+ {
+ newVersion = new Version();
+ return false;
+ }
+ }
+ }
+}
+#endif
diff --git a/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/DotNetFrameworkLocator.cs b/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetFrameworkLocator.cs
similarity index 98%
rename from src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/DotNetFrameworkLocator.cs
rename to src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetFrameworkLocator.cs
index 92560e38a..200275d12 100644
--- a/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/DotNetFrameworkLocator.cs
+++ b/src/NUnitEngine/nunit.engine.core/Internal/RuntimeFrameworks/NetFrameworkLocator.cs
@@ -7,7 +7,7 @@
namespace NUnit.Engine.Internal.RuntimeFrameworks
{
- internal static class DotNetFrameworkLocator
+ internal static class NetFrameworkLocator
{
// Note: this method cannot be generalized past V4, because (a) it has
// specific code for detecting .NET 4.5 and (b) we don't know what
diff --git a/src/NUnitEngine/nunit.engine.core/RuntimeFramework.cs b/src/NUnitEngine/nunit.engine.core/RuntimeFramework.cs
index 33fc7116b..42782f462 100644
--- a/src/NUnitEngine/nunit.engine.core/RuntimeFramework.cs
+++ b/src/NUnitEngine/nunit.engine.core/RuntimeFramework.cs
@@ -134,6 +134,7 @@ public RuntimeFramework(RuntimeType runtime, Version version, string profile)
// Version 0.0 means any version so we can't deduce anything
if (version != DefaultVersion)
{
+ Debug.Assert(IsFrameworkVersion(version));
if (IsFrameworkVersion(version))
ClrVersion = GetClrVersionForFramework(version);
else
@@ -201,6 +202,8 @@ private Version GetClrVersionForFramework(Version frameworkVersion)
return new Version(5, 0, 1);
case 6:
return new Version(6, 0, 0);
+ case 7:
+ return new Version(7, 0, 0);
}
break;
}
@@ -549,10 +552,10 @@ private static void FindAvailableFrameworks()
_availableFrameworks = new List();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
- _availableFrameworks.AddRange(DotNetFrameworkLocator.FindDotNetFrameworks());
+ _availableFrameworks.AddRange(NetFrameworkLocator.FindDotNetFrameworks());
FindDefaultMonoFramework();
- FindDotNetCoreFrameworks();
+ _availableFrameworks.AddRange(NetCoreFrameworkLocator.FindDotNetCoreFrameworks());
}
private static void FindDefaultMonoFramework()
@@ -674,73 +677,6 @@ private static void AddMonoFramework(Version frameworkVersion, string profile)
_availableFrameworks.Add(framework);
}
-
- private static void FindDotNetCoreFrameworks()
- {
- const string WINDOWS_INSTALL_DIR = "C:\\Program Files\\dotnet\\";
- const string LINUX_INSTALL_DIR = "/usr/shared/dotnet/";
- string INSTALL_DIR = Path.DirectorySeparatorChar == '\\'
- ? WINDOWS_INSTALL_DIR
- : LINUX_INSTALL_DIR;
-
- if (!Directory.Exists(INSTALL_DIR))
- return;
- if (!File.Exists(Path.Combine(INSTALL_DIR, "dotnet.exe")))
- return;
-
- string runtimeDir = Path.Combine(INSTALL_DIR, Path.Combine("shared", "Microsoft.NETCore.App"));
- if (!Directory.Exists(runtimeDir))
- return;
-
- var dirList = new DirectoryInfo(runtimeDir).GetDirectories();
- var dirNames = new List();
- foreach (var dir in dirList)
- dirNames.Add(dir.Name);
- var runtimes = GetNetCoreRuntimesFromDirectoryNames(dirNames);
-
- _availableFrameworks.AddRange(runtimes);
- }
-
- // Deal with oddly named directories, which may sometimes appear when previews are installed
- internal static IList GetNetCoreRuntimesFromDirectoryNames(IEnumerable dirNames)
- {
- const string VERSION_CHARS = ".0123456789";
- var runtimes = new List();
-
- foreach (string dirName in dirNames)
- {
- int len = 0;
- foreach (char c in dirName)
- {
- if (VERSION_CHARS.IndexOf(c) >= 0)
- len++;
- else
- break;
- }
-
- if (len == 0)
- continue;
-
- Version fullVersion = null;
- try
- {
- fullVersion = new Version(dirName.Substring(0, len));
- }
- catch
- {
- continue;
- }
-
- var newVersion = new Version(fullVersion.Major, fullVersion.Minor);
- int count = runtimes.Count;
- if (count > 0 && runtimes[count - 1].FrameworkVersion == newVersion)
- continue;
-
- runtimes.Add(new RuntimeFramework(RuntimeType.NetCore, newVersion));
- }
-
- return runtimes;
- }
}
}
#endif
diff --git a/src/NUnitEngine/nunit.engine.tests/Transport/Tcp/TcpServerTests.cs b/src/NUnitEngine/nunit.engine.tests/Transport/Tcp/TcpServerTests.cs
new file mode 100644
index 000000000..a53dc5abd
--- /dev/null
+++ b/src/NUnitEngine/nunit.engine.tests/Transport/Tcp/TcpServerTests.cs
@@ -0,0 +1,71 @@
+// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using NUnit.Framework;
+
+namespace NUnit.Engine.Communication.Transports.Tcp
+{
+ public class TcpServerTests
+ {
+ private TcpServer _server;
+ private List _serverConnections;
+
+ [SetUp]
+ public void StartServer()
+ {
+ _serverConnections = new List();
+ _server = new TcpServer();
+ _server.ClientConnected += (c, g) => _serverConnections.Add(c);
+ _server.Start();
+ }
+
+ [TearDown]
+ public void StopServer()
+ {
+ _server.Stop();
+ }
+
+ [Test]
+ public void SingleClientConnection()
+ {
+ using (TcpClient client = new TcpClient())
+ {
+ client.Connect(_server.EndPoint);
+ client.Client.Send(new Guid().ToByteArray());
+
+ Thread.Sleep(1); // Allow the connection event to run
+ Assert.That(_serverConnections.Count, Is.EqualTo(1), "Should have received 1 connection event");
+ Assert.That(_serverConnections[0].Connected, "Server is not connected to client");
+
+ Assert.True(client.Connected, "Client is not connected to server");
+ }
+ }
+
+ [Test]
+ public void MultipleClientConnections()
+ {
+ TcpClient[] clients = new[] { new TcpClient(), new TcpClient(), new TcpClient() };
+ int num = clients.Length;
+
+ foreach (var client in clients)
+ {
+ client.Connect(_server.EndPoint);
+ client.Client.Send(new Guid().ToByteArray());
+ }
+
+ Thread.Sleep(1); // Allow the connection events to run
+ Assert.That(_serverConnections.Count, Is.EqualTo(num), $"Should have received {num} connection events");
+
+ for (int i = 0; i < num; i++)
+ {
+ Assert.That(_serverConnections[i].Connected, $"Server is not connected to client {i+1}");
+ Assert.True(clients[i].Connected, $"Client {i+1} is not connected to server");
+ }
+ }
+ }
+}
diff --git a/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj b/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
index e586bc682..cb3a14daa 100644
--- a/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
+++ b/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
@@ -2,7 +2,7 @@
NUnit.Engine.Tests
- net35;netcoreapp2.1
+ net35;netcoreapp2.1;netcoreapp3.1
Exe
true
..\..\nunit.snk
@@ -28,7 +28,7 @@
-
+
diff --git a/src/NUnitEngine/nunit.engine/Communication/Transports/Tcp/TcpServer.cs b/src/NUnitEngine/nunit.engine/Communication/Transports/Tcp/TcpServer.cs
index 359704296..cc72a6635 100644
--- a/src/NUnitEngine/nunit.engine/Communication/Transports/Tcp/TcpServer.cs
+++ b/src/NUnitEngine/nunit.engine/Communication/Transports/Tcp/TcpServer.cs
@@ -14,7 +14,7 @@ public class TcpServer
private const int GUID_BUFFER_SIZE = 16;
- TcpListener _listenerSocket;
+ TcpListener _tcpListener;
Thread _listenerThread;
volatile bool _running;
@@ -24,17 +24,21 @@ public class TcpServer
public TcpServer(int port = 0)
{
- _listenerSocket = new TcpListener(IPAddress.Loopback, port);
+ _tcpListener = new TcpListener(IPAddress.Loopback, port);
}
- public IPEndPoint EndPoint => (IPEndPoint)_listenerSocket.LocalEndpoint;
+ public IPEndPoint EndPoint => (IPEndPoint)_tcpListener.LocalEndpoint;
public void Start()
{
- _listenerSocket.Start();
+ _tcpListener.Start();
_running = true;
- _listenerThread = new Thread(WaitForClientConnections);
+ _listenerThread = new Thread(WaitForClientConnections)
+ {
+ Name = "TcpListenerTread",
+ IsBackground = true
+ };
_listenerThread.Start();
}
@@ -43,7 +47,7 @@ public void Stop()
try
{
_running = false;
- _listenerSocket.Stop();
+ _tcpListener.Stop();
}
catch (Exception exception)
{
@@ -57,7 +61,7 @@ private void WaitForClientConnections()
{
try
{
- var clientSocket = _listenerSocket.AcceptSocket();
+ var clientSocket = _tcpListener.AcceptSocket();
if (clientSocket.Connected)
{
// Upon connection, remote agent must immediately send its Id as identification.
@@ -74,7 +78,7 @@ private void WaitForClientConnections()
// 1. We were trying to stop the socket
// 2. The connection was dropped due to some external event
// In either case, we stop the socket and wait a while
- _listenerSocket.Stop();
+ _tcpListener.Stop();
// If we were trying to stop, that's all
if (!_running)
@@ -84,7 +88,7 @@ private void WaitForClientConnections()
Thread.Sleep(500);
try
{
- _listenerSocket.Start();
+ _tcpListener.Start();
}
catch (Exception exception)
{
diff --git a/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs b/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs
index 6411d810e..b98352026 100644
--- a/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs
+++ b/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs
@@ -53,7 +53,7 @@ public AgentProcess(TestAgency agency, TestPackage package, Guid agentId)
StartInfo.FileName = RuntimeFramework.MonoExePath;
string monoOptions = "--runtime=v" + TargetRuntime.ClrVersion.ToString(3);
monoOptions += " --debug";
- StartInfo.Arguments = string.Format("{0} \"{1}\" {2}", monoOptions, AgentExePath, AgentArgs);
+ StartInfo.Arguments = $"{monoOptions} \"{AgentExePath}\" {AgentArgs}";
}
else if (TargetRuntime.Runtime == RuntimeType.Net)
{
@@ -64,7 +64,7 @@ public AgentProcess(TestAgency agency, TestPackage package, Guid agentId)
else if (TargetRuntime.Runtime == RuntimeType.NetCore)
{
StartInfo.FileName = "dotnet";
- StartInfo.Arguments = $"{AgentExePath} {AgentArgs}";
+ StartInfo.Arguments = $"\"{AgentExePath}\" {AgentArgs}";
StartInfo.LoadUserProfile = loadUserProfile;
// TODO: Remove the windows limitation and the use of a hard-coded path.
@@ -116,27 +116,24 @@ public static string GetTestAgentExePath(RuntimeFramework targetRuntime, bool re
string runtimeDir;
string agentName;
- string agentExtension;
int major = targetRuntime.FrameworkVersion.Major;
switch (targetRuntime.Runtime)
{
case RuntimeType.Net:
case RuntimeType.Mono:
runtimeDir = major >= 4 ? "net40" : "net20";
- agentName = requires32Bit ? "nunit-agent-x86" : "nunit-agent";
- agentExtension = ".exe";
+ agentName = requires32Bit ? "nunit-agent-x86.exe" : "nunit-agent.exe";
break;
case RuntimeType.NetCore:
- runtimeDir = major >= 6 ? "net6.0" : major == 5 ? "net5.0" : "netcoreapp3.1";
- agentName = "nunit-agent";
- agentExtension = ".dll";
+ runtimeDir = major >= 7 ? "net7.0" : major == 6 ? "net6.0" : major == 5 ? "net5.0" : "netcoreapp3.1";
+ agentName = "nunit-agent.dll";
break;
default:
log.Error($"Unknown runtime type: {targetRuntime.Runtime}");
return null;
}
- return Path.Combine(Path.Combine(agentsDir, runtimeDir), agentName + agentExtension);
+ return Path.Combine(Path.Combine(agentsDir, runtimeDir), agentName);
}
}
}
diff --git a/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs b/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs
index bd5cecf99..5347ec49d 100644
--- a/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs
+++ b/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs
@@ -173,27 +173,6 @@ private RuntimeFramework SelectRuntimeFrameworkInner(TestPackage package)
return targetFramework;
}
-
- ///
- /// Returns the best available framework that matches a target framework.
- /// If the target framework has a build number specified, then an exact
- /// match is needed. Otherwise, the matching framework with the highest
- /// build number is used.
- ///
- public RuntimeFramework GetBestAvailableFramework(RuntimeFramework target)
- {
- RuntimeFramework result = target;
-
- foreach (RuntimeFramework framework in _availableRuntimes)
- if (framework.Supports(target))
- {
- if (framework.ClrVersion.Build > result.ClrVersion.Build)
- result = framework;
- }
-
- return result;
- }
-
///
/// Use Mono.Cecil to get information about all assemblies and
/// apply it to the package using special internal keywords.
diff --git a/src/NUnitEngine/nunit.engine/nunit.engine.csproj b/src/NUnitEngine/nunit.engine/nunit.engine.csproj
index e05330dd6..279782078 100644
--- a/src/NUnitEngine/nunit.engine/nunit.engine.csproj
+++ b/src/NUnitEngine/nunit.engine/nunit.engine.csproj
@@ -2,7 +2,7 @@
NUnit.Engine
- net20;netstandard2.0
+ net20;netstandard2.0;netcoreapp3.1
true
..\..\nunit.snk
portable