Skip to content

Results are sometimes not propagated #63

@ChristoWolf

Description

@ChristoWolf

Hi!

Not sure how to really put this, but I have encountered this behavior now a few times.

Sometimes, when setting some result variable in PoseContext.Isolate, the variable's content is not changed.

I have below an example where it happens, but I also haven't figured out yet how to pinpoint the issue.
What happens:

  • The shim is executed (breakpoints in it are hit).
  • PoseContext.Isolate throws:
     System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
      at stub_callvirt_FluentAssertions.Primitives.ObjectAssertions`2[System.Object,FluentAssertions.Primitives.ObjectAssertions]_BeEquivalentTo[Point](ObjectAssertions`2 , Point , String , Object[] )
    --- End of inner exception stack trace ---
        at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Delegate.DynamicInvokeImpl(Object[] args)
       at System.Delegate.DynamicInvoke(Object[] args)
       at Pose.PoseContext.Isolate(Action entryPoint, Shim[] shims)
    
[TestMethod]
[DoNotParallelize]
public void TestGetCenterViaClickablePoint()
{
    var point = new System.Windows.Point(123, 3456);
    var expected = new Point((int)point.X, (int)point.Y);
    var matcher = Is.A<System.Windows.Point>();
    var shim = Shim.Replace(() =>
        Is.A<AutomationElement>().TryGetClickablePoint(out matcher))
        .With((AutomationElement @this, out System.Windows.Point p) =>
        {
            p = point;
            return true;
        });
    Point? actual = null;

    PoseContext.Isolate(() =>
        {
            actual = sut.GetCenter();
            actual.Should().BeEquivalentTo(expected);
        }, shim);
}

with

public static Point GetCenter(this AutomationElement element)
{
    if (!element.TryGetClickablePoint(out var point))
    {
        var rect = element.Current.BoundingRectangle;
        point = new(
            (int)(rect.Left + rect.Width / 2),
            (int)(rect.Top + rect.Height / 2));
    }
    return new Point((int)point.X, (int)point.Y);
}

When the assertion is moved outside of PoseContext.Isolate, then the test host crashes:

The active test run was aborted. Reason: Test host process crashed : Fatal error. Internal CLR error. (0x80131506)
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span`1<System.Object> ByRef, System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at System.Delegate.DynamicInvokeImpl(System.Object[])
   at System.Delegate.DynamicInvoke(System.Object[])
   at Pose.PoseContext.Isolate(System.Action, Pose.Shim[])
   at <redacted>.TestGetCenterViaClickablePoint()
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span`1<System.Object> ByRef, System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at System.Reflection.MethodBase.Invoke(System.Object, System.Object[])
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions.MethodInfoExtensions.InvokeAsSynchronousTask(System.Reflection.MethodInfo, System.Object, System.Object[])
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo+<>c__DisplayClass40_0.<ExecuteInternal>b__0()
   at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.ThreadOperations.ExecuteWithAbortSafety(System.Action)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.ExecuteInternal(System.Object[])
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.Invoke(System.Object[])
   at Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Execute(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner.ExecuteTest(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner.RunTestMethod()
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner.Execute()
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner.RunSingleTest(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.TestMethod, System.Collections.Generic.IDictionary`2<System.String,System.Object>)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager.ExecuteTestsWithTestRunner(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestExecutionRecorder, System.String, System.Collections.Generic.IDictionary`2<System.String,System.Object>, Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager.ExecuteTestsInSource(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle, System.String, Boolean)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager.ExecuteTests(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle, Boolean)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager.RunTests(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle, Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestRunCancellationToken)
   at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestExecutor.RunTests(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle)
   at Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators.SerialTestRunDecorator.RunTests(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle)
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.RunTestsWithTests.InvokeExecutor(Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities.LazyExtension`2<Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestExecutor,Microsoft.VisualStudio.TestPlatform.Common.Interfaces.ITestExecutorCapabilities>, System.Tuple`2<System.Uri,System.String>, Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Adapter.RunContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IFrameworkHandle)
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.RunTestInternalWithExecutors(System.Collections.Generic.IEnumerable`1<System.Tuple`2<System.Uri,System.String>>, Int64)
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.RunTestsInternal()
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.BaseRunTests.RunTests()
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.ExecutionManager.StartTestRun(System.Collections.Generic.IEnumerable`1<Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase>, System.String, System.String, Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.ClientProtocol.TestExecutionContext, Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.ITestCaseEventsHandler, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IInternalTestRunEventsHandler)
   at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler+<>c__DisplayClass45_5.<OnMessageReceived>b__4()
   at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler+<>c.<.ctor>b__31_2(System.Action)
   at Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].SafeProcessJob(System.__Canon)
   at Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].BackgroundJobProcessor(System.String)
   at Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<.ctor>b__16_0()
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task+<>c.<.cctor>b__272_0(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef, System.Threading.Thread)
   at System.Threading.Tasks.Task.ExecuteEntryUnsafe(System.Threading.Thread)
   at System.Threading.Tasks.ThreadPoolTaskScheduler+<>c.<.cctor>b__10_0(System.Object)
   at System.Threading.Thread.StartCallback()

If I instead execute (notice actual being initialized with Point.Empty, being a value type)

var point = new System.Windows.Point(123, 3456);
var expected = new Point((int)point.X, (int)point.Y);
var matcher = Is.A<System.Windows.Point>();
var shim = Shim.Replace(() =>
    Is.A<AutomationElement>().TryGetClickablePoint(out matcher))
    .With((AutomationElement @this, out System.Windows.Point p) =>
    {
        p = point;
        return true;
    });
var actual = Point.Empty;

PoseContext.Isolate(() =>
    {
        actual = sut.GetCenter();
    }, shim);

actual.Should().BeEquivalentTo(expected);

nothing crashes, but the test fails with

Expected actual to be {X=123,Y=3456}, but found {X=0,Y=0}.

So I guess it might have something to do with the type of the variable to be set, but I have no other idea what's going on.

Any help would be greatly appreciated!

Versions used:

  • .NET 8 SDK
  • Poser v2.1.0
  • MSTest v2.2.10

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpriority: lowThe issue has low priorityquestion/investigationFurther information or investigation is required

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions