@@ -103,6 +103,135 @@ jobs:
103103 run : |
104104 mlcr run,docker,container --adr.compiler.tags=gcc --docker_mlc_repo=mlcommons@mlperf-automations --docker_mlc_repo_branch=dev --image_name=mlc-script-app-image-classification-onnx-py --env.MLC_DOCKER_RUN_SCRIPT_TAGS=app,image-classification,onnx,python --env.MLC_DOCKER_IMAGE_BASE=ubuntu:22.04 --env.MLC_DOCKER_IMAGE_REPO=local --quiet
105105
106+ - name : Test docker process_mounts input_mapping fallback (src_path fix)
107+ shell : bash
108+ run : |
109+ python3 << 'PYTEST'
110+ import subprocess, re, sys, os
111+
112+ # Find the automation/script directory via mlc
113+ out = subprocess.run(['mlc', 'find', 'script', '--tags=detect,os', '--quiet'],
114+ capture_output=True, text=True)
115+ match = re.search(r'Item path:\s*(.+)', out.stdout + out.stderr)
116+ if not match:
117+ print("ERROR: Could not locate MLC repo via 'mlc find script'")
118+ sys.exit(1)
119+ repo_root = os.path.dirname(os.path.dirname(match.group(1).strip()))
120+ sys.path.insert(0, os.path.join(repo_root, 'automation'))
121+
122+ from script.docker_utils import process_mounts
123+
124+ # Test 1: input_mapping in run_state is used as fallback for docker path remapping
125+ docker_settings = {'user': 'mlcuser'}
126+ mounts = ['${{ MLC_SRC_REPO_PATH }}:${{ MLC_SRC_REPO_PATH }}']
127+ env = {'MLC_SRC_REPO_PATH': '/home/user/repos/my-project'}
128+ run_state = {
129+ 'input_mapping': {'src_path': 'MLC_SRC_REPO_PATH'},
130+ 'file_path_env_keys': [],
131+ 'folder_path_env_keys': []
132+ }
133+ f_run_cmd = {'src_path': '/home/user/repos/my-project'}
134+
135+ result = process_mounts(mounts, env, docker_settings, f_run_cmd, run_state)
136+ assert result['return'] == 0, f"process_mounts failed: {result}"
137+ assert f_run_cmd['src_path'] != '/home/user/repos/my-project', \
138+ f"FAIL: src_path was not remapped to container path! Got: {f_run_cmd['src_path']}"
139+ assert '/mlc-mount/' in f_run_cmd['src_path'], \
140+ f"FAIL: Expected /mlc-mount/ in remapped path, got: {f_run_cmd['src_path']}"
141+ print(f"PASS: src_path correctly remapped to {f_run_cmd['src_path']}")
142+
143+ # Test 2: without input_mapping, f_run_cmd should not be modified
144+ f_run_cmd2 = {'src_path': '/home/user/repos/my-project'}
145+ run_state2 = {
146+ 'input_mapping': {},
147+ 'file_path_env_keys': [],
148+ 'folder_path_env_keys': []
149+ }
150+ mounts2 = ['${{ MLC_SRC_REPO_PATH }}:${{ MLC_SRC_REPO_PATH }}']
151+ result2 = process_mounts(mounts2, env, docker_settings, f_run_cmd2, run_state2)
152+ assert result2['return'] == 0
153+ assert f_run_cmd2['src_path'] == '/home/user/repos/my-project', \
154+ f"FAIL: Without input_mapping, src_path should be unchanged, got: {f_run_cmd2['src_path']}"
155+ print("PASS: Without input_mapping, src_path stays as host path")
156+
157+ print("\nAll process_mounts tests passed!")
158+ PYTEST
159+ - name : Test nested Docker opt-in mount handling
160+ shell : bash
161+ run : |
162+ python - <<'PY'
163+ import importlib.util
164+ import sys
165+ from types import SimpleNamespace
166+ from unittest.mock import patch
167+
168+ sys.path.insert(0, 'automation')
169+
170+ spec = importlib.util.spec_from_file_location(
171+ 'run_docker_customize',
172+ 'script/run-docker-container/customize.py'
173+ )
174+ mod = importlib.util.module_from_spec(spec)
175+ spec.loader.exec_module(mod)
176+
177+ logger_messages = []
178+ logger = SimpleNamespace(
179+ info=lambda *args, **kwargs: logger_messages.append(('info', args)),
180+ error=lambda *args, **kwargs: logger_messages.append(('error', args))
181+ )
182+ DOCKER_ENV_MARKER = '/.dockerenv'
183+ DOCKER_SOCKET = '/var/run/docker.sock'
184+ DOCKER_BIN = '/usr/bin/docker'
185+
186+ def run_case(enable_nested, docker_exit_code=0):
187+ captured = {'cmd': ''}
188+
189+ def fake_system(cmd):
190+ captured['cmd'] = cmd
191+ return docker_exit_code
192+
193+ def fake_exists(path):
194+ if path in [DOCKER_ENV_MARKER, DOCKER_SOCKET, DOCKER_BIN]:
195+ return True
196+ return False
197+
198+ env = {
199+ 'MLC_CONTAINER_TOOL': 'docker',
200+ 'MLC_DOCKER_RUN_SCRIPT_TAGS': 'run,docker,container',
201+ 'MLC_DOCKER_RUN_CMD': 'echo nested-docker-ci-check',
202+ 'MLC_DOCKER_ENABLE_NESTED': 'yes' if enable_nested else 'no'
203+ }
204+ i = {
205+ 'os_info': {'platform': 'linux'},
206+ 'env': env,
207+ 'automation': SimpleNamespace(logger=logger)
208+ }
209+
210+ with patch.object(mod.os.path, 'exists', side_effect=fake_exists), \
211+ patch.object(mod.os, 'system', side_effect=fake_system), \
212+ patch.object(mod.shutil, 'which', return_value=DOCKER_BIN):
213+ result = mod.postprocess(i)
214+
215+ return result, captured['cmd']
216+
217+ enabled_result, enabled_cmd = run_case(True, docker_exit_code=0)
218+ disabled_result, disabled_cmd = run_case(False, docker_exit_code=0)
219+ failed_result, _ = run_case(True, docker_exit_code=1)
220+
221+ assert enabled_result['return'] == 0, enabled_result
222+ assert disabled_result['return'] == 0, disabled_result
223+ error_msg = failed_result.get('error', '').lower()
224+ assert failed_result['return'] == 1, failed_result
225+ assert 'docker' in error_msg, failed_result
226+ assert 'failed' in error_msg, failed_result
227+
228+ assert f'{DOCKER_SOCKET}:{DOCKER_SOCKET}' in enabled_cmd, enabled_cmd
229+ assert f'{DOCKER_BIN}:{DOCKER_BIN}' in enabled_cmd, enabled_cmd
230+ assert f'{DOCKER_SOCKET}:{DOCKER_SOCKET}' not in disabled_cmd, disabled_cmd
231+ assert f'{DOCKER_BIN}:{DOCKER_BIN}' not in disabled_cmd, disabled_cmd
232+ print('Nested Docker opt-in mount handling test passed')
233+ PY
234+
106235 test_experiment :
107236 runs-on : ${{ matrix.os }}
108237 strategy :
0 commit comments