Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[quality-improver] CiRunSummaryAggregateReader.ValidateModule provenance cross-check guards are untested on the throwing path

Closed Beginner friendly
#11,477 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
70/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
csharp
Domain
testing-qa

Research direction

The issue is about adding unit tests for the provenance guards in CiRunSummaryAggregateReader.ValidateModule. Start by reading the existing test file at test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CiRunSummaryAggregationTests.cs and the helper method CreateInput. Then, modify the helper to accept optional parameters for mismatched provenance values. Write new tests that pass mismatched InputArtifact values for ProducingTestModule, TargetFramework, Architecture, and ExecutionId/AttemptNumber, and assert that FormatException is thrown with the expected message. Run the tests to ensure they pass and cover the previously untested throwing paths.

Written by the indexing model from the issue text.

Description

type/automation type/tech-debt
🎯 Repository Quality Improvement Report — CI Run Summary Provenance Guard Coverage Gap

Analysis Date: 2026-09-23
Focus Area: ci-run-summary-provenance-guard-coverage-gap
Strategy Type: Custom

Executive Summary

Microsoft.Testing.Extensions.SharedExtensionHelpers recently gained a new CiRunSummaryAggregation/CiRunSummaryAggregateReader pair that aggregates per-module CI run summary fragments (coverage, flaky tests, history, dependencies) shared by both the AzureDevOpsReport and GitHubActionsReport extensions. CiRunSummaryAggregateReader.ValidateModule includes four distinct "provenance" guards that cross-check a deserialized fragment's ModulePath, TargetFramework, Architecture, and ExecutionId/AttemptNumber against the InputArtifact metadata supplied by the platform's artifact post-processing pipeline, throwing FormatException on any mismatch. These guards exist specifically to catch fragments that were mixed up between modules/frameworks/architectures/retry attempts in CI — exactly the kind of defect that is silent until multi-module or multi-attempt runs corrupt an aggregate report.

test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CiRunSummaryAggregationTests.cs is a substantial 972-line, 23-test suite that already covers schema-version mismatches, duplicate identities, null bounded collections, and null history/dependency entries — but every test constructs its InputArtifact via the CreateInput helper, which always derives producingTestModule, targetFramework, architecture, and executionId directly from the same module object being validated. As a result the four provenance-mismatch branches (lines ~183–192 of CiRunSummaryAggregateReader.cs) are never exercised on their throwing path — a regression that silently disabled cross-module corruption detection (e.g. reverting a != to ==, or dropping a branch) would compile and pass the entire existing suite.

The task below adds targeted tests that pass a mismatched InputArtifact for each of the four provenance dimensions plus the RetryAttempts attempt-number variant, asserting the specific FormatException message for each.

Full Analysis Report
Focus Area: CI Run Summary Provenance Guard Coverage Gap
Current State Assessment

Metrics Collected:

Metric Value Status
CiRunSummaryAggregateReader.cs size 248 lines —
Existing test file size / test count 972 lines / 23 [TestMethod]s ✅ generally strong
Provenance guards in ValidateModule 4 (ProducingTestModule, TargetFramework, Architecture, ExecutionId/AttemptNumber) ❌ 0 tested on throwing path
CreateInput helper derives fields from module under test Always ❌ guarantees provenance always matches
Related sibling files (NamedPipeServerFactory.cs, PipeNameEnvironmentVariableProviderBase.cs, CiRunSummaryFragmentIo.cs, ReportFileNameHelper.cs) 0 dedicated unit tests each ⚠️ noted, out of scope for this task
Findings
Strengths
  • The overall CiRunSummaryAggregation test suite is unusually thorough: schema-version checks, malformed JSON, duplicate identities, bounded-collection truncation ordering, and coverage aggregation are all covered with clear Arrange/Act/Assert structure and descriptive test names.
  • ValidateModule's validation logic itself is well-structured and defensive (checked arithmetic, explicit NaN/Infinity guards, bounded collection caps).
