Skip to content

[None][fix] Suppress agent-path junit for monitor-detected SLURM infra retries - #17130

Merged
dpitman-nvda merged 3 commits into
NVIDIA:mainfrom
dpitman-nvda:fix/slurm-agent-retry-junit-suppression
Aug 5, 2026
Merged

[None][fix] Suppress agent-path junit for monitor-detected SLURM infra retries#17130
dpitman-nvda merged 3 commits into
NVIDIA:mainfrom
dpitman-nvda:fix/slurm-agent-retry-junit-suppression

Conversation

@dpitman-nvda

@dpitman-nvda dpitman-nvda commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Dev Engineer Review

  • Moves SLURM failure classification into the task runner before result caching and JUnit reporting.
  • Suppresses JUnit results for monitor-detected infrastructure failures that succeed on retry.
  • Classifies timeout states as non-retryable UserFailure.
  • Classifies non-terminal SLURM jobs as retryable transient InfraFailure.
  • Preserves normal classification for other failures.
  • Keeps outer-wrapper classification for failures outside test execution.
  • Prevents duplicate classification and extra querySlurmJobState SSH calls.
  • Preserves pipeline interruptions and aborts.
  • Returns null when querySlurmJobState cannot classify a failure.
  • Updates executeLLMTestOnSlurm with the optional classifySlurmFailure closure while preserving compatibility through the default value.
  • Moves superseded-attempt result XML files aside before artifact packaging.
  • Prevents aggregated JUnit processing from re-ingesting superseded retry results.
  • No configuration or test-list changes are included.

QA Engineer Review

No test changes.

Description

A single-node SLURM stage (agent path) that infra-fails on attempt 1 and passes on retry was still marked UNSTABLE: the failed attempt's junit was reported even though the retry succeeded. The suppression decision in cacheErrorAndUploadResult classified the raw pytest error, but the retryable-infra determination (slurm-job-still-running / walltime-timeout) is made by the monitor in runLLMTestlistWithAgent after cacheErrorAndUploadResult already called junit(). So a machine failure whose raw error didn't match a catalog pattern was reported, then retried anyway -> the passing retry couldn't remove attempt 1's results.

Move the SLURM-state classification into a closure applied inside the task runner (via executeLLMTestOnSlurm), so cacheErrorAndUploadResult suppresses this attempt's junit for the same typed failure the retry loop acts on. The outer catch trusts that label (only classifying failures raised outside the task runner), keeping suppression and retry consistent -- a suppressed attempt is always the one that retries, so there is no risk of hiding a non-retried failure. The sbatch path already behaves this way (it throws the typed InfraFailure inside the function that owns junit).

querySlurmJobState self-manages its frontend SSH and returns null on any failure, so running it inside the on-node container degrades gracefully to the prior behavior rather than breaking classification.

Test Coverage

N/A, this is a CI change

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

…URM infra retries

A single-node SLURM stage (agent path) that infra-fails on attempt 1 and passes
on retry was still marked UNSTABLE: the failed attempt's junit was reported even
though the retry succeeded. The suppression decision in cacheErrorAndUploadResult
classified the raw pytest error, but the retryable-infra determination
(slurm-job-still-running / walltime-timeout) is made by the monitor in
runLLMTestlistWithAgent *after* cacheErrorAndUploadResult already called junit().
So a machine failure whose raw error didn't match a catalog pattern was reported,
then retried anyway -> the passing retry couldn't remove attempt 1's results.

Move the SLURM-state classification into a closure applied inside the task runner
(via executeLLMTestOnSlurm), so cacheErrorAndUploadResult suppresses this attempt's
junit for the same typed failure the retry loop acts on. The outer catch trusts
that label (only classifying failures raised outside the task runner), keeping
suppression and retry consistent -- a suppressed attempt is always the one that
retries, so there is no risk of hiding a non-retried failure. The sbatch path
already behaves this way (it throws the typed InfraFailure inside the function
that owns junit).

querySlurmJobState self-manages its frontend SSH and returns null on any failure,
so running it inside the on-node container degrades gracefully to the prior
behavior rather than breaking classification.

