Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/unity-compile-check-and-test-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ jobs:
dotnet test tests/DynamicCodeExecutionScheduler.UnitTests/DynamicCodeExecutionScheduler.UnitTests.csproj --configuration Release
dotnet test tests/SharedRoslynCompilerWorker.UnitTests/SharedRoslynCompilerWorker.UnitTests.csproj --configuration Release
dotnet test tests/OutputFileRetention.UnitTests/OutputFileRetention.UnitTests.csproj --configuration Release
dotnet test tests/RunTestsExecutionTimeout.UnitTests/RunTestsExecutionTimeout.UnitTests.csproj --configuration Release

- name: Cache Library folder
if: env.HAS_UNITY_LICENSE == 'true'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/unity-editmode-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
dotnet test tests/DynamicCodeExecutionScheduler.UnitTests/DynamicCodeExecutionScheduler.UnitTests.csproj --configuration Release
dotnet test tests/SharedRoslynCompilerWorker.UnitTests/SharedRoslynCompilerWorker.UnitTests.csproj --configuration Release
dotnet test tests/OutputFileRetention.UnitTests/OutputFileRetention.UnitTests.csproj --configuration Release
dotnet test tests/RunTestsExecutionTimeout.UnitTests/RunTestsExecutionTimeout.UnitTests.csproj --configuration Release

editmode-tests:
name: EditMode Tests (${{ matrix.unity-version }})
Expand Down
65 changes: 64 additions & 1 deletion Assets/Tests/Editor/RunTestsCancelStopRestoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,66 @@ public async Task StopAndRestoreAsync_WhenAHookThrowsOutsideItsGuard_SwallowsThe
Assert.That(result.DegradationNote, Does.StartWith("Stop/restore failed unexpectedly"));
}

/// <summary>
/// Verifies a throwing cancel hook during a PlayMode run still falls back to requesting and confirming the exit.
/// </summary>
[Test]
public async Task StopAndRestoreAsync_PlayModeWhenTheCancelHookThrows_FallsBackToTheExit()
{
_hooks.CancelException = new InvalidOperationException("cancel failed");
_hooks.PlayingAnswers.Enqueue(true);
_hooks.PlayingAnswers.Enqueue(true);
_hooks.PlayingAnswers.Enqueue(false);

RunTestsCancelStopRestoreResult result = await StopAndRestore(isPlayMode: true, RunGuid);

Assert.That(_hooks.CancelGuids, Is.EqualTo(new List<string> { RunGuid }));
Assert.That(result.TestRunCancelAttempted, Is.True);
Assert.That(result.TestRunCancelSucceeded, Is.False);
Assert.That(_hooks.ExitRequestCount, Is.EqualTo(1));
Assert.That(result.PlayModeExitConfirmed, Is.True);
Assert.That(_hooks.Warnings.Count, Is.EqualTo(1));
Assert.That(_hooks.Warnings[0], Does.StartWith("TryCancelTestRun failed and was ignored"));
}

/// <summary>
/// Verifies an EditMode run without a cancel hook skips the cancel even with a run GUID, warns about the
/// EditMode job, and does not fall into the catch-all.
/// </summary>
[Test]
public async Task StopAndRestoreAsync_EditModeWithoutACancelHook_SkipsTheCancelAndWarnsAboutTheEditModeJob()
{
_hooks.CancelHookAvailable = false;

RunTestsCancelStopRestoreResult result = await StopAndRestore(isPlayMode: false, RunGuid);

Assert.That(_hooks.CancelGuids, Is.Empty);
Assert.That(result.TestRunCancelAttempted, Is.False);
Assert.That(_hooks.ExitRequestCount, Is.EqualTo(0));
Assert.That(
result.DegradationNote,
Does.StartWith("Unity Test Framework 1.3.9 has no public API to cancel an in-flight test job; " +
"an EditMode job may still be running until it finishes. "));
Assert.That(_hooks.Warnings, Is.Empty);
}

/// <summary>
/// Verifies the internal stop-wait delays receive an uncancelable token instead of the caller's canceled one.
/// </summary>
[Test]
public async Task StopAndRestoreAsync_InternalWaits_UseAnUncancelableToken()
{
_hooks.PlayingAnswers.Enqueue(true);
_hooks.PlayingAnswers.Enqueue(true);
_hooks.PlayingAnswers.Enqueue(true);
_hooks.PlayingAnswers.Enqueue(false);

await StopAndRestore(isPlayMode: true, string.Empty);

Assert.That(_hooks.DelayTokens.Count, Is.GreaterThan(0));
Assert.That(_hooks.DelayTokens, Is.All.EqualTo(CancellationToken.None));
}

/// <summary>
/// Verifies a result built without a note never exposes null to the timeout message.
/// </summary>
Expand Down Expand Up @@ -235,6 +295,7 @@ private Task<RunTestsCancelStopRestoreResult> StopAndRestore(bool isPlayMode, st
private sealed class ScriptedHooks
{
internal bool CancelResult { get; set; }
internal bool CancelHookAvailable { get; set; } = true;
internal Exception CancelException { get; set; }
internal Exception ExitException { get; set; }
internal Exception PlayingException { get; set; }
Expand All @@ -244,14 +305,15 @@ private sealed class ScriptedHooks
internal bool RunActiveDefault { get; set; }
internal List<string> CancelGuids { get; } = new List<string>();
internal List<int> Delays { get; } = new List<int>();
internal List<CancellationToken> DelayTokens { get; } = new List<CancellationToken>();
internal List<string> Warnings { get; } = new List<string>();
internal int ExitRequestCount { get; private set; }

internal RunTestsCancelStopRestoreHooks ToHooks()
{
return new RunTestsCancelStopRestoreHooks
{
TryCancelTestRun = TryCancelTestRun,
TryCancelTestRun = CancelHookAvailable ? TryCancelTestRun : null,
IsRunActive = () => RunActiveAnswers.Count > 0 ? RunActiveAnswers.Dequeue() : RunActiveDefault,
IsPlaying = IsPlaying,
RequestExitPlayMode = RequestExitPlayMode,
Expand Down Expand Up @@ -294,6 +356,7 @@ private Task DelayAsync(int milliseconds, CancellationToken ct)
{
// Completes immediately so the bounded polling loop runs synchronously without wall-clock waits.
Delays.Add(milliseconds);
DelayTokens.Add(ct);
return Task.CompletedTask;
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

<ItemGroup>
<Compile Include="../../Packages/src/Editor/FirstPartyTools/RunTests/RunTestsExecutionTimeout.cs" Link="Production/RunTestsExecutionTimeout.cs" />
<Compile Include="../../Packages/src/Editor/FirstPartyTools/RunTests/RunTestsCancelStopRestore.cs" Link="Production/RunTestsCancelStopRestore.cs" />
<Compile Include="../../Packages/src/Editor/FirstPartyTools/RunTests/TestRunnerApiCancelMethodLookup.cs" Link="Production/TestRunnerApiCancelMethodLookup.cs" />
</ItemGroup>
</Project>
Loading