Skip to content

Commit

Permalink
Separate TestThreadContext from ITestRunner and handle ITestRunner.Te…
Browse files Browse the repository at this point in the history
…stWorkerId test framework independently
  • Loading branch information
obligaron committed Jun 4, 2024
1 parent f3ef016 commit 6953ab0
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 142 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Update [versioning policy for plugins](https://docs.reqnroll.net/latest/installation/compatibility.html#versioning-policy) and set plugin dependencies accordingly (#160)
* Generate symbol packages, use deterministic build and update package metadata (#161)
* Separate `TestThreadContext` from `ITestRunner` and handle `ITestRunner.TestWorkerId` test framework independently

# v2.0.2 - 2024-05-31

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Public NotInheritable Class PROJECT_ROOT_NAMESPACE_MSTestAssemblyHooks
Public Shared Async Function AssemblyInitializeAsync(testContext As TestContext) As Task
Dim currentAssembly As Assembly = GetType(PROJECT_ROOT_NAMESPACE_MSTestAssemblyHooks).Assembly
Dim containerBuilder As New MsTestContainerBuilder(testContext)
Await Global.Reqnroll.TestRunnerManager.OnTestRunStartAsync(currentAssembly, Nothing, containerBuilder)
Await Global.Reqnroll.TestRunnerManager.OnTestRunStartAsync(currentAssembly, containerBuilder)
End Function

<AssemblyCleanup>
Expand Down

This file was deleted.

17 changes: 9 additions & 8 deletions Reqnroll.Generator/Generation/UnitTestFeatureGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,9 @@ private void SetupTestClassInitializeMethod(TestClassGenerationContext generatio
//testRunner = TestRunnerManager.GetTestRunnerForAssembly(null, [test_worker_id]);
var testRunnerField = _scenarioPartHelper.GetTestRunnerExpression();

var testRunnerParameters = new[]
{
new CodePrimitiveExpression(null),
_testGeneratorProvider.GetTestWorkerIdExpression()
};

var getTestRunnerExpression = new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression(_codeDomHelper.GetGlobalizedTypeName(typeof(TestRunnerManager))),
nameof(TestRunnerManager.GetTestRunnerForAssembly), testRunnerParameters);
nameof(TestRunnerManager.GetTestRunnerForAssembly));

testClassInitializeMethod.Statements.Add(
new CodeAssignStatement(
Expand Down Expand Up @@ -238,7 +232,14 @@ private void SetupTestClassCleanupMethod(TestClassGenerationContext generationCo
_codeDomHelper.MarkCodeMethodInvokeExpressionAsAwait(expression);

testClassCleanupMethod.Statements.Add(expression);


//
testClassCleanupMethod.Statements.Add(
new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression(_codeDomHelper.GetGlobalizedTypeName(typeof(TestRunnerManager))),
nameof(TestRunnerManager.ReleaseTestRunner),
testRunnerField));

// testRunner = null;
testClassCleanupMethod.Statements.Add(
new CodeAssignStatement(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,5 @@ public interface IUnitTestGeneratorProvider
void SetTestMethodAsRow(TestClassGenerationContext generationContext, CodeMemberMethod testMethod, string scenarioTitle, string exampleSetName, string variantName, IEnumerable<KeyValuePair<string, string>> arguments);

void MarkCodeMethodInvokeExpressionAsAwait(CodeMethodInvokeExpression expression);

CodeExpression GetTestWorkerIdExpression();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,5 @@ public void MarkCodeMethodInvokeExpressionAsAwait(CodeMethodInvokeExpression exp
{
CodeDomHelper.MarkCodeMethodInvokeExpressionAsAwait(expression);
}

public CodeExpression GetTestWorkerIdExpression()
{
// System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()
return new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression("System.Threading.Thread.CurrentThread.ManagedThreadId"),
nameof(ToString)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,5 @@ public void MarkCodeMethodInvokeExpressionAsAwait(CodeMethodInvokeExpression exp
{
CodeDomHelper.MarkCodeMethodInvokeExpressionAsAwait(expression);
}

public CodeExpression GetTestWorkerIdExpression()
=> new CodePropertyReferenceExpression(GetTestContextExpression(), TESTCONTEXT_WORKERID_PROPERTY);
}
}
22 changes: 0 additions & 22 deletions Reqnroll.Generator/UnitTestProvider/XUnit2TestGeneratorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public class XUnit2TestGeneratorProvider : IUnitTestGeneratorProvider
protected internal const string IGNORE_TEST_CLASS = "IgnoreTestClass";
protected internal const string NONPARALLELIZABLE_COLLECTION_NAME = "ReqnrollNonParallelizableFeatures";
protected internal const string IASYNCLIFETIME_INTERFACE = "Xunit.IAsyncLifetime";
protected internal const string XUNITPARALLELWORKERTRACKER_INSTANCE = "Reqnroll.xUnit.ReqnrollPlugin.XUnitParallelWorkerTracker.Instance";

public XUnit2TestGeneratorProvider(CodeDomHelper codeDomHelper)
{
Expand Down Expand Up @@ -178,19 +177,6 @@ public virtual void FinalizeTestClass(TestClassGenerationContext generationConte
nameof(IObjectContainer.RegisterInstanceAs),
new CodeTypeReference(OUTPUT_INTERFACE)),
new CodeVariableReferenceExpression(OUTPUT_INTERFACE_FIELD_NAME)));

// Wrap FeatureTearDown:
// var testWorkerId = <testRunner>.TestWorkerId;
// <FeatureTearDown>
// XUnitParallelWorkerTracker.Instance.ReleaseWorker(testWorkerId);
generationContext.TestClassCleanupMethod.Statements.Insert(0,
new CodeVariableDeclarationStatement(typeof(string), "testWorkerId",
new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(generationContext.TestRunnerField.Name), "TestWorkerId")));
generationContext.TestClassCleanupMethod.Statements.Add(
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression(GlobalNamespaceIfCSharp(XUNITPARALLELWORKERTRACKER_INSTANCE)),
"ReleaseWorker",
new CodeVariableReferenceExpression("testWorkerId")));
}

protected virtual void IgnoreFeature(TestClassGenerationContext generationContext)
Expand Down Expand Up @@ -414,14 +400,6 @@ public void MarkCodeMethodInvokeExpressionAsAwait(CodeMethodInvokeExpression exp
CodeDomHelper.MarkCodeMethodInvokeExpressionAsAwait(expression);
}

public CodeExpression GetTestWorkerIdExpression()
{
// XUnitParallelWorkerTracker.Instance.GetWorkerId()
return new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression(GlobalNamespaceIfCSharp(XUNITPARALLELWORKERTRACKER_INSTANCE)),
"GetWorkerId");
}

private string GlobalNamespaceIfCSharp(string typeName)
{
return CodeDomHelper.TargetLanguage == CodeDomProviderLanguage.CSharp ? "global::" + typeName : typeName;
Expand Down
2 changes: 1 addition & 1 deletion Reqnroll/ISyncTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Reqnroll
public interface ISyncTestRunner
{
/// <summary>
/// The ID of the parallel test worker processing the current scenario. How the worker ID is obtained is dependent on the test execution framework.
/// The ID of the parallel test worker processing the current scenario.
/// </summary>
string TestWorkerId { get; }

Expand Down
4 changes: 3 additions & 1 deletion Reqnroll/ITestRunner.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
using System;
using System.Threading.Tasks;

namespace Reqnroll
{
public interface ITestRunner
{
/// <summary>
/// The ID of the parallel test worker processing the current scenario. How the worker ID is obtained is dependent on the test execution framework.
/// The ID of the parallel test worker processing the current scenario.
/// </summary>
string TestWorkerId { get; }
FeatureContext FeatureContext { get; }
ScenarioContext ScenarioContext { get; }
ITestThreadContext TestThreadContext { get; }

[Obsolete("TestWorkerId is now managed by Reqnroll internally - Method will be removed in v3")]
void InitializeTestRunner(string testWorkerId);

Task OnTestRunStartAsync();
Expand Down
3 changes: 2 additions & 1 deletion Reqnroll/ITestRunnerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public interface ITestRunnerManager
Assembly TestAssembly { get; }
Assembly[] BindingAssemblies { get; }
bool IsMultiThreaded { get; }
ITestRunner GetTestRunner(string workerId);
ITestRunner GetTestRunner();
void ReleaseTestThreadContext(ITestThreadContext testThreadContext);
void Initialize(Assembly testAssembly);
Task FireTestRunEndAsync();
Task FireTestRunStartAsync();
Expand Down
21 changes: 21 additions & 0 deletions Reqnroll/Infrastructure/TestThreadContainerInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Reqnroll.BoDi;

namespace Reqnroll.Infrastructure;

internal class TestThreadContainerInfo
{
internal string Id { get; }

internal TestThreadContainerInfo(string id)
{
Id = id;
}

internal static string GetId(IObjectContainer objectContainer)
{
if (!objectContainer.IsRegistered<TestThreadContainerInfo>())
return null;
var testThreadContainerInfo = objectContainer.Resolve<TestThreadContainerInfo>();
return testThreadContainerInfo.Id;
}
}
6 changes: 4 additions & 2 deletions Reqnroll/TestRunner.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using Reqnroll.Bindings;
using Reqnroll.Infrastructure;
Expand All @@ -8,7 +9,7 @@ public class TestRunner : ITestRunner
{
private readonly ITestExecutionEngine _executionEngine;

public string TestWorkerId { get; private set; }
public string TestWorkerId => TestThreadContainerInfo.GetId(TestThreadContext.TestThreadContainer);

public TestRunner(ITestExecutionEngine executionEngine)
{
Expand All @@ -26,9 +27,10 @@ public async Task OnTestRunStartAsync()
await _executionEngine.OnTestRunStartAsync();
}

[Obsolete("TestWorkerId is now managed by Reqnroll internally - Method will be removed in v3")]
public void InitializeTestRunner(string testWorkerId)
{
TestWorkerId = testWorkerId;
// do nothing method will be removed
}

public async Task OnFeatureStartAsync(FeatureInfo featureInfo)
Expand Down
Loading

0 comments on commit 6953ab0

Please sign in to comment.