Get fuzzy match candidates for a test name using meson introspect. This queries the Meson build system for all registered tests containing the test name substring, enabling fuzzy matching even when the build directory is freshly created and no executables exist yet. Uses ``mes
(build_dir: Path, test_name: str)
| 69 | |
| 70 | |
| 71 | def get_fuzzy_test_candidates(build_dir: Path, test_name: str) -> list[str]: |
| 72 | """ |
| 73 | Get fuzzy match candidates for a test name using meson introspect. |
| 74 | |
| 75 | This queries the Meson build system for all registered tests containing the |
| 76 | test name substring, enabling fuzzy matching even when the build directory |
| 77 | is freshly created and no executables exist yet. |
| 78 | |
| 79 | Uses ``meson introspect --tests`` which returns registered test names directly, |
| 80 | avoiding issues with target type filtering (tests are shared libraries, not |
| 81 | executables, in the DLL-based test architecture). |
| 82 | |
| 83 | Performance: the full ``meson introspect --tests`` subprocess (~700 ms) is |
| 84 | expensive. Results are cached in ``<build_dir>/.meson_introspect_tests_cache.json`` |
| 85 | and reused on subsequent runs as long as ``build.ninja`` has not changed. |
| 86 | This saves ~700 ms per specific-test invocation (e.g., ``bash test alloca``). |
| 87 | |
| 88 | Args: |
| 89 | build_dir: Meson build directory |
| 90 | test_name: Test name to search for (e.g., "async", "s16x16") |
| 91 | |
| 92 | Returns: |
| 93 | List of matching test names (e.g., ["fl_async", "fl_fixed_point_s16x16"]) |
| 94 | """ |
| 95 | if not build_dir.exists(): |
| 96 | return [] |
| 97 | |
| 98 | # Fast-path: use cached test names when build.ninja hasn't changed. |
| 99 | # Measured cost of meson introspect --tests: ~700 ms on Windows. |
| 100 | # Cache invalidation: build.ninja mtime updates on every meson reconfigure, |
| 101 | # which is the only event that changes the registered test list. |
| 102 | # Cache stores only test name strings (~6 KB) for fast JSON parsing (~5 ms). |
| 103 | test_names: list[str] | None = _load_introspect_tests_cache(build_dir) |
| 104 | |
| 105 | if test_names is None: |
| 106 | # Cache miss: run meson introspect subprocess |
| 107 | try: |
| 108 | # Query Meson for all registered tests (not targets) |
| 109 | # --tests returns test registrations which have the correct names |
| 110 | # regardless of whether the underlying target is exe, shared_library, etc. |
| 111 | result = subprocess.run( |
| 112 | [get_meson_executable(), "introspect", str(build_dir), "--tests"], |
| 113 | capture_output=True, |
| 114 | text=True, |
| 115 | encoding="utf-8", |
| 116 | errors="replace", |
| 117 | timeout=10, |
| 118 | check=False, |
| 119 | ) |
| 120 | |
| 121 | # SELF-HEALING: Detect missing/corrupted intro files |
| 122 | # When intro-targets.json, intro-tests.json or other introspection files are missing, |
| 123 | # meson introspect fails with "is missing! Directory is not configured yet?" |
| 124 | # This indicates the build directory is in a corrupted state. |
| 125 | if result.returncode != 0: |
| 126 | stderr_output = result.stderr.lower() |
| 127 | stdout_output = result.stdout.lower() |
| 128 |
no test coverage detected