-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathFrameworkHandlerAdapter.cs
189 lines (159 loc) · 7.58 KB
/
FrameworkHandlerAdapter.cs
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
using Microsoft.Testing.Extensions.VSTestBridge.Helpers;
using Microsoft.Testing.Platform.Capabilities.TestFramework;
using Microsoft.Testing.Platform.CommandLine;
using Microsoft.Testing.Platform.Extensions.Messages;
using Microsoft.Testing.Platform.Logging;
using Microsoft.Testing.Platform.Messages;
using Microsoft.Testing.Platform.OutputDevice;
using Microsoft.Testing.Platform.Services;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using TestSessionContext = Microsoft.Testing.Platform.TestHost.TestSessionContext;
namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel;
/// <summary>
/// Bridge implementation of <see cref="IFrameworkHandle"/> that forwards calls to VSTest and Microsoft Testing Platforms.
/// </summary>
internal sealed class FrameworkHandlerAdapter : IFrameworkHandle
{
/// <remarks>
/// Not null when used in the context of VSTest.
/// </remarks>
private readonly IFrameworkHandle? _frameworkHandle;
private readonly ILogger<FrameworkHandlerAdapter> _logger;
private readonly IMessageBus _messageBus;
private readonly VSTestBridgedTestFrameworkBase _adapterExtensionBase;
private readonly TestSessionContext _session;
private readonly CancellationToken _cancellationToken;
private readonly bool _isTrxEnabled;
private readonly MessageLoggerAdapter _comboMessageLogger;
private readonly string _testAssemblyPath;
private readonly INamedFeatureCapability? _namedFeatureCapability;
private readonly ICommandLineOptions _commandLineOptions;
public FrameworkHandlerAdapter(
VSTestBridgedTestFrameworkBase adapterExtensionBase,
TestSessionContext session,
string[] testAssemblyPaths,
ITestApplicationModuleInfo testApplicationModuleInfo,
INamedFeatureCapability? namedFeatureCapability,
ICommandLineOptions commandLineOptions,
IMessageBus messageBus,
IOutputDevice outputDevice,
ILoggerFactory loggerFactory,
bool isTrxEnabled,
CancellationToken cancellationToken,
IFrameworkHandle? frameworkHandle = null)
{
if (testAssemblyPaths.Length == 0)
{
throw new ArgumentException($"{nameof(testAssemblyPaths)} should contain at least one test assembly.");
}
else if (testAssemblyPaths.Length > 1)
{
_testAssemblyPath = testApplicationModuleInfo.GetCurrentTestApplicationFullPath();
if (!testAssemblyPaths.Contains(_testAssemblyPath))
{
throw new ArgumentException("None of the test assemblies are the test application.");
}
}
else
{
_testAssemblyPath = testAssemblyPaths[0];
}
_namedFeatureCapability = namedFeatureCapability;
_commandLineOptions = commandLineOptions;
_frameworkHandle = frameworkHandle;
_logger = loggerFactory.CreateLogger<FrameworkHandlerAdapter>();
_messageBus = messageBus;
_adapterExtensionBase = adapterExtensionBase;
_session = session;
_cancellationToken = cancellationToken;
_isTrxEnabled = isTrxEnabled;
_comboMessageLogger = new MessageLoggerAdapter(loggerFactory, outputDevice, adapterExtensionBase, frameworkHandle);
}
/// <inheritdoc/>
public bool EnableShutdownAfterTestRun
{
get => _frameworkHandle?.EnableShutdownAfterTestRun ?? false;
set
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.EnableShutdownAfterTestRun: set to {value}");
if (_frameworkHandle is not null)
{
_frameworkHandle.EnableShutdownAfterTestRun = value;
}
}
}
/// <inheritdoc/>
public int LaunchProcessWithDebuggerAttached(string filePath, string? workingDirectory, string? arguments,
IDictionary<string, string?>? environmentVariables)
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.LaunchProcessWithDebuggerAttached");
return _frameworkHandle?.LaunchProcessWithDebuggerAttached(filePath, workingDirectory, arguments, environmentVariables)
?? -1;
}
/// <inheritdoc/>
public void RecordAttachments(IList<AttachmentSet> attachmentSets)
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.RecordAttachments");
_frameworkHandle?.RecordAttachments(attachmentSets);
PublishTestSessionAttachmentsAsync(attachmentSets).Await();
}
/// <inheritdoc/>
public void RecordEnd(TestCase testCase, TestOutcome outcome)
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.RecordEnd");
_cancellationToken.ThrowIfCancellationRequested();
testCase.FixUpTestCase(_testAssemblyPath);
// Forward call to VSTest
_frameworkHandle?.RecordEnd(testCase, outcome);
}
/// <inheritdoc/>
public void RecordResult(TestResult testResult)
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.RecordResult");
_cancellationToken.ThrowIfCancellationRequested();
testResult.TestCase.FixUpTestCase(_testAssemblyPath);
// Forward call to VSTest
_frameworkHandle?.RecordResult(testResult);
// Publish node state change to Microsoft Testing Platform
var testNode = testResult.ToTestNode(_isTrxEnabled, _namedFeatureCapability, _commandLineOptions);
var testNodeChange = new TestNodeUpdateMessage(_session.SessionUid, testNode);
_messageBus.PublishAsync(_adapterExtensionBase, testNodeChange).Await();
}
/// <inheritdoc/>
public void RecordStart(TestCase testCase)
{
_logger.LogTrace($"{nameof(FrameworkHandlerAdapter)}.RecordStart");
_cancellationToken.ThrowIfCancellationRequested();
testCase.FixUpTestCase(_testAssemblyPath);
// Forward call to VSTest
_frameworkHandle?.RecordStart(testCase);
// Publish node state change to Microsoft Testing Platform
var testNode = testCase.ToTestNode(_isTrxEnabled, _namedFeatureCapability, _commandLineOptions);
testNode.Properties.Add(InProgressTestNodeStateProperty.CachedInstance);
var testNodeChange = new TestNodeUpdateMessage(_session.SessionUid, testNode);
_messageBus.PublishAsync(_adapterExtensionBase, testNodeChange).Await();
}
/// <inheritdoc/>
public void SendMessage(TestMessageLevel testMessageLevel, string message)
=> _comboMessageLogger.SendMessage(testMessageLevel, message);
private async Task PublishTestSessionAttachmentsAsync(IEnumerable<AttachmentSet> attachments)
{
foreach (AttachmentSet attachmentSet in attachments)
{
foreach (UriDataAttachment attachment in attachmentSet.Attachments)
{
if (!attachment.Uri.IsFile)
{
throw new FormatException($"Test adapter {_adapterExtensionBase.DisplayName} only supports file attachments.");
}
var fileArtifact = new SessionFileArtifact(_session.SessionUid, new(attachment.Uri.LocalPath), attachmentSet.DisplayName, attachment.Description);
await _messageBus.PublishAsync(_adapterExtensionBase, fileArtifact);
}
}
}
}