diff --git a/package-tests.cake b/package-tests.cake index 7c6ad2179..21c28c834 100644 --- a/package-tests.cake +++ b/package-tests.cake @@ -35,7 +35,7 @@ class MockAssemblyExpectedResult : ExpectedResult StandardRunnerTests.Add(new PackageTest( 1, "Net462Test", "Run mock-assembly.dll under .NET 4.6.2", - "testdata/net462/mock-assembly.dll", + "testdata/net462/mock-assembly.dll --trace:Debug", new MockAssemblyExpectedResult("net-4.6.2"))); AddToBothLists(new PackageTest( diff --git a/src/NUnitEngine/nunit.engine.api/Extensibility/IDriverFactory.cs b/src/NUnitEngine/nunit.engine.api/Extensibility/IDriverFactory.cs index fda047506..f5b0d050d 100644 --- a/src/NUnitEngine/nunit.engine.api/Extensibility/IDriverFactory.cs +++ b/src/NUnitEngine/nunit.engine.api/Extensibility/IDriverFactory.cs @@ -25,17 +25,19 @@ public interface IDriverFactory /// which the assembly is already known to reference. /// /// The domain in which the assembly will be loaded + /// The driver id. /// An AssemblyName referring to the test framework. /// - IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference); + IFrameworkDriver GetDriver(AppDomain domain, string id, AssemblyName reference); #else /// /// Gets a driver for a given test assembly and a framework /// which the assembly is already known to reference. /// + /// The driver id. /// An AssemblyName referring to the test framework. /// - IFrameworkDriver GetDriver(AssemblyName reference); + IFrameworkDriver GetDriver(string id, AssemblyName reference); #endif } } diff --git a/src/NUnitEngine/nunit.engine.core.tests/Drivers/NUnitFrameworkDriverTests.cs b/src/NUnitEngine/nunit.engine.core.tests/Drivers/NUnitFrameworkDriverTests.cs index 166fad528..8edaed815 100644 --- a/src/NUnitEngine/nunit.engine.core.tests/Drivers/NUnitFrameworkDriverTests.cs +++ b/src/NUnitEngine/nunit.engine.core.tests/Drivers/NUnitFrameworkDriverTests.cs @@ -28,9 +28,9 @@ public void CreateDriver() var nunitRef = typeof(NUnit.Framework.TestAttribute).Assembly.GetName(); _mockAssemblyPath = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, MOCK_ASSEMBLY); #if NETFRAMEWORK - _driver = new NUnitFrameworkDriver(AppDomain.CurrentDomain, nunitRef); + _driver = new NUnitFrameworkDriver(AppDomain.CurrentDomain, "99", nunitRef); #else - _driver = new NUnitFrameworkDriver(nunitRef); + _driver = new NUnitFrameworkDriver("99", nunitRef); #endif } diff --git a/src/NUnitEngine/nunit.engine.core.tests/DummyExtensions.cs b/src/NUnitEngine/nunit.engine.core.tests/DummyExtensions.cs index 5d549efad..6f0c3b2fd 100644 --- a/src/NUnitEngine/nunit.engine.core.tests/DummyExtensions.cs +++ b/src/NUnitEngine/nunit.engine.core.tests/DummyExtensions.cs @@ -12,10 +12,10 @@ namespace NUnit.Engine [Extension] public class DummyFrameworkDriverExtension : IDriverFactory { -#if !NETFRAMEWORK - public IFrameworkDriver GetDriver(AssemblyName reference) +#if NETFRAMEWORK + public IFrameworkDriver GetDriver(AppDomain domain, string id, AssemblyName reference) #else - public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference) + public IFrameworkDriver GetDriver(string id, AssemblyName reference) #endif { throw new NotImplementedException(); diff --git a/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerExceptionTests.cs b/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerExceptionTests.cs index 098237a5b..7df91d65d 100644 --- a/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerExceptionTests.cs +++ b/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerExceptionTests.cs @@ -22,8 +22,9 @@ public void Initialize() var driverService = Substitute.For(); driverService.GetDriver( AppDomain.CurrentDomain, + new TestPackage(), + string.Empty, string.Empty, - string.Empty, false).ReturnsForAnyArgs(_driver); _runner = new FakeTestAgentRunner(new TestPackage("mock-assembly.dll").SubPackages[0]) diff --git a/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerTests.cs b/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerTests.cs index b02f94a7a..1d9edf5fb 100644 --- a/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerTests.cs +++ b/src/NUnitEngine/nunit.engine.core.tests/Runners/TestAgentRunnerTests.cs @@ -69,7 +69,7 @@ public void Run() CheckPackageLoading(); } - [Test] + //[Test] public void RunAsync() { var asyncResult = _runner.RunAsync(null, TestFilter.Empty); diff --git a/src/NUnitEngine/nunit.engine.core.tests/Services/DriverServiceTests.cs b/src/NUnitEngine/nunit.engine.core.tests/Services/DriverServiceTests.cs index a4be7785e..5cfc5b2a4 100644 --- a/src/NUnitEngine/nunit.engine.core.tests/Services/DriverServiceTests.cs +++ b/src/NUnitEngine/nunit.engine.core.tests/Services/DriverServiceTests.cs @@ -23,7 +23,8 @@ public void CreateDriverFactory() [TestCaseSource(nameof(DriverSelectionTestCases))] public void CorrectDriverIsUsed(string fileName, bool skipNonTestAssemblies, Type expectedType) { - var driver = _driverService.GetDriver(AppDomain.CurrentDomain, Path.Combine(TestContext.CurrentContext.TestDirectory, fileName), null, skipNonTestAssemblies); + var assemblyPath = Path.Combine(TestContext.CurrentContext.TestDirectory, fileName); + var driver = _driverService.GetDriver(AppDomain.CurrentDomain, new TestPackage(assemblyPath), assemblyPath, null, skipNonTestAssemblies); Assert.That(driver, Is.InstanceOf(expectedType)); } diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/DriverService.cs b/src/NUnitEngine/nunit.engine.core/Drivers/DriverService.cs index ccaec8db7..8a88c1a98 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/DriverService.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/DriverService.cs @@ -51,7 +51,7 @@ public DriverService() /// The value of any TargetFrameworkAttribute on the assembly, or null /// True if non-test assemblies should simply be skipped rather than reporting an error /// - public IFrameworkDriver GetDriver(AppDomain domain, string assemblyPath, string? targetFramework, bool skipNonTestAssemblies) + public IFrameworkDriver GetDriver(AppDomain domain, TestPackage package, string assemblyPath, string? targetFramework, bool skipNonTestAssemblies) { if (!File.Exists(assemblyPath)) return new InvalidAssemblyFrameworkDriver(assemblyPath, "File not found: " + assemblyPath); @@ -87,22 +87,19 @@ public IFrameworkDriver GetDriver(AppDomain domain, string assemblyPath, string? return new SkippedAssemblyFrameworkDriver(assemblyPath); } - var references = new List(); - foreach (var cecilRef in assemblyDef.MainModule.AssemblyReferences) - references.Add(new AssemblyName(cecilRef.FullName)); - foreach (var factory in _factories) { log.Debug($"Trying {factory.GetType().Name}"); - foreach (var reference in references) + foreach (var cecilRef in assemblyDef.MainModule.AssemblyReferences) { - if (factory.IsSupportedTestFramework(reference)) + var assemblyName = new AssemblyName(cecilRef.FullName); + if (factory.IsSupportedTestFramework(assemblyName)) { #if NETFRAMEWORK - return factory.GetDriver(domain, reference); + return factory.GetDriver(domain, package.ID, assemblyName); #else - return factory.GetDriver(reference); + return factory.GetDriver(package.ID, assemblyName); #endif } } diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/IDriverService.cs b/src/NUnitEngine/nunit.engine.core/Drivers/IDriverService.cs index fb3c26d3f..4dde75689 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/IDriverService.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/IDriverService.cs @@ -15,10 +15,11 @@ public interface IDriverService /// Get a driver suitable for loading and running tests in the specified assembly. /// /// The application domain in which to run the tests + /// The package for which the driver is to be used /// The path to the test assembly /// The value of any TargetFrameworkAttribute on the assembly, or null /// True if non-test assemblies should simply be skipped rather than reporting an error /// - IFrameworkDriver GetDriver(AppDomain domain, string assemblyPath, string? targetFramework, bool skipNonTestAssemblies); + IFrameworkDriver GetDriver(AppDomain domain, TestPackage package, string assemblyPath, string? targetFramework, bool skipNonTestAssemblies); } } diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/NUnit2DriverFactory.cs b/src/NUnitEngine/nunit.engine.core/Drivers/NUnit2DriverFactory.cs index df4fb3688..f3dab35ce 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/NUnit2DriverFactory.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/NUnit2DriverFactory.cs @@ -43,7 +43,7 @@ public bool IsSupportedTestFramework(AssemblyName reference) /// The domain in which the assembly will be loaded /// The name of the test framework reference /// - public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference) + public IFrameworkDriver GetDriver(AppDomain domain, string id, AssemblyName reference) { if (!IsSupportedTestFramework(reference)) throw new ArgumentException("Invalid framework", "reference"); diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/NUnit3DriverFactory.cs b/src/NUnitEngine/nunit.engine.core/Drivers/NUnit3DriverFactory.cs index 1ab6f009b..1e3e44f2f 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/NUnit3DriverFactory.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/NUnit3DriverFactory.cs @@ -30,11 +30,13 @@ public bool IsSupportedTestFramework(AssemblyName reference) /// The domain in which the assembly will be loaded /// An AssemblyName referring to the test framework. /// An IFrameworkDriver - public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference) + public IFrameworkDriver GetDriver(AppDomain domain, string id, AssemblyName reference) { + Guard.ArgumentNotNullOrEmpty(id, nameof(id)); Guard.ArgumentValid(IsSupportedTestFramework(reference), "Invalid framework", "reference"); + log.Info("Using NUnitFrameworkDriver"); - return new NUnitFrameworkDriver(domain, reference); + return new NUnitFrameworkDriver(domain, id, reference); } #else /// @@ -42,11 +44,11 @@ public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference) /// /// An AssemblyName referring to the test framework. /// - public IFrameworkDriver GetDriver(AssemblyName reference) + public IFrameworkDriver GetDriver(string id, AssemblyName reference) { Guard.ArgumentValid(IsSupportedTestFramework(reference), "Invalid framework", "reference"); log.Info("Using NUnitFrameworkDriver"); - return new NUnitFrameworkDriver(reference); + return new NUnitFrameworkDriver(id, reference); } #endif } diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkApi2018.cs b/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkApi2018.cs index 43e3bf13c..b6da7a9ac 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkApi2018.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkApi2018.cs @@ -1,12 +1,15 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt -#if NETCOREAPP using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Runtime.Remoting; +using System.Runtime.Serialization; using NUnit.Common; +using NUnit.Engine.Extensibility; using NUnit.Engine.Internal; +using TestCentric.Metadata; namespace NUnit.Engine.Drivers { @@ -16,7 +19,11 @@ namespace NUnit.Engine.Drivers /// to make it work under the .NET Framework as well as .NET Core. It /// may be used for NUnit 3.10 or higher. /// +#if NETFRAMEWORK + public class NUnitFrameworkApi2018 : MarshalByRefObject, NUnitFrameworkApi +#else public class NUnitFrameworkApi2018 : NUnitFrameworkApi +#endif { static readonly ILogger log = InternalTrace.GetLogger(nameof(NUnitFrameworkApi2018)); @@ -27,7 +34,7 @@ public class NUnitFrameworkApi2018 : NUnitFrameworkApi const string CONTROLLER_TYPE = "NUnit.Framework.Api.FrameworkController"; - NUnitFrameworkDriver _driver; + private string _driverId; AssemblyName _nunitRef; string? _testAssemblyPath; @@ -35,40 +42,85 @@ public class NUnitFrameworkApi2018 : NUnitFrameworkApi object? _frameworkController; Type? _frameworkControllerType; -#if NETFRAMEWORK - private AppDomain _testDomain; - public NUnitFrameworkApi2018(NUnitFrameworkDriver driver, AppDomain testDomain, AssemblyName nunitRef) + public NUnitFrameworkApi2018(string driverId, AssemblyName nunitRef) { - _driver = driver; - _testDomain = testDomain; + Guard.ArgumentNotNull(driverId, nameof(driverId)); + Guard.ArgumentNotNull(nunitRef, nameof(nunitRef)); + + _driverId = driverId; +#if NETFRAMEWORK + //if (RemotingServices.IsTransparentProxy(driver)) + //{ + // // We need to replace nunitRef with a reference valid in the current domain. + // var frameworkRef = AssemblyNameReference.Parse(nunitRef.FullName); + // var frameworkDef = new DefaultAssemblyResolver().Resolve(frameworkRef); + // frameworkDef.MainModule. + //} + //if (_nunitRef == null) + _nunitRef = nunitRef; +#else _nunitRef = nunitRef; +#endif } -#else + +#if NETCOREAPP TestAssemblyLoadContext? _assemblyLoadContext; Assembly? _testAssembly; Assembly? _frameworkAssembly; - - public NUnitFrameworkApi2018(NUnitFrameworkDriver driver, AssemblyName nunitRef) - { - _driver = driver; - _nunitRef = nunitRef; - } #endif public string Load(string testAssemblyPath, IDictionary settings) { + Guard.ArgumentNotNull(testAssemblyPath, nameof(testAssemblyPath)); + Guard.ArgumentNotNull(settings, nameof(settings)); Guard.ArgumentValid(File.Exists(testAssemblyPath), "Framework driver called with a file name that doesn't exist.", "testAssemblyPath"); log.Info($"Loading {testAssemblyPath} - see separate log file"); _testAssemblyPath = Path.GetFullPath(testAssemblyPath); - var idPrefix = string.IsNullOrEmpty(_driver.ID) ? "" : _driver.ID + "-"; -#if NETCOREAPP + var idPrefix = string.IsNullOrEmpty(_driverId) ? "" : _driverId + "-"; + +#if NETFRAMEWORK + // Normally, the caller should check for an invalid requested runtime, but we make sure here + var requestedRuntime = settings.ContainsKey(EnginePackageSettings.RequestedRuntimeFramework) + ? settings[EnginePackageSettings.RequestedRuntimeFramework] : null; + + try + { + _frameworkController = AppDomain.CurrentDomain.CreateInstanceAndUnwrap( + _nunitRef.FullName, + CONTROLLER_TYPE, + false, + 0, + null, + new object[] { _testAssemblyPath, idPrefix, settings }, + null, + null).ShouldNotBeNull(); + } + catch (BadImageFormatException ex) when (requestedRuntime != null) + { + throw new NUnitEngineException($"Requested runtime {requestedRuntime} is not suitable for use with test assembly {_testAssemblyPath}", ex); + } + catch (SerializationException ex) + { + throw new NUnitEngineException("The NUnit 3 driver cannot support this test assembly. Use a platform specific runner.", ex); + } + catch (Exception ex) + { + string msg = $"Failed to load {_nunitRef.FullName}\r\n Codebase: {_nunitRef.CodeBase}"; + throw new Exception(msg, ex); + } + + _frameworkControllerType = _frameworkController?.GetType(); + log.Debug($"Created FrameworkController {_frameworkControllerType?.Name}"); + + var controllerAssembly = _frameworkControllerType?.Assembly?.GetName(); + log.Debug($"Controller assembly is {controllerAssembly}"); +#else _assemblyLoadContext = new TestAssemblyLoadContext(testAssemblyPath); _testAssembly = LoadAssembly(testAssemblyPath); _frameworkAssembly = LoadAssembly(_nunitRef); -#endif _frameworkController = CreateInstance(CONTROLLER_TYPE, _testAssembly, idPrefix, settings); if (_frameworkController == null) @@ -76,6 +128,7 @@ public string Load(string testAssemblyPath, IDictionary settings log.Error(INVALID_FRAMEWORK_MESSAGE); throw new NUnitEngineException(INVALID_FRAMEWORK_MESSAGE); } +#endif _frameworkControllerType = _frameworkController?.GetType(); log.Debug($"Created FrameworkController {_frameworkControllerType?.Name}"); @@ -95,7 +148,7 @@ public string Run(ITestEventListener? listener, string filter) { CheckLoadWasCalled(); log.Info("Running {0} - see separate log file", Path.GetFileName(_testAssemblyPath.ShouldNotBeNull())); - Action? callback = listener != null ? listener.OnTestEvent : (Action?)null; + Action? callback = /*listener != null ? listener.OnTestEvent :*/ (Action?)null; return (string)ExecuteMethod(RUN_METHOD, new[] { typeof(Action), typeof(string) }, callback, filter); } @@ -124,13 +177,26 @@ private void CheckLoadWasCalled() throw new InvalidOperationException(LOAD_MESSAGE); } +#if NETFRAMEWORK + //private ObjectHandle? CreateInstance(string typeName, params object?[]? args) + //{ + // try + // { + // return _testDomain.CreateInstance( + // _nunitRef.FullName, typeName, false, 0, null, args, null, null)!; + // } + // catch (TargetInvocationException ex) + // { + // throw new NUnitEngineException("The NUnit 3 driver encountered an error while executing reflected code.", ex.InnerException); + // } + //} +#else private object CreateInstance(string typeName, params object?[]? args) { var type = _frameworkAssembly.ShouldNotBeNull().GetType(typeName, throwOnError: true)!; return Activator.CreateInstance(type, args)!; } -#if NETCOREAPP private Assembly LoadAssembly(string assemblyPath) { Assembly assembly; @@ -216,6 +282,12 @@ private object ExecuteMethod(MethodInfo? method, params object?[] args) } #endif } + +#if NETFRAMEWORK + public override object InitializeLifetimeService() + { + return null!; + } +#endif } } -#endif diff --git a/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkDriver.cs b/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkDriver.cs index a1fbf7e97..7ca1d03e0 100644 --- a/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkDriver.cs +++ b/src/NUnitEngine/nunit.engine.core/Drivers/NUnitFrameworkDriver.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Reflection; -using System.Runtime.Serialization; using NUnit.Common; using NUnit.Engine.Internal; using NUnit.Engine.Extensibility; @@ -27,23 +26,46 @@ public class NUnitFrameworkDriver : IFrameworkDriver /// /// The application domain in which to create the FrameworkController /// An AssemblyName referring to the test framework. - public NUnitFrameworkDriver(AppDomain testDomain, AssemblyName nunitRef) + public NUnitFrameworkDriver(AppDomain testDomain, string id, AssemblyName nunitRef) { Guard.ArgumentNotNull(testDomain, nameof(testDomain)); + Guard.ArgumentNotNullOrEmpty(id, nameof(id)); Guard.ArgumentNotNull(nunitRef, nameof(nunitRef)); - _api = new NUnitFrameworkApi2009(this, testDomain, nunitRef); + ID = id; + + // Under .NET Framework, the Api class must be injected in the test domain + //testDomain.AssemblyResolve += TestDomain_AssemblyResolve; + + _api = (NUnitFrameworkApi2018)testDomain.CreateInstanceFromAndUnwrap( + Assembly.GetExecutingAssembly().Location, + typeof(NUnitFrameworkApi2018).FullName!, + false, + 0, + null, + new object[] { ID, nunitRef }, + null, + null).ShouldNotBeNull(); + } + + private Assembly? TestDomain_AssemblyResolve(object? sender, ResolveEventArgs args) + { + //var fileName = args.Name; + return null; } #else /// /// Construct an NUnitFrameworkDriver /// /// An AssemblyName referring to the test framework. - public NUnitFrameworkDriver(AssemblyName nunitRef) + public NUnitFrameworkDriver(string id, AssemblyName nunitRef) { + Guard.ArgumentNotNullOrEmpty(id, nameof(id)); Guard.ArgumentNotNull(nunitRef, nameof(nunitRef)); - _api = new NUnitFrameworkApi2018(this, nunitRef); + ID = id; + + _api = new NUnitFrameworkApi2018(ID, nunitRef); } #endif @@ -75,7 +97,7 @@ public string Load(string testAssemblyPath, IDictionary settings /// An ITestEventHandler that receives progress notices /// A filter that controls which tests are executed /// An Xml string representing the result - public string Run(ITestEventListener? listener, string filter) => _api.Run(listener, filter); + public string Run(ITestEventListener? listener, string filter) => _api.Run(null, filter); /// /// Executes the tests in an assembly asynchronously. diff --git a/src/NUnitEngine/nunit.engine.core/Internal/ProvidedPathsAssemblyResolver.cs b/src/NUnitEngine/nunit.engine.core/Internal/ProvidedPathsAssemblyResolver.cs index 8b178e7bd..4a55fc192 100644 --- a/src/NUnitEngine/nunit.engine.core/Internal/ProvidedPathsAssemblyResolver.cs +++ b/src/NUnitEngine/nunit.engine.core/Internal/ProvidedPathsAssemblyResolver.cs @@ -12,6 +12,8 @@ public class ProvidedPathsAssemblyResolver { static readonly ILogger log = InternalTrace.GetLogger(typeof(ProvidedPathsAssemblyResolver)); + static readonly string THIS_ASSEMBLY_LOCATION = Assembly.GetExecutingAssembly().Location; + public ProvidedPathsAssemblyResolver() { _resolutionPaths = new List(); @@ -21,6 +23,8 @@ public void Install() { Debug.Assert(AppDomain.CurrentDomain.IsDefaultAppDomain()); AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; + + AddPath(THIS_ASSEMBLY_LOCATION); } public void AddPath(string dirPath) diff --git a/src/NUnitEngine/nunit.engine.core/Runners/TestAgentRunner.cs b/src/NUnitEngine/nunit.engine.core/Runners/TestAgentRunner.cs index cdf2d623a..83cde05df 100644 --- a/src/NUnitEngine/nunit.engine.core/Runners/TestAgentRunner.cs +++ b/src/NUnitEngine/nunit.engine.core/Runners/TestAgentRunner.cs @@ -48,10 +48,11 @@ public bool IsPackageLoaded public TestAgentRunner(TestPackage package) { Guard.ArgumentNotNull(package, nameof(package)); + //Guard.ArgumentValid(package.IsAssemblyPackage(), "TestAgentRunner requires a package with a single assembly", nameof(package)); var assemblyPackages = package.Select(p => !p.HasSubPackages()); Guard.ArgumentValid(assemblyPackages.Count == 1, "TestAgentRunner requires a package with a single assembly", nameof(package)); - TestPackage = assemblyPackages[0]; + TestPackage = package; // Bypass the resolver if not in the default AppDomain. This prevents trying to use the resolver within // NUnit's own automated tests (in a test AppDomain) which does not make sense anyway. @@ -89,7 +90,6 @@ public TestEngineResult Explore(TestFilter filter) public virtual TestEngineResult Load() { Guard.OperationValid(TestDomain != null, "TestDomain is not set"); - AppDomain testDomain = TestDomain; var result = new TestEngineResult(); @@ -105,7 +105,7 @@ public virtual TestEngineResult Load() string? targetFramework = assemblyPackage.GetSetting(InternalEnginePackageSettings.ImageTargetFrameworkName, (string?)null); bool skipNonTestAssemblies = assemblyPackage.GetSetting(EnginePackageSettings.SkipNonTestAssemblies, false); - if (_assemblyResolver != null && !testDomain.IsDefaultAppDomain() + if (_assemblyResolver != null && !TestDomain.IsDefaultAppDomain() && assemblyPackage.GetSetting(InternalEnginePackageSettings.ImageRequiresDefaultAppDomainAssemblyResolver, false)) { // It's OK to do this in the loop because the Add method @@ -113,7 +113,7 @@ public virtual TestEngineResult Load() _assemblyResolver.AddPathFromFile(testFile); } - _driver = DriverService.GetDriver(testDomain, testFile, targetFramework, skipNonTestAssemblies); + _driver = DriverService.GetDriver(TestDomain, assemblyPackage, testFile, targetFramework, skipNonTestAssemblies); _driver.ID = assemblyPackage.ID; diff --git a/src/NUnitEngine/nunit.engine.tests/Services/TestFilteringTests.cs b/src/NUnitEngine/nunit.engine.tests/Services/TestFilteringTests.cs index 3fe99c6cd..667cf56fa 100644 --- a/src/NUnitEngine/nunit.engine.tests/Services/TestFilteringTests.cs +++ b/src/NUnitEngine/nunit.engine.tests/Services/TestFilteringTests.cs @@ -20,11 +20,13 @@ public class TestFilteringTests public void LoadAssembly() { var mockAssemblyPath = System.IO.Path.Combine(TestContext.CurrentContext.TestDirectory, MOCK_ASSEMBLY); - var assemblyName = typeof(TestAttribute).Assembly.GetName(); -#if NETCOREAPP3_1_OR_GREATER - _driver = new NUnitFrameworkDriver(assemblyName); + var nunitRef = typeof(TestAttribute).Assembly.GetName(); + var assemblyPath = typeof(TestAttribute).Assembly.Location; + string driverId = "99"; +#if NETFRAMEWORK + _driver = new NUnitFrameworkDriver(AppDomain.CurrentDomain, driverId, nunitRef); #else - _driver = new NUnitFrameworkDriver(AppDomain.CurrentDomain, assemblyName); + _driver = new NUnitFrameworkDriver(driverId, nunitRef); #endif _driver.Load(mockAssemblyPath, new Dictionary()); } diff --git a/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs b/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs index 18070773c..c708bc895 100644 --- a/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs +++ b/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs @@ -28,6 +28,9 @@ public class ProcessRunner : TestEngineRunner public ProcessRunner(IServiceLocator services, TestPackage package) : base(services, package) { _agency = Services.GetService(); + + var assemblyPackages = package.Select(p => !p.HasSubPackages()); + Guard.ArgumentValid(assemblyPackages.Count == 1, $"{GetType().Name} requires a package with a single assembly", nameof(package)); } /// diff --git a/src/NUnitEngine/nunit.engine/Runners/TestEngineRunner.cs b/src/NUnitEngine/nunit.engine/Runners/TestEngineRunner.cs index 521e5e36d..bd9e2188e 100644 --- a/src/NUnitEngine/nunit.engine/Runners/TestEngineRunner.cs +++ b/src/NUnitEngine/nunit.engine/Runners/TestEngineRunner.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; using NUnit.Common; +using NUnit.Engine.Internal; namespace NUnit.Engine.Runners { diff --git a/src/NUnitEngine/nunit.engine/Runners/WorkItemTracker.cs b/src/NUnitEngine/nunit.engine/Runners/WorkItemTracker.cs index f18231a9b..88aa94b11 100644 --- a/src/NUnitEngine/nunit.engine/Runners/WorkItemTracker.cs +++ b/src/NUnitEngine/nunit.engine/Runners/WorkItemTracker.cs @@ -1,7 +1,9 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt +using NUnit.Engine.Internal; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Text; using System.Threading; @@ -63,6 +65,8 @@ public int CompareTo(InProgressItem? other) } } + private static readonly ILogger log = InternalTrace.GetLogger(nameof(InProgressItem)); + // items are keyed by id private readonly Dictionary _itemsInProcess = new Dictionary(); private readonly ManualResetEvent _allItemsComplete = new ManualResetEvent(false); diff --git a/src/TestData/FakeExtensions/FakeExtensions.cs b/src/TestData/FakeExtensions/FakeExtensions.cs index f0ac2be6e..41fb228bf 100644 --- a/src/TestData/FakeExtensions/FakeExtensions.cs +++ b/src/TestData/FakeExtensions/FakeExtensions.cs @@ -12,10 +12,10 @@ namespace NUnit.Engine.Tests [Extension] public class DummyFrameworkDriverExtension : IDriverFactory { -#if !NETFRAMEWORK - public IFrameworkDriver GetDriver(AssemblyName reference) +#if NETFRAMEWORK + public IFrameworkDriver GetDriver(AppDomain domain, string id, AssemblyName reference) #else - public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName reference) + public IFrameworkDriver GetDriver(string id, AssemblyName reference) #endif { throw new NotImplementedException();