await operation in step causing thread switching(from a managed thread to thread pool thread) when using reqnroll while specflow continues to execute using same managed thread #564
Replies: 1 comment
-
Duplicate of #563 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
We are currently migrating from specflow to reqnroll. Specflow tests are configured to use "Nunit" as test execution framework and run in parallell(Parallelizable(ParallelScope.Fixtures).
Existing implementation:
BeforeTestRun hook: Registering CustomValueComparerRetriever(Implementation of IValueRetriever,IValueComparer) with reqnroll.assisst.Service.
BeforeFeature hook: creates an entry in dictionary object with threadId and objectcontainer for every execution of hook.
please see below for code samples.
[Binding]
internal class AssistRetrieverAndComparerRegistrationHooks
{
private static readonly Dictionary<int, List> ThreadFeatureContainers = new();
[BeforeFeature]
public static void BeforeFeature(IObjectContainer container,IContextManager manager)
{
var threadId = Environment.CurrentManagedThreadId;
}
[BeforeTestRun]
public static void BeforeTestRun(ILogger logger)
{
var valueRetrieverComparer = new StepArgumentTransformationValueRetrieverComparer(ThreadFeatureContainers);
lock (Reqnroll.Assist.Service.Instance)
{
logger.LogDebug("Registering StepArgumentTransformation value Retriever/Comparer");
if (!Reqnroll.Assist.Service.Instance.ValueRetrievers.OfType().Any())
{
Reqnroll.Assist.Service.Instance.ValueRetrievers.Register(valueRetrieverComparer);
}
}
}
CustomValueRetrieverComparer
internal class StepArgumentTransformationValueRetrieverComparer : IValueRetriever,
IValueComparer
{
private readonly IDictionary<int, List> _containers;
public bool CanRetrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type propertyType)
{
if (GetContainer() is not IObjectContainer container)
{
return false;
}
}
public object Retrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type propertyType)
{
if (GetContainer() is not IObjectContainer container)
{
return false;
}
}
private IObjectContainer GetContainer()
{
lock (_containers)
{
return _containers.TryGetValue(Environment.CurrentManagedThreadId, out var result)
? result.LastOrDefault()
: null;
}
}
While invoking Table.CreateInstance() method from a step, assist.service is invoking canretrieve on the customvaluecomparerretriever which is fetching objectcontainer related to the current feature passing the currentmanagedThreadId to dictionary(created in beforeFeaturehook) it worked fine in specflow but after migrating to reqnroll thread executing the canretrieve of customValueComparerRetriever is different from thread executing the beforefeature hook.Hence we are not able to get objectcontainer of current feature hence not able to create instance from table.
Note:There is an await call in one of the steps which causing the switch from managed thread(that executed beforefeaturehook) to a threadpool thread to takeover the subsequent execution whereas same await operation when used with specflow did not cause switching to a threadpool thread. I am assuming this switching is internal to .NET asyn/await implementation but I am wondering why this is not happening any time while using specflow.
Can you please help me how to deal with this problem or change the implementation for reqnroll?
Beta Was this translation helpful? Give feedback.
All reactions