test: replace blind time.sleep(5) with polling in L0_lifecycle - #8920
test: replace blind time.sleep(5) with polling in L0_lifecycle#8920Moyummmm wants to merge 2 commits into
Conversation
Add wait_for_model_state() helper to qa/common/test_util.py that polls is_model_ready() instead of using fixed-duration sleeps.
Replace 13 instances of time.sleep(5) in lifecycle_test.py with deterministic polling using tu.wait_for_model_state(). Reduces flaky CI failures caused by fixed-duration sleeps under resource contention.
Greptile SummaryReplaces fixed five-second lifecycle-test delays with a shared, bounded model-readiness polling helper.
Confidence Score: 4/5The configuration-reload synchronization needs correction before merging because three updated tests can still proceed against stale model state and fail intermittently. Polling version 3 for readiness cannot prove that a configuration mutation was processed when that version was already ready under the previous configuration. Files Needing Attention: qa/L0_lifecycle/lifecycle_test.py Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Mutate model configuration] --> B{Repository poll has run?}
B -- No --> C[Old version 3 remains ready]
C --> D[wait_for_model_state returns immediately]
D --> E[Assertions observe stale configuration]
E --> F[Intermittent test failure]
B -- Yes --> G[Reload applies new configuration]
G --> H[Assertions observe expected state]
Reviews (1): Last reviewed commit: "test: replace time.sleep(5) with wait_fo..." | Re-trigger Greptile |
| tu.wait_for_model_state( | ||
| httpclient.InferenceServerClient("localhost:8000", verbose=True), | ||
| model_name, | ||
| True, | ||
| str(version), | ||
| ) |
There was a problem hiding this comment.
Already-ready state bypasses reload
When the configuration changes between repository polling cycles, version 3 remains ready under the old configuration, so wait_for_model_state(..., True, "3") returns immediately and the subsequent label and version-policy checks race the reload, causing intermittent test failures. The same issue applies to the waits after the second configuration change and the configuration deletion.
What does the PR do?
Replace 13 instances of
time.sleep(5)inqa/L0_lifecycle/lifecycle_test.pywith a deterministic polling loop using a newtu.wait_for_model_state()helper inqa/common/test_util.py.Root cause
Fixed-duration
time.sleep(5)calls that wait for model load/unload are unreliable under CI resource contention. If the server takes longer than 5 seconds (e.g., under GPU/CPU contention, I/O pressure, or on Jetson/Orin), the subsequentis_model_ready()assertion fails even though the model would eventually reach the correct state.Fix
qa/common/test_util.py: Addedwait_for_model_state(triton_client, model_name, expected_ready, model_version, timeout_sec, interval_sec)helper. It pollsis_model_ready()at 1-second intervals until the expected state is reached or the 30-second timeout expires.qa/L0_lifecycle/lifecycle_test.py: Replacedtime.sleep(5)in the following test functions with calls to the new helper, polling the specific model/version that changed:test_dynamic_model_load_unload(4 replacements)test_dynamic_version_load_unload(2 replacements)test_dynamic_model_modify(2 replacements)test_multiple_model_repository_polling(2 replacements)test_apply_custom_config/test_delete_custom_config(2 replacements)Intentionally kept
time.sleep(5)in:Checklist
<type>: <description>Commit Type:
Related Issues:
Closes #8919
Where should the reviewer start?
qa/common/test_util.py— newwait_for_model_state()helperqa/L0_lifecycle/lifecycle_test.py— replacementsTest plan:
python3 -m py_compile qa/common/test_util.py qa/L0_lifecycle/lifecycle_test.py(syntax check passes)qa/L0_lifecycle/test.shwith standard Triton CI configurationCaveats:
httpclient.InferenceServerClientfor each polling call. This is consistent with the existing pattern in the test file where clients are created inline.time.sleep(5)calls (negative tests) and 1 scheduler timeout sleep are intentionally unchanged.