|
11 | 11 | E2E tests for mz-debug |
12 | 12 | """ |
13 | 13 |
|
| 14 | +import shutil |
14 | 15 | import urllib.request |
15 | 16 | from pathlib import Path |
16 | 17 |
|
@@ -137,12 +138,21 @@ def _assert_cpu_capture_preserves_heap_profile( |
137 | 138 | ) |
138 | 139 |
|
139 | 140 |
|
140 | | -def _newest_dump_dir() -> Path: |
141 | | - """Returns the most recently written `mz_debug_<timestamp>` directory in the |
142 | | - working directory, where `mz-debug` writes its output.""" |
143 | | - dump_dirs = [p for p in Path.cwd().glob("mz_debug_*") if p.is_dir()] |
144 | | - assert dump_dirs, "mz-debug did not create an mz_debug_* output directory" |
145 | | - return max(dump_dirs, key=lambda p: p.stat().st_mtime) |
| 141 | +def _sole_dump_dir(run_dir: Path) -> Path: |
| 142 | + """Returns the single `mz_debug_<timestamp>` directory that an `mz-debug` run |
| 143 | + wrote into `run_dir`. |
| 144 | +
|
| 145 | + `mz-debug` names its output directory with minute precision, so consecutive |
| 146 | + runs share a directory and a later run happily inherits an earlier run's |
| 147 | + artifacts. Asserting on one run's output therefore requires giving it an |
| 148 | + otherwise empty working directory, and finding more than one directory in |
| 149 | + there means the isolation broke. |
| 150 | + """ |
| 151 | + dump_dirs = sorted(p for p in run_dir.glob("mz_debug_*") if p.is_dir()) |
| 152 | + assert ( |
| 153 | + len(dump_dirs) == 1 |
| 154 | + ), f"expected exactly one mz_debug_* output directory in {run_dir}, found {dump_dirs}" |
| 155 | + return dump_dirs[0] |
146 | 156 |
|
147 | 157 |
|
148 | 158 | def _assert_default_dump_files(dump_dir: Path, container_id: str) -> None: |
@@ -197,15 +207,23 @@ def workflow_default(c: Composition, parser: WorkflowArgumentParser) -> None: |
197 | 207 | _assert_cpu_capture_preserves_heap_profile(c, container_id) |
198 | 208 |
|
199 | 209 | # Smoke test: a full `mz-debug` run against the emulator completes without |
200 | | - # error and produces the complete set of default output files. |
| 210 | + # error and produces the complete set of default output files. It runs in an |
| 211 | + # empty directory of its own so that it cannot inherit the artifacts of the |
| 212 | + # explicitly flagged run above, which enabled CPU profiling and would |
| 213 | + # otherwise leave a CPU profile behind in the shared, minute-granular output |
| 214 | + # directory. |
| 215 | + run_dir = Path("default-run").absolute() |
| 216 | + shutil.rmtree(run_dir, ignore_errors=True) |
| 217 | + run_dir.mkdir() |
201 | 218 | spawn.runv( |
202 | 219 | [ |
203 | | - "./mz-debug", |
| 220 | + Path("mz-debug").absolute(), |
204 | 221 | "emulator", |
205 | 222 | "--docker-container-id", |
206 | 223 | container_id, |
207 | 224 | "--mz-connection-url", |
208 | 225 | "postgres://mz_system@127.0.0.1:6877/materialize", |
209 | | - ] |
| 226 | + ], |
| 227 | + cwd=run_dir, |
210 | 228 | ) |
211 | | - _assert_default_dump_files(_newest_dump_dir(), container_id) |
| 229 | + _assert_default_dump_files(_sole_dump_dir(run_dir), container_id) |
0 commit comments