-
Notifications
You must be signed in to change notification settings - Fork 162
Expand file tree
/
Copy pathNUnitFrameworkApi2009.cs
More file actions
168 lines (138 loc) · 6.84 KB
/
Copy pathNUnitFrameworkApi2009.cs
File metadata and controls
168 lines (138 loc) · 6.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using NUnit.Common;
namespace NUnit.Engine.Drivers
{
/// <summary>
/// This is the original NUnit 3 API, which only works for .NET Framework.
/// As far as I can discover, it first appeared in pre-release 2.9.1,
/// on launchpad in 2009, hence the name.
/// </summary>
internal class NUnitFrameworkApi2009 : NUnitFrameworkApi
{
private static readonly Logger log = InternalTrace.GetLogger(nameof(NUnitFrameworkApi2009));
private const string LOAD_MESSAGE = "Method called without calling Load first. Possible error in runner.";
private const string INVALID_FRAMEWORK_MESSAGE = "Running tests against this version of the framework using this driver is not supported. Please update NUnit.Framework to the latest version.";
private const string FAILED_TO_LOAD_ASSEMBLY = "Failed to load assembly ";
private const string FAILED_TO_LOAD_NUNIT = "Failed to load the NUnit Framework in the test assembly";
private const string CONTROLLER_TYPE = "NUnit.Framework.Api.FrameworkController";
private readonly string _driverId;
private readonly AppDomain _testDomain;
private readonly AssemblyName _nunitRef;
private string? _testAssemblyPath;
private object? _frameworkController;
private Type? _frameworkControllerType;
public NUnitFrameworkApi2009(AppDomain testDomain, string driverId, AssemblyName nunitRef)
{
Guard.ArgumentNotNull(testDomain);
Guard.ArgumentNotNull(driverId);
Guard.ArgumentNotNull(nunitRef);
_testDomain = testDomain;
_driverId = driverId;
_nunitRef = nunitRef;
}
public string Load(string testAssemblyPath, IDictionary<string, object> settings)
{
Guard.ArgumentValid(File.Exists(testAssemblyPath), "Framework driver called with a file name that doesn't exist.", nameof(testAssemblyPath));
log.Info($"Loading {testAssemblyPath} - see separate log file");
_testAssemblyPath = testAssemblyPath;
// Normally, the caller should check for an invalid requested runtime, but to be sure,
// we check it. The setting value is only used for an error message.
settings.TryGetValue(SettingDefinitions.RequestedRuntimeFramework.Name, out object? requestedRuntime);
var idPrefix = _driverId + "-";
try
{
_frameworkController = _testDomain.CreateInstanceAndUnwrap(
_nunitRef.FullName,
CONTROLLER_TYPE,
false,
0,
null,
new object[] { _testAssemblyPath, idPrefix, settings },
null,
null).ShouldNotBeNull();
}
catch (BadImageFormatException ex) when (requestedRuntime is not 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);
}
_frameworkControllerType = _frameworkController.GetType();
log.Debug($"Created FrameworkController {_frameworkControllerType.Name}");
return ExecuteAction(LOAD_ACTION);
}
public int CountTestCases(string filter)
{
CheckLoadWasCalled();
return int.Parse(ExecuteAction(COUNT_ACTION, filter));
}
public string Run(ITestEventListener? listener, string filter)
{
CheckLoadWasCalled();
log.Info("Running {0} - see separate log file", Path.GetFileName(_testAssemblyPath.ShouldNotBeNull()));
return ExecuteAction(RUN_ACTION, listener, filter);
}
public void RunAsync(Action<string>? callback, string filter) => throw new NotImplementedException();
public void RequestStop() => ExecuteAction(STOP_RUN_ACTION, false);
public void ForcedStop() => ExecuteAction(STOP_RUN_ACTION, true);
public bool ForcedStopSupported => true;
public string Explore(string filter)
{
CheckLoadWasCalled();
log.Info("Exploring {0} - see separate log file", Path.GetFileName(_testAssemblyPath.ShouldNotBeNull()));
return ExecuteAction(EXPLORE_ACTION, filter);
}
private void CheckLoadWasCalled()
{
if (_frameworkController is null)
throw new InvalidOperationException(LOAD_MESSAGE);
}
// Actions with no extra arguments beyond controller and handler
private const string LOAD_ACTION = CONTROLLER_TYPE + "+LoadTestsAction";
private string ExecuteAction(string action)
{
CallbackHandler handler = new CallbackHandler();
CreateObject(action, _frameworkController, handler);
return handler.Result.ShouldNotBeNull();
}
// Actions with one extra argument
private const string EXPLORE_ACTION = CONTROLLER_TYPE + "+ExploreTestsAction";
private const string COUNT_ACTION = CONTROLLER_TYPE + "+CountTestsAction";
private const string STOP_RUN_ACTION = CONTROLLER_TYPE + "+StopRunAction";
private string ExecuteAction(string action, object arg1)
{
CallbackHandler handler = new CallbackHandler();
CreateObject(action, _frameworkController, arg1, handler);
return handler.Result.ShouldNotBeNull();
}
// Run action has two extra arguments and uses a special handler
private const string RUN_ACTION = CONTROLLER_TYPE + "+RunTestsAction";
private string ExecuteAction(string action, ITestEventListener? listener, string filter)
{
RunTestsCallbackHandler handler = new RunTestsCallbackHandler(listener);
CreateObject(action, _frameworkController, filter, handler);
return handler.Result.ShouldNotBeNull();
}
private object CreateObject(string typeName, params object?[]? args)
{
try
{
return _testDomain.CreateInstanceAndUnwrap(
_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);
}
}
}
}
#endif