Skip to content

chore: Remove Editor-freezing and obsolete tests from the Unity test suite - #1310

Merged
hatayama merged 6 commits into
v3-betafrom
feature/improve-tests
Jun 12, 2026
Merged

hatayama merged 6 commits into
v3-betafrom
feature/improve-tests

Conversation

@hatayama

Copy link
Copy Markdown
Owner

Summary

  • The Unity EditMode test suite no longer freezes the Editor partway through a run.
  • Obsolete and meaningless tests that could never catch a regression are gone, so the suite is faster and easier to trust.

User Impact

  • Before: running the full EditMode suite intermittently deadlocked the Editor (the Test Runner progress bar stuck on a test name), forcing a hard kill of Unity. A managed-stack dump pinned the hang to cancellation tests that block the main thread in Task.Wait() while the awaited continuation also needs the main thread.
  • After: the full EditMode suite and the PlayMode suite both run to completion. EditMode finishes with no freeze; PlayMode passes 73/73.
  • The freeze was non-deterministic (the first run of a session could pass), which is why it had not surfaced reliably before.

Changes

All changes are test-only; no product, CLI, or Unity runtime behavior is affected.

  • Remove EditMode tests that drive the real dynamic-code compile-and-execute pipeline end-to-end (forbidden by the Unity Freeze Prevention policy): CommandRunnerTests, ExecuteDynamicCodeToolAutoUsingTests, ExecuteDynamicCodeToolSecurityTests, RestrictedModeDangerousApiTests, plus the integration fixtures in AutoInjectedNamespacesTests and PreUsingResolverTests. The pure unit tests in those files are kept.
  • Remove the cancellation-race tests in CompiledAssemblyBuilderTests (in-flight cancel + same-thread teardown wait) that the stack dump identified as the deadlock, and EditorFrameWaiterTests (fire-and-forget cross-frame work).
  • Remove a MainThreadSwitcherTests case with an unbounded WaitUntil, keeping the equivalent case that has a timeout.
  • Remove dead #if UNITYCLILOOP_HAS_ROSLYN tests (the symbol is never defined anywhere) and revive the pure parameter-validation cases; remove the obsolete TDD-scaffold DynamicCodeExecutorDictionaryErrorTest.
  • Remove placeholder/framework-only/tautological tests: the _Test_For_Test_ fixture, BasicPlayModeTests, a self-declared-obsolete RunTestsToolTests case, and the DynamicCodeSecurityManager.CanExecute tautologies.
  • Make the JsonRpcProcessorCliVersionGateTests server-busy assertions deterministic by seeding the editor play-state snapshot, fixing a pre-existing failure on a clean checkout.

Verification

  • uloop compile: 0 errors, 0 warnings.
  • uloop run-tests (EditMode): completes without freezing; the C/D/E window ran twice at 295/295.
  • uloop run-tests --test-mode PlayMode: 73/73 pass.
  • Two pre-existing failures remain (InputVisualizationCanvasPrefabTests.RuntimeSources_WhenScanned_AreEditorOnly, OnionAssemblyDependencyTests.ProductionEditorStartupHooks_WhenLoaded_AreOwnedOnlyByCompositionRootBootstrap); they also fail on a clean checkout and are outside this PR's scope.

hatayama added 6 commits June 11, 2026 23:21
UNITYCLILOOP_HAS_ROSLYN is not defined anywhere in the repository
(ProjectSettings, csc.rsp, asmdef versionDefines, CI), so the three
test files gated behind #if UNITYCLILOOP_HAS_ROSLYN have never been
compiled or executed.

- Delete RestrictedModeDangerousApiTests: all 37 tests run real
  dynamic-code compile-and-execute flows (compileOnly: false) in
  EditMode, which the Unity Freeze Prevention policy forbids, so the
  file must not be revived. Coverage loss is zero because it never ran.
- Delete DynamicCodeExecutorDictionaryErrorTest: TDD debugging
  scaffolding for a long-fixed bug, with a vacuous Assert.Pass on the
  success path and coverage duplicated by DynamicCodeExecutorTests.
- Revive ExecuteDynamicCodeParameterValidationTests by removing the
  stale #if gate: parameter validation throws before any compilation
  and the success path is compile-only, so the freeze risk is low.
  The CompileOnly:false auto-return test was dropped instead of
  revived because SourceShaperTests already covers return shaping
  as a pure unit test.

Verified with uloop compile (0 errors, 0 warnings) and uloop run-tests:
both revived tests pass; the 4 suite failures also fail on clean HEAD
and are unrelated to this change.
These tests could never catch a real regression:

- Delete Assets/Tests/_Test_For_Test_: its two tests are
  Assert.True(true) placeholders and nothing references the
  test_for_test assembly.
- Delete BasicPlayModeTests: all five tests verify C# language and
  Unity engine basics (arithmetic, string concat, Time.time
  monotonicity) rather than project code. Other PlayMode tests keep
  the suite populated.
