Skip to content

PDX-486: feat(mcp) — testrun zero-tests guard (Thread B, PR 1/3)#185

Merged
mrdailey99 merged 3 commits into
developfrom
fix/PDX-486-validate-typo-b-zero-tests-guard
May 20, 2026
Merged

PDX-486: feat(mcp) — testrun zero-tests guard (Thread B, PR 1/3)#185
mrdailey99 merged 3 commits into
developfrom
fix/PDX-486-validate-typo-b-zero-tests-guard

Conversation

@mrdailey99
Copy link
Copy Markdown
Collaborator

Context

When provar_automation_testrun exits 0 but no tests actually executed — most often because the provardx-properties.json has testCase instead of testCases (or vice versa, or any unknown selector key) — the response previously contained an empty steps[] array and no other signal. Agents (and humans) had no way to distinguish "intentionally zero tests ran" from "typo silently dropped my entire selector," leading to wasted retry loops and downstream confusion when later tooling tried to read results.

This PR is Thread B, PR 1 of 3 in the VALIDATE-TYPO / propagation track. It introduces the RUN-001 zero-tests guard on provar_automation_testrun.

Why

  • Closes the silent-failure gap on the most common Provar properties typo (testCasetestCases).
  • Lands the first consumer of the shared WARNING_CODES enum from PDX-485 (PDX-485: chore(mcp) — shared warningCodes.ts enum #182) in production tooling.
  • Sets up a single JUnit introspection point (introspectJUnit) so the future JUNIT-001 mismatch warning (PDX-491, Thread B PR 3) can extend it cleanly without re-parsing the XML.

What changed

  • src/mcp/tools/automationTools.ts
    • New introspectJUnit(config) helper returning { steps, stepCount, parseWarning, resultsPathResolved } — single read-point for downstream warning emitters.
    • Success-path branch now appends a formatWarning(WARNING_CODES.RUN_001, …) entry to a warnings[] array when resultsPathResolved && stepCount === 0. Strictly additive — exitCode and isError are untouched.
    • Tool description now mentions the RUN-001 surface and the testCase/testCases spelling pitfall.
  • docs/mcp.md — documents the new warnings[] field on the testrun output and references RUN-001.
  • test/unit/mcp/automationTools.test.ts — four new tests covering: fires on empty <testsuite>, does not fire when steps ≥ 1, does not fire on non-zero exit, does not fire when results dir is unresolved. The expected warning string is built via formatWarning (no inline duplicates).

Out of scope (sibling PRs)

  • Validator unknown-key detection — VALIDATE-TYPO-A (Thread A PR 1).
  • provar_automation_config_load propagating SCHEMA-001 — scheduled for Thread B PR 3 stitch commit after both halves merge.
  • properties_file inline param (PDX-487) — Thread B PR 2.
  • JUNIT-001 mismatch warning (PDX-491) — Thread B PR 3 (will extend introspectJUnit).

Test plan

  • yarn compile clean.
  • yarn lint clean.
  • Full unit suite (node_modules/.bin/nyc node_modules/.bin/mocha "test/**/*.test.ts") — 1163 passing, 1 pending, 0 failing.
  • automationTools.test.ts — 80/80 passing, includes the four new RUN-001 scenarios.
  • MCP smoke test — could not run locally on this machine due to "No activated Provar license found" (environmental, unrelated to this change). CI smoke run will validate end-to-end.

Dependencies

  • Depends on PDX-485: chore(mcp) — shared warningCodes.ts enum #182 (PDX-485 chore/PDX-485-warning-codes-enum) — uses WARNING_CODES.RUN_001 and formatWarning from src/mcp/utils/warningCodes.ts. PDX-485 is already merged into this branch.
  • Sibling of Thread A PR-1 (VALIDATE-TYPO-A) — that PR adds the validator unknown-key detection and a testcases-typo.json fixture. This PR uses its own inline JUnit XML fixtures to avoid coupling.

RCA: provar_automation_testrun returned exitCode 0 with an empty steps[] array when a misspelled testCase/testCases key in provardx-properties.json caused the run to select nothing. Agents (and humans) had no signal to disambiguate "intentionally zero tests ran" from "typo silently dropped my entire selector", leading to wasted retry loops and downstream confusion when later tooling complained about missing results.

Fix: Introduce a single JUnit introspection helper (introspectJUnit) that returns stepCount, parseWarning, and a resultsPathResolved flag. When sf exits 0 and the JUnit XML for the resolved results dir contains zero test cases, the response gains a warnings[] entry built via formatWarning(WARNING_CODES.RUN_001, ...) pointing the agent at the testCase/testCases spelling pitfall. The warning is additive — exitCode and isError remain unchanged. The helper is structured so future PDX-491 JUNIT-001 (expected-vs-actual mismatch) can read stepCount from the same struct without re-parsing. Updated the tool description, docs/mcp.md (RUN-001 output documentation), and added four targeted tests (positive, success-with-steps negative, non-zero-exit negative, unresolved-results-dir silent case).
Copilot AI review requested due to automatic review settings May 19, 2026 21:20
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

Quality Orchestrator

🟢 LOW · 4 / 100 · All changed files have mapped tests.


🧪 Tests to Run · Running 2 of 53 tests

  • unit/mcp/antTools.test.ts
  • unit/mcp/automationTools.test.ts
▶ Run command
npx vitest run \
  unit/mcp/antTools.test.ts \
  unit/mcp/automationTools.test.ts

⚡ quality-orchestrator  ·  /qo stub <file>  ·  qo analyze-local

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a standardized warning-code surface to MCP and introduces a RUN-001 “zero tests executed” guard on provar_automation_testrun, so consumers can distinguish “success but nothing ran” from a normal successful run with results.

Changes:

  • Added WARNING_CODES + formatWarning() utility and corresponding unit tests.
  • Added JUnit introspection helper + success-path warnings[] emission for RUN-001 when step count is zero.
  • Updated MCP docs and automationTools tests to document/cover the new warnings[] output shape.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/mcp/utils/warningCodes.ts Introduces shared warning code constants and canonical formatter.
src/mcp/tools/automationTools.ts Adds introspectJUnit() and emits RUN-001 warning on zero-step successful testruns.
test/unit/mcp/utils/warningCodes.test.ts Adds unit coverage for code mapping and formatter behavior.
test/unit/mcp/automationTools.test.ts Adds unit scenarios for the RUN-001 warning behavior.
docs/mcp.md Documents warning codes and adds warnings[]/RUN-001 to testrun tool docs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/mcp/tools/automationTools.ts Outdated
Comment on lines +344 to +349
if (junit.resultsPathResolved && junit.stepCount === 0) {
const warningStr = formatWarning(WARNING_CODES.RUN_001, ZERO_TESTS_MESSAGE);
// Append rather than overwrite so future warning emitters (e.g. JUNIT-001 mismatch
// in PDX-491) can coexist on the same response without stepping on each other.
const existing = response['warnings'] as string[] | undefined;
response['warnings'] = existing ? existing.concat(warningStr) : [warningStr];
Comment thread docs/mcp.md Outdated
Comment on lines +1411 to +1416
Each entry represents one test case. `status` is `"pass"`, `"fail"`, or `"skip"`. If the results directory cannot be located or contains no JUnit XML, `details.warning` explains why and `steps` is absent.

**Zero-tests guard (RUN-001):** when the sf command exits 0 but the JUnit report contains zero executed test cases, the response includes a `warnings[]` array containing a [`RUN-001`](#warning-codes) message. This is almost always a typo such as `testCase` vs `testCases` (or some other unknown key) in `provardx-properties.json` — the run silently selected nothing. The warning is additive and never flips `exitCode` or sets `isError`; the failure surface remains driven by the underlying `sf` exit code.

**Error codes:** `AUTOMATION_TESTRUN_FAILED`, `SF_NOT_FOUND`
**Warning codes:** `RUN-001` (zero tests executed despite success)
Comment on lines +239 to +246
describe('RUN-001 zero-tests-executed warning', () => {
const expectedWarning = formatWarning(
WARNING_CODES.RUN_001,
'Test run exited successfully but zero tests were executed. ' +
'Check the testCase / testCases (note spelling) field in provardx-properties.json.'
);

it('fires when exit is 0 and JUnit step count is 0 (empty <testsuite>)', () => {
…s when JUnit data missing

RCA: The RUN-001 zero-tests-executed warning fired whenever `resultsPathResolved === true && stepCount === 0`. That condition is also true when the results dir was located but contained no XML files, or when every XML file failed to parse — in those cases the tool has no data on which to claim "zero tests ran" yet would still emit RUN-001, misdirecting the agent toward a properties-file typo when the real problem was an unreadable/unwritten results dir.

Fix: Extended parseJUnitResults to return parsedAny: boolean (true iff at least one JUnit XML file was located AND parsed without throwing). Tightened the RUN-001 gate in introspectJUnit/registerAutomationTestRun to require `resultsPathResolved && parsedAny && stepCount === 0`. The "no XML found" and "all XML unparseable" branches now stay silent on warnings[] and surface only through details.warning, as the docs already described. Aligned the in-tree tool description and docs/mcp.md to spell out the parsedAny requirement, and added/strengthened tests covering the missing-XML, malformed-XML, and empty-<testsuite> (legit RUN-001) cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

@mrdailey99 mrdailey99 left a comment

Choose a reason for hiding this comment

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

Addressed in 3ca9379: tightened RUN-001 to require parsedAny; added missing-XML and malformed-XML negative tests; docs aligned.

@mrdailey99 mrdailey99 merged commit 3e4ef29 into develop May 20, 2026
4 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.

2 participants