Signed-off-by: Derek Pitman <dpitman@nvidia.com>
@dpitman-nvda
dpitman-nvda requested a review from a team as a code owner July 31, 2026 16:24
@dpitman-nvda
dpitman-nvda requested review from mzweilz and tburt-nv July 31, 2026 16:24
@dpitman-nvda dpitman-nvda changed the title [TRTLLMINF-81][fix] Suppress agent-path junit for monitor-detected SLURM infra retries [None][fix] Suppress agent-path junit for monitor-detected SLURM infra retries Jul 31, 2026
@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ff266f12-8dc8-487a-abdc-098bb607f146

📥 Commits

Reviewing files that changed from the base of the PR and between 1eb3077 and 60955ac.

📒 Files selected for processing (1)
  • jenkins/L0_Test.groovy
🚧 Files skipped from review as they are similar to previous changes (1)
  • jenkins/L0_Test.groovy

Walkthrough

SLURM failures are classified before result caching and JUnit reporting. Timeout states become non-retryable UserFailures. Active jobs become retryable InfraFailures. Retry-superseded XML files are renamed before packaging.

Changes

SLURM failure classification

Layer / File(s) Summary
SLURM failure classification and runner integration
jenkins/L0_Test.groovy
The task runner classifies timeout states as non-retryable UserFailures, active jobs as retryable InfraFailures, and other failures through the existing classifier. executeLLMTestOnSlurm applies the optional classifier before result caching and reporting.
Retry result artifact handling
jenkins/L0_Test.groovy
Retry-superseded result XML files are renamed before packaging, which prevents top-level JUnit collection while retaining the files in the uploaded artifact.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: tburt-nv

Sequence Diagram(s)

sequenceDiagram
  participant SLURM
  participant TaskRunner
  participant ResultCache
  participant JUnitReporter
  SLURM->>TaskRunner: return job state and execution failure
  TaskRunner->>TaskRunner: classify failure
  TaskRunner->>ResultCache: cache classified result
  ResultCache->>JUnitReporter: report result
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the fix for suppressing agent-path JUnit results during monitor-detected SLURM infrastructure retries.
Description check ✅ Passed The description explains the failure, the classification change, the fallback behavior, and the CI test coverage status.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
jenkins/L0_Test.groovy (1)

1278-1290: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the unreachable FlowInterruptedException check.

FlowInterruptedException extends java.lang.InterruptedException. The preceding catch (InterruptedException e) { throw e } at Line 1278-1279 already intercepts any FlowInterruptedException before control can reach catch (Exception e) at Line 1280. The e.getClass().name.contains("FlowInterruptedException") check at Line 1286 can therefore never be true; the comment's stated goal ("Pipeline aborts ... must not be relabeled") is already achieved by the first catch clause alone.

This is dead code with no functional effect today, but it misleads a future reader into thinking this line provides protection that it does not. Remove it, or add a short comment noting the InterruptedException catch already covers this case.