- Remove RunTestsToolTests.ParseParameters_ShouldParseCorrectly: its
  own comment declares it obsolete since Schema classes replaced JSON
  parameter parsing, and it only reads back values it just assigned.
- Remove the two DynamicCodeSecurityManager CanExecute tests: the
  implementation returns true for every defined enum value, so the
  assertions are tautologies with zero regression-detection power.

Verified with uloop compile (0 errors, 0 warnings) and a filtered
uloop run-tests pass on the remaining tests in the touched fixtures.
SwitchToMainThread_WhenCalledFromBackgroundThread_ShouldSwitchBackToMainThread
waited on the background task with WaitUntil and no timeout, so a hung
Task.Run body would block the Editor forever. The sibling test
SwitchToMainThread_WhenCalledFromBackgroundThread_ShouldSwitchToMainThread
verifies the same main-thread switch with a 5-second deadline, so no
coverage is lost. Task.Run itself stays because exercising
MainThreadSwitcher requires starting from a background thread.

Verified with uloop compile (0 errors, 0 warnings); the remaining
MainThreadSwitcherTests test and the full PlayMode suite (73 tests) pass.
…flows

These tests drove the real DynamicCodeCompiler / executor / tool-dispatch
pipeline end-to-end inside EditMode, which the Unity Freeze Prevention
policy forbids: the AssemblyBuilder/Roslyn worker fires editor callbacks
that the synchronous test runner can deadlock against.

- Delete CommandRunnerTests: executes a prebuilt dynamic command whose
  generated wrapper calls GetAwaiter().GetResult().
- Delete ExecuteDynamicCodeToolAutoUsingTests and
  ExecuteDynamicCodeToolSecurityTests: full execute-dynamic-code tool
  dispatch into the real compiler.
- Drop the AutoInjectedNamespacesIntegrationTests and
  PreUsingResolverIntegrationTests fixtures (real CompileAsync) while
  keeping the pure PreUsingResolver/WrapperTemplate unit tests.
- Drop the ExecuteDynamicCodeParameterValidationTests cases that ran the
  compiler; keep the pure pre-compilation parameter-validation case.

Verified: the C/D/E EditMode window completes twice (295/295) and the
full EditMode suite no longer freezes.
A SIGQUIT managed-stack dump of a frozen Editor pinned the hang to
CompiledAssemblyBuilderTests.AwaitBuildCompletionAsync_WhenCancellation
IsRequested: the async test cancels an in-flight task, then NUnit blocks
the main thread in Task.Wait() while the task's continuation needs that
same main thread, producing a Monitor.Wait deadlock. The Test Runner
dialog showed the *next* test name, which is why earlier single-test
guesses kept missing the real culprit.

- Delete both cancellation-race tests in CompiledAssemblyBuilderTests
  (in-flight CancellationTokenSource.Cancel + same-thread teardown wait);
  keep the pure CreateUniqueCompilationName test.
- Delete EditorFrameWaiterTests: its [UnityTest] cases launch cross-frame
  WaitFramesAsync work via .Forget() fire-and-forget, which threw
  TaskCanceledException during teardown inside the freeze window. The
  fire-and-forget pattern is forbidden by the Unity Freeze Prevention
  policy.

Verified: with these removed the C/D/E window completes twice (295/295)
and the full EditMode suite finishes without freezing.
ProcessRequest_WhenFirstToolWaitsForMainThread and the dynamic-code
variant asserted that server_busy error data omits isPlaying/isPaused.
That held only in isolation: during a real suite run the editor update
loop populates UnityCliLoopEditorStateSnapshot, so the background-thread
CreateBusyException path includes both fields and the tests failed on a
clean checkout.

Seed the snapshot to a known (false, false) state before each request
and assert those values, then clear it in the finally block, so the
tests verify the documented contract regardless of editor play state.
@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7839ada3-5bb5-4ef0-8ae2-c2177820c7e6

📥 Commits

Reviewing files that changed from the base of the PR and between 875fd91 and 2adda8c.

⛔ Files ignored due to path filters (11)
  • Assets/Tests/Editor/DynamicCodeToolTests/CommandRunnerTests.cs.meta is excluded by none and included by none
  • Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorDictionaryErrorTest.cs.meta is excluded by none and included by none
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolAutoUsingTests.cs.meta is excluded by none and included by none
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolSecurityTests.cs.meta is excluded by none and included by none
  • Assets/Tests/Editor/DynamicCodeToolTests/RestrictedModeDangerousApiTests.cs.meta is excluded by none and included by none
  • Assets/Tests/Editor/EditorFrameWaiterTests.cs.meta is excluded by none and included by none
  • Assets/Tests/PlayMode/BasicPlayModeTests.cs.meta is excluded by none and included by none
  • Assets/Tests/_Test_For_Test_.meta is excluded by none and included by none
  • Assets/Tests/_Test_For_Test_/ConsoleLogRetrieverTests.cs.meta is excluded by none and included by none
  • Assets/Tests/_Test_For_Test_/UnityCLILoop.test_for_test.Editor.asmdef is excluded by none and included by none
  • Assets/Tests/_Test_For_Test_/UnityCLILoop.test_for_test.Editor.asmdef.meta is excluded by none and included by none
