// 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.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Core single-test execution logic. /// internal sealed partial class TestMethodRunner { private async Task ExecuteTestAsync(ITestContext executionContext, TestMethodInfo testMethodInfo) { TestResult[] results; try { ExecutionContext? capturedContext = testMethodInfo.Parent.ExecutionContext ?? testMethodInfo.Parent.Parent.ExecutionContext; // Fast path: when no ExecutionContext was captured (the common case), // ExecutionContextHelpers.RunOnContext would simply call the action inline. // Skip the TaskCompletionSource bridge, async-lambda closure, and Action // delegate allocations entirely. if (capturedContext is null) { using (TestContextImplementation.SetCurrentTestContext(executionContext as TestContext)) { testMethodInfo.TestContext = executionContext; results = _executionActivityLease is null ? await _testMethodInfo.Executor.ExecuteAsync(testMethodInfo).ConfigureAwait(false) : await _executionActivityLease.RunAsync( () => _testMethodInfo.Executor.ExecuteAsync(testMethodInfo)).ConfigureAwait(false); } } else { var tcs = new TaskCompletionSource(); #pragma warning disable VSTHRD101 // Avoid unsupported async delegates ExecutionContextHelpers.RunOnContext( capturedContext, async () => { try { using (TestContextImplementation.SetCurrentTestContext(executionContext as TestContext)) { testMethodInfo.TestContext = executionContext; TestResult[] executionResults = _executionActivityLease is null ? await _testMethodInfo.Executor.ExecuteAsync(testMethodInfo).ConfigureAwait(false) : await _executionActivityLease.RunAsync( () => _testMethodInfo.Executor.ExecuteAsync(testMethodInfo)).ConfigureAwait(false); tcs.SetResult(executionResults); } } catch (Exception e) { tcs.SetException(e); } }); #pragma warning restore VSTHRD101 // Avoid unsupported async delegates results = await tcs.Task.ConfigureAwait(false); } } catch (Exception ex) { results = [ new TestResult { TestFailureException = new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, _testMethodInfo.Executor.GetType().FullName, ex.ToString()), ex), }, ]; } return results; } /// /// Updates each given result with new execution and parent execution identifiers. /// /// Results. private static void UpdateResultsWithParentInfo(List results) { foreach (TestResult result in results) { result.ExecutionId = Guid.NewGuid(); result.ParentExecId = Guid.NewGuid(); } } }