Skip to content

Commit

Permalink
Merge pull request nunit#4692 from stevenaw/4598-timeout-context-outp…
Browse files Browse the repository at this point in the history
…ut-snapshot

Apply test output from timedout tests on non-threadabort platforms
  • Loading branch information
stevenaw committed May 29, 2024
2 parents 2d20f5d + a2acd41 commit 747ee61
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 19 deletions.
31 changes: 13 additions & 18 deletions src/NUnitFramework/framework/Internal/Commands/TimeoutCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,23 @@ public override TestResult Execute(TestExecutionContext context)
{
try
{
var testExecution = RunTestOnSeparateThread(context);
if (Task.WaitAny(new Task[] { testExecution }, _timeout) != -1
|| _debugger.IsAttached)
var separateContext = new TestExecutionContext(context)
{
context.CurrentResult = testExecution.GetAwaiter().GetResult();
}
else
{
string message = $"Test exceeded Timeout value of {_timeout}ms";
CurrentResult = context.CurrentTest.MakeTestResult()
};
var testExecution = Task.Run(() => innerCommand.Execute(separateContext));
var timedOut = Task.WaitAny(new Task[] { testExecution }, _timeout) == -1;

if (timedOut && !_debugger.IsAttached)
{
context.CurrentResult.SetResult(
ResultState.Failure,
message);
$"Test exceeded Timeout value of {_timeout}ms");
}
else
{
context.CurrentResult.CopyOutputTo(separateContext.CurrentResult);
context.CurrentResult = testExecution.GetAwaiter().GetResult();
}
}
catch (Exception exception)
Expand All @@ -116,15 +120,6 @@ public override TestResult Execute(TestExecutionContext context)

return context.CurrentResult;
}

private Task<TestResult> RunTestOnSeparateThread(TestExecutionContext context)
{
var separateContext = new TestExecutionContext(context)
{
CurrentResult = context.CurrentTest.MakeTestResult()
};
return Task.Run(() => innerCommand.Execute(separateContext));
}
#endif
}
}
10 changes: 10 additions & 0 deletions src/NUnitFramework/framework/Internal/Results/TestResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ internal void AddTestAttachment(TestAttachment attachment)
_testAttachments.Add(attachment);
}

/// <summary>
/// Apply the output from the provided TestResult to this one
/// </summary>
/// <param name="result">The TestResult to apply output from</param>
internal void CopyOutputTo(TestResult result)
{
OutWriter.Flush();
result.OutWriter.Write(Output);
}

/// <summary>
/// Gets the collection of files attached to the test
/// </summary>
Expand Down
69 changes: 69 additions & 0 deletions src/NUnitFramework/testdata/TimeoutFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,73 @@ public void TestTimeOutTestCase(int delay)
Thread.Sleep(delay);
}
}

[TestFixture]
public class TimeoutWithSetupAndOutputAfterTimeoutFixture
{
[SetUp]
public void Setup()
{
TestContext.WriteLine("setup");
}

[Test, Timeout(600)]
public void Test2()
{
TestContext.WriteLine("method output before pause");
Thread.Sleep(1_000);
TestContext.WriteLine("method output after pause");
Assert.That(1, Is.EqualTo(0));
}

[TearDown]
public void TearDown()
{
}
}

[TestFixture]
public class TimeoutWithSetupAndOutputFixture
{
[SetUp]
public void Setup()
{
TestContext.WriteLine("setup");
}

[Test, Timeout(2_000)]
public void Test2()
{
TestContext.WriteLine("method output");
Assert.That(1, Is.EqualTo(0));
}

[TearDown]
public void TearDown()
{
}
}

[TestFixture]
public class TimeoutWithSetupTestAndTeardownOutputFixture
{
[SetUp]
public void Setup()
{
TestContext.WriteLine("setup");
}

[Test, Timeout(2_000)]
public void Test2()
{
TestContext.WriteLine("method output");
Assert.That(1, Is.EqualTo(0));
}

[TearDown]
public void TearDown()
{
TestContext.WriteLine("teardown");
}
}
}
35 changes: 34 additions & 1 deletion src/NUnitFramework/tests/Attributes/TimeoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Abstractions;
using NUnit.Framework.Tests.TestUtilities;
using System.Linq;
using NUnit.TestData;

namespace NUnit.Framework.Tests.Attributes
Expand Down Expand Up @@ -157,6 +157,7 @@ public void TestTimesOutAndTearDownIsRun()
TestMethod? testMethod = (TestMethod?)TestFinder.Find(nameof(TimeoutFixture.VeryLongTestWith50msTimeout), suite, false);
Assert.That(testMethod, Is.Not.Null);
ITestResult result = TestBuilder.RunTest(testMethod, fixture);

Assert.That(result.ResultState.Status, Is.EqualTo(TestStatus.Failed));
Assert.That(result.ResultState.Site, Is.EqualTo(FailureSite.Test));
Assert.That(result.Message, Does.Contain("50ms"));
Expand All @@ -174,6 +175,38 @@ public void TestTimesOutAndTearDownIsRun()
#endif
}

[Test]
public void OutputIsCapturedOnTimedoutTest()
{
var suiteResult = TestBuilder.RunTestFixture(typeof(TimeoutWithSetupAndOutputFixture));
var testMethod = suiteResult.Children.First();

Assert.That(testMethod.Output, Does.Contain("setup"));
Assert.That(testMethod.Output, Does.Contain("method output"));
}

[Test]
public void OutputIsCapturedOnNonTimedoutTest()
{
var suiteResult = TestBuilder.RunTestFixture(typeof(TimeoutWithSetupTestAndTeardownOutputFixture));
var testMethod = suiteResult.Children.First();

Assert.That(testMethod.Output, Does.Contain("setup"));
Assert.That(testMethod.Output, Does.Contain("method output"));
Assert.That(testMethod.Output, Does.Contain("teardown"));
}

[Test]
public void OutputIsCapturedOnTimedoutTestAfterTimeout()
{
var suiteResult = TestBuilder.RunTestFixture(typeof(TimeoutWithSetupAndOutputAfterTimeoutFixture));
var testMethod = suiteResult.Children.First();

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"));
}

[Test]
public void SetUpTimesOutAndTearDownIsRun()
{
Expand Down

0 comments on commit 747ee61

Please sign in to comment.