Skip to content

Reset per-run state between variations of mlc test script - #317

Closed
anandhu-eng wants to merge 1 commit into
mainfrom
fix-test-action-state-leak
Closed

anandhu-eng wants to merge 1 commit into
mainfrom
fix-test-action-state-leak

Conversation

@anandhu-eng

Copy link
Copy Markdown
Contributor

Problem

Every process_modified_files job in mlperf-automations#1086 whose script has both an r2-downloader and an rclone variation fails (example run):

* mlcr get,dataset,openorca,language-processing,preprocessed,_rclone,_mlc,_dry-run
  * mlcr download-and-extract,_r2-downloader,_rclone,_url.mlc-inference:mlcommons-inference-wg-public/open_orca
Error : Multiple variation tags selected for the variation group "download-tool": {'r2-downloader', 'rclone'}

The invoked tags are correct — _rclone only. The _r2-downloader comes 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

self.env = i.get('env', self.env)
self.state = i.get('state', self.state)
self.const = i.get('const', self.const)
self.const_state = i.get('const_state', self.const_state)
self.add_deps_recursive = i.get('adr', self.add_deps_recursive)

Each CLI invocation gets a fresh ScriptAutomation from call_script_module_function, so a normal mlcr run is unaffected. But the test action loops over tests.run_inputs[*].variations_list calling self.run(ii) on one instance, and ii carries no adr. So:

  1. _r2-downloader run merges {dae: {tags: '_r2-downloader'}} into self.add_deps_recursive.
  2. _rclone run inherits it and merges _rclone on top.
  3. The dae dep resolves as _r2-downloader,_rclone → two tags in the download-tool group.

self.recursion_spaces, self.env and self.run_state leak 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_list has two entries from the same add_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 each self.run(), so every variation starts from the state the automation object was constructed with. Scoped to the test loop — 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 as download-and-extract,_r2-downloader,_url.https://inference.mlcommons-storage.org/... and download-and-extract,_rclone,_url.mlc-inference:..., each with one download-tool tag.
  • Same command on main without the fix reproduces the CI error verbatim, so the reproduction is faithful and the fix is what closes it.
  • New regression test tests/test_script_test_state_isolation.py builds a throwaway two-script repo in a temp MLC_REPOS and asserts the second variation resolves its dep with _b alone. Fails on main, passes here.
  • Full suite: python3 -m pytest tests/ -q → 101 passed.
  • autopep8 -a --diff on both files reports nothing on the added lines (one pre-existing f-string elsewhere in module.py is untouched).

🤖 Generated with Claude Code

`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>
@anandhu-eng
anandhu-eng requested a review from a team as a code owner September 4, 2026 18:47
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

🤖 AI PR Review Summary

This 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 calls caused state bleed across runs, leading to incorrect dependency selections. The design is sound and the added test verifies isolation. The main risk is ensuring all relevant state keys are included in PER_RUN_STATE_KEYS and that deep copies are sufficient to isolate mutable state. No major design issues detected.

'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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

@anandhu-eng anandhu-eng closed this Sep 4, 2026
@anandhu-eng
anandhu-eng deleted the fix-test-action-state-leak branch September 4, 2026 18:59
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant