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

Apply test output from timedout tests on non-threadabort platforms #4692

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

Conversation

stevenaw
Copy link
Member

@stevenaw stevenaw commented Apr 15, 2024

Fixes #4598

@manfred-brands You mentioned in the source issue that you may also be looking into this on your own branch.

I've put up this PR as I was able to get this working in a relatively self-contained way for the existing code which may be able to merge either independent of your larger rework or could perhaps be PR'd into it as well. This PR could also be discarded if you've already gotten it working on your end too


separateContext.CurrentResult.ApplyOutput(context.CurrentResult);

if (timedOut && !_debugger.IsAttached)
Copy link
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: I had to move the Task.WaitAny to it's own line in order to apply the test output afterwards. I ended up inverting this check here as part of that as I found it read clearer this way but I'm happy to instead change it back to something like:

if (!timedOut || _debugger.IsAttached)

Copy link
Member

@manfred-brands manfred-brands left a comment

Choose a reason for hiding this comment

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

Not sure if this will work.
The problem is the test continuing to run and writing output to its context when at the same time the teardown is run.


separateContext.CurrentResult.ApplyOutput(context.CurrentResult);
Copy link
Member

Choose a reason for hiding this comment

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

Should this not be the other way around?
You want the separateContext to go to the context not the other way around?

Copy link
Member Author

Choose a reason for hiding this comment

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

From memory (which may be flawed) but I think I saw in the debugger that these were getting written to the original context but that it was getting overridden when we create the testResult from the separateContext (which is what would then get output).

I'll load this up and rerun it soon to confirm

Copy link
Member Author

Choose a reason for hiding this comment

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

I see the method wording here could be confusing too.
Leaving desired functionally aside for a moment, if the intention of this code were to take the output from separateContext and apply it to context perhaps the method name would be clearer if it were ApplyOutputTo?

Copy link
Member

Choose a reason for hiding this comment

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

CopyOutputTo would be clearer. At the moment unless I got it wrong it does a CopyOutputFrom

Copy link
Member Author

Choose a reason for hiding this comment

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

Of course, thanks! That's also more consistent with some BCL methods like Stream.CopyTo()


Assert.That(testMethod.Output, Does.Contain("setup"));
Assert.That(testMethod.Output, Does.Contain("method output before pause"));
Assert.That(testMethod.Output, Does.Not.Contain("method output after pause"));
Copy link
Member

Choose a reason for hiding this comment

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

Under .Net core that data will be written after the test has timed out and is likely not available.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that's the intended behaviour, right? The Does.Not here ensures that any output written after the test times out isn't captured

Copy link
Member

Choose a reason for hiding this comment

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

It is not the intended behaviour, but the current behaviour on net 6.0`

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe it's also the current behavior on other runtimes like netfx. Changing that would be a bigger body of work than I was looking to do in this PR, and one which we may wish to discuss further with the team in a separate issue.

If we were to keep this PR focused on just resuming outputting of what is executed, would you prefer we leave this assertion in place knowing it may change if the behavior does, or should we remove the assertion?


[TearDown]
public void TearDown()
{
Copy link
Member

Choose a reason for hiding this comment

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

The #4598 issue talks about TearDown output being lost. We need a test with that in.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point! I had changed the test from having a TearDown to a SetUp during development and missed re-adding a separate TearDown case. I'll add one.

I think the originating issue sought more to keep output from the test method itself in the presence of a TearDown rather than output from the TearDown itself but that will be a good test for me to add here to. One thing to note here though is that I think this was a NET6-specific bug and that presently TearDown is presently only run for timedout test cases on netfx (#2397). I verified the behaviour described there and it's consistent as far back as 3.12

Copy link
Member Author

Choose a reason for hiding this comment

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

Wait, sorry. @manfred-brands I think this does cover the example in the issue as it talks about test output from the test rather than the TearDown, but I'll still take another look and see if there's any edge cases I could add

@stevenaw
Copy link
Member Author

stevenaw commented May 8, 2024

@manfred-brands I've been able to get back to coding this.

I've pushed the naming change to adjust ApplyContext -> CopyOutputTo to make it a bit clearer what's happening. My memory was indeed correct, the output was getting lost because the currentContext was getting written to while the separateContext owned the TestResult which was getting output.

To verify the 3.x functionality I'm trying to restore here, I've put up a branch with the same tests on the 3.x branch. CI is still verifying but they pass as-is locally for me.

I'm a little unclear on if there's further changes you'd like to see here, can you please take a look and let me know?

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.

DefaultTimeout in .runsettings + TearDown method seems to break test output
2 participants