Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ActionDebouncer.cs to support tests with no Sync context #15804

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

pinzart90
Copy link
Contributor

We have a lot of tests that do not setup any SyncronizationContext but still test WPF controls.
This does not work when calling FromCurrentSynchronizationContext (throws exception)

Ex
https://master-5.jenkins.autodesk.com/job/Dynamo/job/DynamoSelfServe/job/pullRequestValidation/17145/testReport/junit/DynamoCoreWpfTests/ConverterTests/SearchHighlightMarginConverterTest/

Purpose

(FILL ME IN) This section describes why this PR is here. Usually it would include a reference to the tracking task that it is part or all of the solution for.

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated
  • This PR contains no files larger than 50 MB

Release Notes

(FILL ME IN) Brief description of the fix / enhancement. Use N/A to indicate that the changes in this pull request do not apply to Release Notes. Mandatory section

Reviewers

(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of

// The TaskScheduler.FromCurrentSynchronizationContext() exists only if there is a valid SyncronizationContex.
// Calling this method from a non UI thread could have a null SyncronizationContex.Current,
// so in that case we use the default TaskScheduler which uses the thread pool.
var taskScheduler = SynchronizationContext.Current != null ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Default;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change makes it a bit harder to predict where the continuation will be executed. The alternative is to identify all tests that call into the ActionDebouncer and make sure they setup a SyncContext before (seemed too tedious to do)

Copy link
Member

Choose a reason for hiding this comment

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

if the sync context is not on the UI thread can we log something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The sync context should always be setup in a UI thread. But I can add it if it makes it more understandable

Copy link

github-actions bot commented Feb 4, 2025

UI Smoke Tests

Test: success. 11 passed, 0 failed.
TestComplete Test Result
Workflow Run: UI Smoke Tests
Check: UI Smoke Tests

@mjkkirschner
Copy link
Member

@pinzart90 is this failure intermittent or repeatable?

@pinzart90
Copy link
Contributor Author

pinzart90 commented Feb 5, 2025

@pinzart90 is this failure intermittent or repeatable?

Locally it is repeatable. It also failed at least once on the build machines.
It could be intermitent. The syncContext is usually set once per thread in our tests. But it depends on how nunit switches the threads when running tests. If nunit runs tests on the thread pool, then new threads could be spun up dynamically, and if the tests being run do not explicitly set the sync context, then it does not.get one.
We only set sync contexts for tests that derive from the UITestBase or systemTestBase

@pinzart90
Copy link
Contributor Author

One single known flaky test is failing RemovesScriptTagsFromLoadedHtml, probably a dispatcher/webview2 thing.
https://master-5.jenkins.autodesk.com/job/Dynamo/job/DynamoSelfServe/job/pullRequestValidation/17149/

}
else
{// This might happen when running tests in non UI threads.
if (Dispatcher.CurrentDispatcher != null)
Copy link
Member

@mjkkirschner mjkkirschner Feb 5, 2025

Choose a reason for hiding this comment

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

shouldn't this check for null
couldn't current dispatcher be any dispatcher - not just the UI dispatcher?

Copy link
Contributor Author

@pinzart90 pinzart90 Feb 5, 2025

Choose a reason for hiding this comment

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

Dispatcher.CurrentDispatcher != null - this means it is in the UI thread.
The check is like this:
IF the current sync context not null - then all is as expected.
If the current sync context is null :

  • then we are probably in a unit test (non UI thread)
  • but if we are in a UI thread, then this case is weird and we should log it
    Does this make sense?

Copy link
Member

Choose a reason for hiding this comment

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

How does Dispatcher.CurrentDispatcher != null ensure it's the UI thread?
I thought that this just accessed the dispatcher of the thread?

taken from SO:

Dispatcher.CurrentDispatcher gets the dispatcher for the current thread. So, if you're looking for the UI thread's Dispatcher from a background process, don't use this.

Application.Current.Dispatcher will always give you the UI thread's dispatcher, as this is the thread that spins up the sole Application instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I wasn't too sure about that. Looks like Application.Current?.Dispatcher != null would be a better check for a UI thread,

Copy link
Member

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants