-
Notifications
You must be signed in to change notification settings - Fork 269
/
Copy pathTestHostTestFrameworkInvoker.cs
95 lines (75 loc) · 5.13 KB
/
TestHostTestFrameworkInvoker.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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Testing.Platform.Capabilities;
using Microsoft.Testing.Platform.Capabilities.TestFramework;
using Microsoft.Testing.Platform.Extensions.Messages;
using Microsoft.Testing.Platform.Extensions.OutputDevice;
using Microsoft.Testing.Platform.Extensions.TestFramework;
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.Logging;
using Microsoft.Testing.Platform.Messages;
using Microsoft.Testing.Platform.OutputDevice;
using Microsoft.Testing.Platform.Resources;
using Microsoft.Testing.Platform.Services;
using Microsoft.Testing.Platform.TestHost;
namespace Microsoft.Testing.Platform.Requests;
[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "HotReload needs to inherit and override ExecuteRequestAsync")]
internal class TestHostTestFrameworkInvoker(IServiceProvider serviceProvider) : ITestFrameworkInvoker, IOutputDeviceDataProducer, IDataProducer
{
protected IServiceProvider ServiceProvider { get; } = serviceProvider;
public string Uid => nameof(TestHostTestFrameworkInvoker);
public string Version => AppVersion.DefaultSemVer;
public string DisplayName => string.Empty;
public string Description => string.Empty;
public Type[] DataTypesProduced => [typeof(TestRequestExecutionTimeInfo)];
public Task<bool> IsEnabledAsync() => Task.FromResult(true);
public async Task ExecuteAsync(ITestFramework testFramework, ClientInfo client, CancellationToken cancellationToken)
{
ILogger<TestHostTestFrameworkInvoker> logger = ServiceProvider.GetLoggerFactory().CreateLogger<TestHostTestFrameworkInvoker>();
await logger.LogInformationAsync($"Test framework UID: '{testFramework.Uid}' Version: '{testFramework.Version}' DisplayName: '{testFramework.DisplayName}' Description: '{testFramework.Description}'");
foreach (ICapability capability in ServiceProvider.GetTestFrameworkCapabilities().Capabilities)
{
if (capability is ITestNodesTreeFilterTestFrameworkCapability testNodesTreeFilterCapability)
{
await logger.LogInformationAsync($"ITestNodesTreeFilterCapability.IsSupported: {testNodesTreeFilterCapability.IsSupported}");
}
}
DateTimeOffset startTime = DateTimeOffset.UtcNow;
var stopwatch = Stopwatch.StartNew();
SessionUid sessionId = ServiceProvider.GetTestSessionContext().SessionId;
CreateTestSessionResult createTestSessionResult = await testFramework.CreateTestSessionAsync(new(sessionId, client, cancellationToken));
await HandleTestSessionResultAsync(createTestSessionResult.IsSuccess, createTestSessionResult.WarningMessage, createTestSessionResult.ErrorMessage);
ITestExecutionRequestFactory testExecutionRequestFactory = ServiceProvider.GetTestExecutionRequestFactory();
TestExecutionRequest request = await testExecutionRequestFactory.CreateRequestAsync(new(sessionId, client));
IMessageBus messageBus = ServiceProvider.GetMessageBus();
// Execute the test request
var taskCompletionSource = new TaskCompletionSource();
using CancellationTokenRegistration r = cancellationToken.Register(() => taskCompletionSource.TrySetCanceled());
await Task.WhenAny(ExecuteRequestAsync(testFramework, request, messageBus, cancellationToken), taskCompletionSource.Task);
CloseTestSessionResult closeTestSessionResult = await testFramework.CloseTestSessionAsync(new(sessionId, client, cancellationToken));
await HandleTestSessionResultAsync(closeTestSessionResult.IsSuccess, closeTestSessionResult.WarningMessage, closeTestSessionResult.ErrorMessage);
DateTimeOffset endTime = DateTimeOffset.UtcNow;
await messageBus.PublishAsync(this, new TestRequestExecutionTimeInfo(new TimingInfo(startTime, endTime, stopwatch.Elapsed)));
}
public virtual async Task ExecuteRequestAsync(ITestFramework testFramework, TestExecutionRequest request, IMessageBus messageBus, CancellationToken cancellationToken)
{
await Task.Yield();
using SemaphoreSlim requestSemaphore = new(0, 1);
await testFramework.ExecuteRequestAsync(new(request, messageBus, new SemaphoreSlimRequestCompleteNotifier(requestSemaphore), cancellationToken));
await requestSemaphore.WaitAsync(cancellationToken);
}
private async Task HandleTestSessionResultAsync(bool isSuccess, string? warningMessage, string? errorMessage)
{
if (warningMessage is not null)
{
IOutputDevice outputDisplay = ServiceProvider.GetOutputDevice();
await outputDisplay.DisplayAsync(this, new WarningMessageOutputDeviceData(warningMessage));
}
if (!isSuccess)
{
ITestApplicationProcessExitCode testApplicationProcessExitCode = ServiceProvider.GetTestApplicationProcessExitCode();
await testApplicationProcessExitCode.SetTestAdapterTestSessionFailureAsync(errorMessage
?? PlatformResources.TestHostAdapterInvokerFailedTestSessionErrorMessage);
}
}
}