♻️ Proposed cleanup
             } catch (Exception e) {
                 // Label the failure against the SLURM job's terminal state before
                 // cacheErrorAndUploadResult decides junit suppression, so a monitor-
                 // detected infra failure (e.g. slurm-job-still-running) suppresses this
-                // attempt's results and a passing retry stays green. Pipeline aborts
-                // (FlowInterruptedException) must not be relabeled.
-                if (classifySlurmFailure == null || e.getClass().name.contains("FlowInterruptedException")) {
+                // attempt's results and a passing retry stays green. Pipeline aborts
+                // (FlowInterruptedException) are already excluded by the InterruptedException
+                // catch above, since FlowInterruptedException extends InterruptedException.
+                if (classifySlurmFailure == null) {
                     throw e
                 }
                 throw classifySlurmFailure(e)
             }

As per the verified Jenkins plugin API, FlowInterruptedException is public final class FlowInterruptedException extends InterruptedException, so any generic Exception catch block placed after an InterruptedException catch block never sees it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jenkins/L0_Test.groovy` around lines 1278 - 1290, Remove the unreachable
FlowInterruptedException class-name check from the catch (Exception e) guard in
the surrounding try/catch flow. Retain the preceding catch (InterruptedException
e) rethrow, which already preserves pipeline abort behavior, and keep the
classifySlurmFailure handling for other exceptions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jenkins/L0_Test.groovy`:
- Around line 1233-1248: Track whether classifySlurmFailure has already
processed the current SLURM attempt, including the deferred path that returns
the original exception, and update the outer catch around executeLLMTestOnSlurm
to skip reclassification when that flag is set. Preserve propagation of the
already-classified or deferred exception while still classifying failures raised
outside the task runner exactly once.

---

Nitpick comments:
In `@jenkins/L0_Test.groovy`:
- Around line 1278-1290: Remove the unreachable FlowInterruptedException
class-name check from the catch (Exception e) guard in the surrounding try/catch
flow. Retain the preceding catch (InterruptedException e) rethrow, which already
preserves pipeline abort behavior, and keep the classifySlurmFailure handling
for other exceptions unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6ea18a1e-801b-46f4-8002-0b503a002ac8

📥 Commits

Reviewing files that changed from the base of the PR and between 932d3b9 and 2056975.

📒 Files selected for processing (1)
  • jenkins/L0_Test.groovy

Comment thread jenkins/L0_Test.groovy
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63065 [ run ] triggered by Bot. Commit: 2056975 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63065 [ run ] completed with state FAILURE. Commit: 2056975
/LLM/main/L0_MergeRequest_PR pipeline #51164 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

Address CodeRabbit: on the deferred path classifySlurmFailure returns the raw
exception (not a TrtllmCiException), so the outer catch reclassified it a second
time -- the common path for ordinary test failures. The duplicate call adds an
avoidable querySlurmJobState SSH round trip and, because elapsed time and the
job state advance while cacheErrorAndUploadResult uploads results and runs
junit(), the second verdict could differ and flip the retry/suppression decision
the first classification already made. Track classification with a flag so the
outer catch only classifies failures raised outside the task runner.

Signed-off-by: Derek Pitman <dpitman@nvidia.com>
@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63131 [ run ] triggered by Bot. Commit: 1eb3077 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63131 [ run ] completed with state FAILURE. Commit: 1eb3077
/LLM/main/L0_MergeRequest_PR pipeline #51219 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63482 [ run ] triggered by Bot. Commit: 1eb3077 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63482 [ run ] completed with state FAILURE. Commit: 1eb3077
/LLM/main/L0_MergeRequest_PR pipeline #51451 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63537 [ run ] triggered by Bot. Commit: 1eb3077 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63537 [ run ] completed with state FAILURE. Commit: 1eb3077
/LLM/main/L0_MergeRequest_PR pipeline #51503 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63777 [ run ] triggered by Bot. Commit: 1eb3077 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63777 [ run ] completed with state SUCCESS. Commit: 1eb3077
/LLM/main/L0_MergeRequest_PR pipeline #51726 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63793 [ run ] triggered by Bot. Commit: 1eb3077 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63793 [ run ] completed with state SUCCESS. Commit: 1eb3077
/LLM/main/L0_MergeRequest_PR pipeline #51739 completed with status: 'UNSTABLE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

…gated junit

A suppressed infra-retry attempt still uploads its result tar for forensics.
The top-level Collect Test Result stage re-ingests every results-*.tar.gz via
junit('**/results*.xml'), so a superseded attempt's results-timeout.xml (left
by a monitor-cut still-running job) flipped the build UNSTABLE even though the
stage passed on retry. Move the superseded attempt's result XMLs aside before
taring so neither junit path re-counts them.

Signed-off-by: Derek Pitman <dpitman@nvidia.com>
@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63825 [ run ] triggered by Bot. Commit: 60955ac Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63825 [ run ] completed with state FAILURE. Commit: 60955ac
/LLM/main/L0_MergeRequest_PR pipeline #51766 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@dpitman-nvda

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64059 [ run ] triggered by Bot. Commit: 60955ac Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #64059 [ run ] completed with state SUCCESS. Commit: 60955ac
/LLM/main/L0_MergeRequest_PR pipeline #51988 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

CI Report

Link to invocation

@dpitman-nvda
dpitman-nvda merged commit e5e3821 into NVIDIA:main Aug 5, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants