Repository navigation
ai-summary: ignore errors a test declared expected - #133
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the AI log extraction pipeline to suppress developer-declared expected error lines (via EXPECTED_ERROR log brackets) before downstream crash detection and error section extraction, reducing false “CRASHED” classifications for negative tests.
Changes:
- Added parsing + masking for
[EXPECTED_ERROR BEGIN ... message=...] ... [EXPECTED_ERROR END]blocks so declared expected error lines don’t influence crash detection or extracted error sections. - Refactored crash detection into clearer buckets (hard crash / collection crash / killed / TT_FATAL+TT_THROW / selected Python exceptions).
- Applied expected-error masking early in
extract_log()so it affects all later processing.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """Line ranges of properly closed [EXPECTED_TT_ERROR BEGIN match=...]...[END] | ||
| blocks, paired with the declared match pattern. An unclosed block is ignored, | ||
| so its contents are never masked.""" |
| """Return a copy of `lines` with developer-declared expected errors blanked out. | ||
| For each closed [EXPECTED_TT_ERROR BEGIN match='<pat>']...[END] bracket, the two | ||
| marker lines and any in-between line matching <pat> are replaced with "" — so they | ||
| are seen by neither crash detection nor section extraction. Everything else — a | ||
| different line in the block, or anything outside a bracket — is untouched.""" |
| masked[start] = "" # [EXPECTED_TT_ERROR BEGIN ...] marker | ||
| masked[end] = "" # [EXPECTED_TT_ERROR END] marker |
| # Strip developer-declared expected errors (expect_tt_error brackets) up front, so | ||
| # they're excluded from EVERYTHING downstream — crash detection and the error | ||
| # sections handed to the LLM alike. |
| # TT_THROW/TT_FATAL means tt-metal crashed, which cascades to vLLM timeout and test | ||
| # failures. (full_text already has expect_tt_error-declared errors masked out above.) | ||
| # |
| # Strip developer-declared expected errors (expect_tt_error brackets) up front, so | ||
| # they're excluded from EVERYTHING downstream — crash detection and the error | ||
| # sections handed to the LLM alike. | ||
| lines = _mask_expected_errors(lines) | ||
|
|
127d1b9 to
d0ac90d
Compare
d0ac90d to
54294a7
Compare
There was a problem hiding this comment.
⚠️ Not ready to approve
The current masking implementation can drop newlines (risking cross-line regex matches), and the new behavior around error section extraction isn’t fully asserted by the added tests.
Copilot's findings
- Files reviewed: 4/4 changed files
- Comments generated: 5
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
| for start, block_end, pattern in ranges: | ||
| masked[start] = "" # [EXPECTED_ERROR BEGIN ...] marker | ||
| masked[block_end] = "" # [EXPECTED_ERROR END] marker | ||
| try: | ||
| pat = re.compile(pattern) | ||
| except re.error: | ||
| continue # malformed pattern → mask only the markers, treat content as real | ||
| for i in range(start + 1, block_end): | ||
| if pat.search(masked[i]): | ||
| masked[i] = "" |
| nonempty = [ln for ln in lines if ln.strip()] | ||
| completion_chunks = [(log_source.name, nonempty[:_MARKER_WINDOW], nonempty[-_MARKER_WINDOW:])] | ||
|
|
||
| # Strip developer-declared expected errors (expect_tt_error brackets) up front, so |
| def test_declared_error_is_masked(self, tmp_path): | ||
| log = ( | ||
| '[EXPECTED_ERROR BEGIN] RuntimeError message="must be BFLOAT8_B"\n' | ||
| "TT_FATAL global_tensor must be BFLOAT8_B or BFLOAT16, got Float32\n" | ||
| '[EXPECTED_ERROR END] RuntimeError message="must be BFLOAT8_B"\n' | ||
| ) | ||
| assert not _extract(tmp_path, log).has_crash |
| def test_undeclared_error_in_block_still_crashes(self, tmp_path): | ||
| log = ( | ||
| '[EXPECTED_ERROR BEGIN] RuntimeError message="must be BFLOAT8_B"\n' | ||
| "TT_FATAL unrelated device hang\n" | ||
| '[EXPECTED_ERROR END] RuntimeError message="must be BFLOAT8_B"\n' | ||
| ) | ||
| assert _extract(tmp_path, log).has_crash |
| detection_patterns: dict | None = None, | ||
| expected_error_markers: dict | None = None, | ||
| ) -> ExtractedLog: | ||
| """ | ||
| Extract important parts from a CI log. |
Lines inside an [EXPECTED_ERROR BEGIN <Type> message="..."]...[END] bracket (emitted by the expect_error pytest fixture) that match the declared message are masked before crash detection AND section extraction. A deliberately provoked error (e.g. a negative test's TT_FATAL) no longer triggers a false CRASH, while a different error in the same block — or anything outside a bracket — still does. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A pytest SKIPPED result never ran, so a crash/timeout token quoted in its skip reason (e.g. "Disabled by #44858: ... TT_FATAL ...") was flipping the job to CRASHED. Blank lines matching ignored_line_patterns (analysis.yaml) up front, alongside the expected-error masking. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54294a7 to
d648faa
Compare
Two pre-detection passes (expected-error brackets, non-event lines) and the window+timestamp gate are non-obvious; record the flow and the invariant. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Ready to approve
The change is well-scoped, includes solid test coverage for the new masking behavior, and the remaining feedback is limited to small documentation/performance nits.
Note: this review does not count toward required approvals for merging.
Copilot's findings
- Files reviewed: 6/6 changed files
- Comments generated: 3
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
| def _default_expected_error_markers() -> dict: | ||
| """Bundled expected_error_markers, for direct extract_log() calls without config.""" | ||
| from .config import load_config | ||
|
|
||
| return load_config().get("expected_error_markers", {}) |
| def _default_ignored_line_patterns() -> list[str]: | ||
| """Bundled ignored_line_patterns, for direct extract_log() calls without config.""" | ||
| from .config import load_config | ||
|
|
||
| return load_config().get("ignored_line_patterns", []) |
Copilot review: one leftover expect_tt_error comment (markers are expect_error), and extract_log's Args omitted detection_patterns/expected_error_markers/ ignored_line_patterns. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lines inside an [EXPECTED_ERROR BEGIN message="..."]...[END] bracket (emitted by the expect_error pytest fixture) that match the declared message are masked before crash detection AND section extraction. A deliberately provoked error (e.g. a negative test's TT_FATAL) no longer triggers a false CRASH, while a different error in the same block — or anything outside a bracket — still does.