Areas for Improvement
  • ⚠️ Medium severity: The four provenance cross-check guards in ValidateModule (src/Platform/SharedExtensionHelpers/CiRunSummaryAggregateReader.cs, lines ~163–192) have no test coverage for their throwing path. CreateInput (test helper, line ~851) always builds an InputArtifact whose producingTestModule/targetFramework/architecture/executionId match the module being validated, so a regression that weakens or removes any of these four if checks would not be caught by the existing 23 tests.
  • ⚠️ Low-medium severity (noted, not actioned): NamedPipeServerFactory.cs, PipeNameEnvironmentVariableProviderBase.cs, CiRunSummaryFragmentIo.cs, and ReportFileNameHelper.cs in the same SharedExtensionHelpers project also have zero dedicated unit tests, but their logic is comparatively thin (pipe naming/env var plumbing, file read/write wrappers) and lower risk than the provenance guards, which protect data integrity of CI reporting across concurrent/retried test runs.

🤖 Suggested Improvement Tasks
Task 1: Add tests for ValidateModule's ProducingTestModule provenance mismatch

Priority: Medium
Estimated Effort: Small

In test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CiRunSummaryAggregationTests.cs, add a test that writes a valid fragment for a module (e.g. via CreateModule/WriteFragmentAsync), then calls CiRunSummaryAggregation.ReadAndAggregate with an InputArtifact whose producingTestModule argument is a different path than module.ModulePath (while input.Path still points at the correct fragment file). Assert Assert.ThrowsExactly<FormatException>(...) and, ideally, assert on the exception message containing "provenance does not match" to pin the specific guard. This exercises src/Platform/SharedExtensionHelpers/CiRunSummaryAggregateReader.cs's if (input.ProducingTestModule is not null && !PathsEqual(...)) branch.


Task 2: Add tests for TargetFramework and Architecture provenance mismatch

Priority: Medium
Estimated Effort: Small

Add two tests (or one [DataRow]-parameterized test) analogous to Task 1, but instead pass an InputArtifact with a targetFramework or architecture value that differs from the fragment's module. Both branches are in ValidateModule immediately after the ProducingTestModule check. Consider extracting a small helper overload of CreateInput that accepts explicit override values for producingTestModule, targetFramework, architecture, and executionId instead of always deriving them from module, to keep the new tests concise and to make future provenance tests easy to add.


Task 3: Add tests for ExecutionId/AttemptNumber provenance mismatch in both post-processing modes

Priority: Medium
Estimated Effort: Small

Add tests covering both branches of the ternary in the ExecutionId guard:

  • ArtifactPostProcessingMode.RetryAttempts: pass an input.ExecutionId that either fails int.TryParse or parses to a value different from module.AttemptNumber.
  • Default mode: pass an input.ExecutionId string that differs from module.ExecutionId.

Both should throw FormatException with the execution-provenance message. This directly complements the existing GitHubAggregate_ForRetryAttempts_UsesInitialAttemptCoverage test, which exercises the happy path of RetryAttempts mode but not its mismatch guard.


Task 4: Extend the shared CreateInput test helper to support mismatched provenance construction

Priority: Low
Estimated Effort: Small

Refactor CreateInput(string path, CiRunSummaryModule module) (line ~851) to add optional parameters (producingTestModule, targetFramework, architecture, executionId) defaulting to the module's own values, so Tasks 1–3 can construct mismatched InputArtifacts without duplicating the existing helper's boilerplate. Keep the existing call sites unchanged by relying on the new parameters' defaults.


📊 Historical Context
Previous Focus Areas
Date Focus Area Type
2026-09-21 extension-self-registration-acceptance-coverage Custom
2026-09-22 noncooperative-parent-process-listener-untested Custom
2026-09-23 ci-run-summary-provenance-guard-coverage-gap Custom

🎯 Recommendations
Immediate Actions (This Week)
  1. Add the four provenance-mismatch tests (Tasks 1–3) — Priority: Medium
Short-term Actions (This Month)
  1. Consider adding basic unit tests for NamedPipeServerFactory, PipeNameEnvironmentVariableProviderBase, CiRunSummaryFragmentIo, and ReportFileNameHelper in SharedExtensionHelpers — Priority: Low

Next analysis: 2026-09-24 — Focus area selected based on diversity algorithm

🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · copilot · auto · 113.4 AIC · ⌖ 6.87 AIC · ⊞ 16.5K · [◷]( · ◷)

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
  • expires on Sep 25, 2026, 10:27 PM UTC
Dominant language
C#
Stars
1k
Forks
314
Avg merge
8h 40m
Merged PRs (30d)
435

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/testfx

All issues in microsoft/testfx

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.