Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add System.ComponentModel.EventBasedAsync tests #20931

Merged
merged 4 commits into from
Jun 19, 2017
Merged

Add System.ComponentModel.EventBasedAsync tests #20931

merged 4 commits into from
Jun 19, 2017

Conversation

hughbe
Copy link

@hughbe hughbe commented Jun 12, 2017

This increases CC to 100% in the library

@hughbe
Copy link
Author

hughbe commented Jun 12, 2017

I may need some help here...

I get the following errors when I use RemoteInvoke, which don't occur without RemoteInvoke. They seem to be coming from the main method of RemoteExecutorConsoleApp...

  Discovering: System.ComponentModel.EventBasedAsync.Tests
  Discovered:  System.ComponentModel.EventBasedAsync.Tests
  Starting:    System.ComponentModel.EventBasedAsync.Tests
  Exception from RemoteExecutorConsoleApp(System.ComponentModel.EventBasedAsync.Tests, Version=4.1.1.0, Culture=neutral
  , PublicKeyToken=9d77cc7ad39b68eb, System.ComponentModel.Tests.AsyncOperationFinalizerTests+<>c__DisplayClass2_0, <Fi
  nalizer_OperationCompleted_CompletesOperation>b__0):
  Assembly: System.ComponentModel.EventBasedAsync.Tests, Version=4.1.1.0, Culture=neutral, PublicKeyToken=9d77cc7ad39b6
  8eb
  Type: System.ComponentModel.Tests.AsyncOperationFinalizerTests+<>c__DisplayClass2_0
  Method: Int32 <Finalizer_OperationCompleted_CompletesOperation>b__0()
  Exception: 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 System.ComponentModel.Tests.AsyncOperationFinalizerTests.<>c__DisplayClass2_0.<Finalizer_OperationCompleted_Com
  pletesOperation>b__0()
     --- End of inner exception stack trace ---
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
     at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
     at RemoteExecutorConsoleApp.Program.Main(String[] args)

  Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invoc
  ation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
     at System.ComponentModel.Tests.AsyncOperationFinalizerTests.<>c__DisplayClass2_0.<Finalizer_OperationCompleted_Com
  pletesOperation>b__0()
     --- End of inner exception stack trace ---
     at RemoteExecutorConsoleApp.Program.Main(String[] args)
     System.ComponentModel.Tests.AsyncOperationFinalizerTests.Finalizer_OperationCompleted_CompletesOperation [FAIL]
        Assert.Equal() Failure
        Expected: 42
        Actual:   -532462766
        Stack Trace:
  Exception from RemoteExecutorConsoleApp(System.ComponentModel.EventBasedAsync.Tests, Version=4.1.1.0, Culture=neutral
  , PublicKeyToken=9d77cc7ad39b68eb, System.ComponentModel.Tests.AsyncOperationFinalizerTests+<>c__DisplayClass1_0, <Fi
  nalizer_OperationCompleted_DoesNotCallOperationCompleted>b__0):
  Assembly: System.ComponentModel.EventBasedAsync.Tests, Version=4.1.1.0, Culture=neutral, PublicKeyToken=9d77cc7ad39b6
  8eb
  Type: System.ComponentModel.Tests.AsyncOperationFinalizerTests+<>c__DisplayClass1_0
  Method: Int32 <Finalizer_OperationCompleted_DoesNotCallOperationCompleted>b__0()
              at System.Diagnostics.RemoteExecutorTestBase.RemoteInvokeHandle.Dispose()
              at System.ComponentModel.Tests.AsyncOperationFinalizerTests.Finalizer_OperationCompleted_CompletesOperati
  on()
  Exception: 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 System.ComponentModel.Tests.AsyncOperationFinalizerTests.<>c__DisplayClass1_0.<Finalizer_OperationCompleted_Doe
  sNotCallOperationCompleted>b__0()
     --- End of inner exception stack trace ---
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
     at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
     at RemoteExecutorConsoleApp.Program.Main(String[] args)

  Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invoc
  ation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
     at System.ComponentModel.Tests.AsyncOperationFinalizerTests.<>c__DisplayClass1_0.<Finalizer_OperationCompleted_Doe
  sNotCallOperationCompleted>b__0()
     --- End of inner exception stack trace ---
     at RemoteExecutorConsoleApp.Program.Main(String[] args)
     System.ComponentModel.Tests.AsyncOperationFinalizerTests.Finalizer_OperationCompleted_DoesNotCallOperationComplete
  d [FAIL]
        Assert.Equal() Failure
        Expected: 42
        Actual:   -532462766
        Stack Trace:
  Finished:    System.ComponentModel.EventBasedAsync.Tests

