Mock out idle sleeps in orchestration tests (~9x faster)#5223
Closed
saitcakmak wants to merge 1 commit into
Closed
Mock out idle sleeps in orchestration tests (~9x faster)#5223saitcakmak wants to merge 1 commit into
saitcakmak wants to merge 1 commit into
Conversation
The ax/orchestration test suite spent ~400s of wall time almost entirely sleeping, not computing. Two sources of pure idle time are removed via a shared _mock_orchestrator_poll_sleep() helper called from both test classes' setUp: 1. The orchestrator polling loop (ax.orchestration.orchestrator.sleep). Many tests leave init_seconds_between_polls / min_seconds_before_poll at their non-zero defaults. Loop termination depends on total_seconds_elapsed (which accumulates the configured interval regardless of actual sleeping), so removing the wait is behavior-preserving. 2. The exponential backoff between DB-save retries in retry_on_exception (initial_wait_seconds=5 -> 5s + 10s = 15s for test_suppress_all_storage_errors). Only sleep is mocked, via a wraps-ed copy of the time module, so the retry count and all other time.* functions are untouched and trial-TTL tests that rely on real time.sleep still work. Runtime: 401.6s -> 42.9s (single-threaded), all 164 tests still pass.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5223 +/- ##
==========================================
- Coverage 96.50% 96.49% -0.02%
==========================================
Files 617 617
Lines 69776 70012 +236
==========================================
+ Hits 67339 67557 +218
- Misses 2437 2455 +18 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@saitcakmak has imported this pull request. If you are a Meta employee, you can view this in D107551763. |
|
@saitcakmak merged this pull request in 873933b. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TLDR
Mocks out
sleepin orchestrator tests, reducing the test runtime significantly.Summary
The
ax/orchestrationtest suite was the single slowest test directory in Ax — ~400s of wall time — but it spent almost all of that sleeping, not computing (~20s CPU of 400s wall). This PR removes the idle waits via a shared_mock_orchestrator_poll_sleep()helper called from both test classes'setUp(the subclassTestAxOrchestratorMultiTypeExperimentcallsTestCase.setUpdirectly rather thansuper(), so both need it).Two sources of pure idle time are removed:
Orchestrator polling loop (
ax.orchestration.orchestrator.sleep). Many tests leaveinit_seconds_between_polls/min_seconds_before_pollat their non-zero defaults (1.0s), so the polling loop just waits. Loop termination depends ontotal_seconds_elapsed— which accumulates the configured interval regardless of whethersleepactually pauses — so removing the wait is behavior-preserving.Retry backoff in
retry_on_exception(initial_wait_seconds=5→ 5s + 10s = 15s fortest_suppress_all_storage_errors). Onlysleepis mocked, via awraps-ed copy of thetimemodule (patch("ax.utils.common.executils.time", Mock(wraps=time))), so the retry count and every othertime.*function are untouched — and trial-TTL tests that rely on realtime.sleep(e.g.test_generate_candidates_can_remove_stale_candidates) keep working against the real clock.Result
Single-threaded, all 164 tests still pass:
~89% faster (401.6s → 42.9s). Previously-dominant tests (
test_ignore_global_stopping~20s,test_run_n_trials*~11s,test_suppress_all_storage_errors~15s) all drop to sub-second. The TTL tests intentionally still take ~2.2s, confirming real elapsed-time behavior is preserved.GitHub CI results:
Before: 28m 5s https://github.com/facebook/Ax/actions/runs/26967821950/job/79575013374
After: 20m 46s https://github.com/facebook/Ax/actions/runs/26968208766/job/79576349702?pr=5223
Test Plan
pytest ax/orchestration/→ 164 passedufmt+flake8clean