📒 Files selected for processing (16)
  • Assets/Tests/Editor/DynamicCodeToolTests/AutoInjectedNamespacesTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/CommandRunnerTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/CompiledAssemblyBuilderTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorDictionaryErrorTest.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeSecurityManagerTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeParameterValidationTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolAutoUsingTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolSecurityTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/PreUsingResolverTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/RestrictedModeDangerousApiTests.cs
  • Assets/Tests/Editor/EditorFrameWaiterTests.cs
  • Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
  • Assets/Tests/Editor/MainThreadSwitcherTests.cs
  • Assets/Tests/Editor/RunTestsToolTests.cs
  • Assets/Tests/PlayMode/BasicPlayModeTests.cs
  • Assets/Tests/_Test_For_Test_/ConsoleLogRetrieverTests.cs
💤 Files with no reviewable changes (14)
  • Assets/Tests/Editor/RunTestsToolTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/CommandRunnerTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolAutoUsingTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/ExecuteDynamicCodeToolSecurityTests.cs
  • Assets/Tests/Test_For_Test/ConsoleLogRetrieverTests.cs
  • Assets/Tests/PlayMode/BasicPlayModeTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorDictionaryErrorTest.cs
  • Assets/Tests/Editor/MainThreadSwitcherTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/RestrictedModeDangerousApiTests.cs
  • Assets/Tests/Editor/EditorFrameWaiterTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/PreUsingResolverTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeSecurityManagerTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/CompiledAssemblyBuilderTests.cs
  • Assets/Tests/Editor/DynamicCodeToolTests/AutoInjectedNamespacesTests.cs

📝 Walkthrough

Walkthrough

This PR removes multiple integration and unit test fixtures from the test suite, simplifies preprocessor guards in parameter validation tests, and hardens editor-state management in version gate tests. The changes consolidate DynamicCodeTool test coverage and improve async test reliability.

Changes

Test Suite Cleanup and Infrastructure Hardening

Layer / File(s) Summary
DynamicCodeTool Integration Test Suite Consolidation
Assets/Tests/Editor/DynamicCodeToolTests/AutoInjectedNamespacesTests.cs, PreUsingResolverTests.cs, ExecuteDynamicCodeParameterValidationTests.cs, CompiledAssemblyBuilderTests.cs, DynamicCodeSecurityManagerTests.cs, RunTestsToolTests.cs
Removes integration test fixtures (AutoInjectedNamespacesIntegrationTests, PreUsingResolverIntegrationTests) covering auto-namespace injection and pre-using resolution. Unwraps ExecuteDynamicCodeParameterValidationTests from #if UNITYCLILOOP_HAS_ROSLYN guard and truncates additional test cases. Removes filename-sanitization assertions and obsolete parameter-parsing tests. Cleans up unused imports across files.
Test Infrastructure State Management and Timing Updates
Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs, MainThreadSwitcherTests.cs
Adds explicit UnityCliLoopEditorStateSnapshot.SetPlayStateForTesting() initialization and ClearForTesting() cleanup to single-flight and dynamic-code version gate tests to prevent state leakage between test runs. Rewrites SwitchToMainThread test to use Time.realtimeSinceStartup-based polling with 5-second timeout instead of immediate completion flags, improving async completion detection reliability.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • hatayama/unity-cli-loop#1306: Adds comprehensive EditorFrameWaiterTests coverage while this PR deletes the same test file, indicating a transition in testing strategy for frame-wait semantics.
  • hatayama/unity-cli-loop#829: Reworks the Roslyn security pipeline and compiler integration, which directly relates to why multiple Roslyn-guarded DynamicCodeTool test fixtures are being removed in this PR.
  • hatayama/unity-cli-loop#1079: Updates ExecuteDynamicCodeToolAutoUsingTests.cs and ExecuteDynamicCodeToolSecurityTests.cs execution wiring, while this PR removes those same test fixtures entirely.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly and concisely summarizes the primary change: removing tests from the test suite to fix Editor freezing and eliminate obsolete tests.
Description check ✅ Passed The pull request description provides detailed context directly related to the changeset, including summary, user impact, specific changes, and verification results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/improve-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 27 files

Re-trigger cubic

@hatayama
hatayama merged commit f650787 into v3-beta Jun 12, 2026
10 of 11 checks passed
@hatayama
hatayama deleted the feature/improve-tests branch June 12, 2026 00:50
RyanXie123 pushed a commit to RyanXie123/unity-cli-loop that referenced this pull request Sep 22, 2026
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.

1 participant