Reset per-run state between variations of mlc test script - #317
anandhu-eng wants to merge 1 commit into
Conversation
`ScriptAutomation.run` falls back to the instance attributes (`env`,
`state`, `const`, `const_state`, `add_deps_recursive`, `run_state`,
`recursion_spaces`, ...) whenever the caller does not pass the matching
key. The `test` action loops over `tests.run_inputs[*].variations_list`
calling `self.run()` on one automation instance, so each variation
inherited whatever the previous one left behind.
For a script whose download-tool variations contribute
`add_deps_recursive`, the first variation's entry survived into the
second, and both tags were then applied to the same dep:
mlcr download-and-extract,_r2-downloader,_rclone,_url.<...>
Error : Multiple variation tags selected for the variation group
"download-tool": {'r2-downloader', 'rclone'}
Snapshot the per-run state once in `test` and restore it before each
`self.run()`, so every variation starts from the state the automation
object was constructed with.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅ |
🤖 AI PR Review SummaryThis PR introduces explicit snapshot and restore methods for the per-run state in ScriptAutomation to prevent state leakage between test variations. It addresses a subtle bug where instance attributes used as fallback in |
| 'run_inputs', [{"docker_os": "ubuntu", "docker_os_version": "22.04"}])) | ||
|
|
||
| # Every test variation is an independent top level run, so | ||
| # each one has to start from the state this automation object |
There was a problem hiding this comment.
Consider adding a comment or docstring to PER_RUN_STATE_KEYS explaining why these specific keys are included and if this list needs to be updated when new per-run state attributes are added.
| @@ -2932,6 +2974,7 @@ def test(self, i): | |||
| ii['docker_image_name'] = alias | |||
|
|
|||
There was a problem hiding this comment.
Restoring the run state before each variation is critical; consider adding a comment here explaining that this prevents state bleed between variations for future maintainers.
Problem
Every
process_modified_filesjob in mlperf-automations#1086 whose script has both anr2-downloaderand anrclonevariation fails (example run):The invoked tags are correct —
_rcloneonly. The_r2-downloadercomes from the previous variation in the same test.Root cause
ScriptAutomation.run()falls back to the instance attributes whenever the caller doesn't pass the matching key:https://github.com/mlcommons/mlcflow/blob/d6c103c/automation/script/module.py#L360-L369
Each CLI invocation gets a fresh
ScriptAutomationfromcall_script_module_function, so a normalmlcrrun is unaffected. But thetestaction loops overtests.run_inputs[*].variations_listcallingself.run(ii)on one instance, andiicarries noadr. So:_r2-downloaderrun merges{dae: {tags: '_r2-downloader'}}intoself.add_deps_recursive._rclonerun inherits it and merges_rcloneon top.daedep resolves as_r2-downloader,_rclone→ two tags in thedownload-toolgroup.self.recursion_spaces,self.envandself.run_stateleak the same way — visible in the CI log as the second variation's output being indented one level deeper than the first.This isn't specific to the two rclone-removal PRs; it hits any script whose
variations_listhas two entries from the sameadd_deps_recursive-carrying variation group. It surfaced now because #1086 touches 37 metas at once.Fix
Snapshot the per-run state once in
test()and restore it before eachself.run(), so every variation starts from the state the automation object was constructed with. Scoped to thetestloop —run()itself is untouched.Test plan
Against
mlcommons/mlperf-automations@60d0eb2(main) with this mlcflow branch:mlc test script 5614c39cb1564d72 --test_input_index=1 --quiet(get-preprocessed-dataset-openorca, the failing job above) → exit 0. Deps now resolve asdownload-and-extract,_r2-downloader,_url.https://inference.mlcommons-storage.org/...anddownload-and-extract,_rclone,_url.mlc-inference:..., each with one download-tool tag.mainwithout the fix reproduces the CI error verbatim, so the reproduction is faithful and the fix is what closes it.tests/test_script_test_state_isolation.pybuilds a throwaway two-script repo in a tempMLC_REPOSand asserts the second variation resolves its dep with_balone. Fails onmain, passes here.python3 -m pytest tests/ -q→ 101 passed.autopep8 -a --diffon both files reports nothing on the added lines (one pre-existing f-string elsewhere inmodule.pyis untouched).🤖 Generated with Claude Code