If anyone knows what I've done wrong, I'd appreciate some assistance

@stephentoub
Copy link
Member

I get the following errors when I use RemoteInvoke, which don't occur without RemoteInvoke

The lambda you give to RemoteInvoke must not close over anything. We only marshal the name of the lambda method plus any arguments explicitly passed as arguments to RemoteInvoke; when the display class is instantiated in the remote process, the lifted fields accessed by the display class would be null.

@hughbe
Copy link
Author

hughbe commented Jun 12, 2017

That'd be it, thanks!

{
MethodInfo finalizer = typeof(AsyncOperation).GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(finalizer);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be better to actually test the functionality of the finalizer rather than testing for its presence via reflection and invoking it explicitly as is done below. You could do this by creating your own sync ctx that the finalizer will call back to.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong, the tests do exactly that. They use the following sync context that the finalizer does indeed call back to when we manually invoke it. This test you commented on is just a sanity checker.

public class OperationCompletedTracker : SynchronizationContext
{
    public int OperationCompletedCounter { get; set; }

    public override void OperationCompleted() => OperationCompletedCounter++;
}

In terms of guaranteeing that the finalizer is invoked without reflection, I don't know what the best way to do that is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They use the following sync context that the finalizer does indeed call back to when we manually invoke it.

But we shouldn't manually invoke it via reflection. You instead need to ensure that the object is collectable (e.g. ctor it in a helper method to ensure the JIT doesn't artificially extend its lifetime), and then force collection with GC.Collect and wait for finalizers to run with GC.WaitForPendingFinalizers.

Assert.Null(e.Result);
Assert.False(backgroundWorker.IsBusy);
};
backgroundWorker.RunWorkerAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't going to play particularly nicely with xunit. Any failures are going to happen asynchronously, maybe after the test has already completed, and in fact the process may shut down before it gets a chance to run.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I've updated the test to handle this fact, and also to make sure that the completed handler was called

Copy link
Member

@safern safern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than Stephen's comments LGTM.

@safern
Copy link
Member

safern commented Jun 14, 2017

The tests you're adding use RemoteExecutor and that will break this tests for UWP since RemoteExecutor is broken. There is a PR open to fix that, so I would like this PR to be merged after the other one since we are trying to get our test failures in UWP to 0 so that we can enable a CI leg.

#21014 this is the PR that we should wait for.

@safern safern added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Jun 14, 2017
@hughbe
Copy link
Author

hughbe commented Jun 14, 2017

Sure thing @safern

@hughbe
Copy link
Author

hughbe commented Jun 16, 2017

Test Innerloop OSX10.12 Release x64 Build and Test

1 similar comment
@hughbe
Copy link
Author

hughbe commented Jun 17, 2017

Test Innerloop OSX10.12 Release x64 Build and Test

@hughbe
Copy link
Author

hughbe commented Jun 17, 2017

I've removed the reflection - I think the blocker for this PR for RemoteExecutorTestBase is no more, right?

@safern
Copy link
Member

safern commented Jun 17, 2017

I've removed the reflection - I think the blocker for this PR for RemoteExecutorTestBase is no more, right?

I'll pull your changes and confirm locally that the tests don't cause any regression for uap, so that we don't go backwards in the progress we've made.

@hughbe
Copy link
Author

hughbe commented Jun 19, 2017

@safern I know it was the weekend, but let me know how it goes :)

@safern
Copy link
Member

safern commented Jun 19, 2017

@safern I know it was the weekend, but let me know how it goes :)

Taking a look now. I'll let you know :)

@safern
Copy link
Member

safern commented Jun 19, 2017

They pass in Uap so I will merge :) Thanks @hughbe

@safern safern merged commit e4a633a into dotnet:master Jun 19, 2017
@safern safern removed the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Jun 19, 2017
@hughbe hughbe deleted the eventbasedasync-fixes branch June 19, 2017 23:52
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Add System.ComponentModel.EventBasedAsync tests


Commit migrated from dotnet/corefx@e4a633a
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants