Skip to content

Allow paths in --report-trx-filename#8406

Merged
Evangelink merged 12 commits into
mainfrom
dev/amauryleve/trx-filename-path
May 22, 2026
Merged

Allow paths in --report-trx-filename#8406
Evangelink merged 12 commits into
mainfrom
dev/amauryleve/trx-filename-path

Conversation

@Evangelink
Copy link
Copy Markdown
Member

Fixes #5634.

Today the --report-trx-filename option only accepts a bare file name; any path component fails validation with file name argument must not contain path. The original restriction predated placeholder support (#5364) and was meant to avoid stomping on result files when multiple test projects targeted the same TestResults folder. Now that placeholders can disambiguate per project / TFM, it is safe to lift the restriction.

Behavior

  • --report-trx-filename now accepts a bare file name, a relative path, or an absolute path.
  • Placeholders are resolved on the full input; only the leaf file name is sanitized for invalid chars, so path separators in the directory portion are preserved.
  • Relative paths nest under the test results directory; absolute paths are written as-is (Path.Combine short-circuits on rooted second arg).
  • Missing intermediate directories are created automatically via IFileSystem.CreateDirectory.
  • The .trx extension check now targets the leaf file name. A new validation rejects inputs whose leaf is empty (e.g. sub/).

Out of scope

  • Artifact copying still occurs under the test results directory (unchanged from today / VSTest behavior). Filed under follow-up if requested.

Tests

  • New unit tests in TrxReportGeneratorCommandLineTests for bare/relative/absolute paths and empty-leaf rejection.
  • New unit tests in TrxTests for relative subdir, absolute path, and per-leaf sanitization (verifies CreateDirectory is invoked).
  • TrxTests acceptance tests: replaced the two *_TrxReportShouldFail cases with success counterparts (relative subdir + absolute path).
  • HelpInfoAllExtensionsTests updated to match new option description.

Localization

  • Updated TrxReportFileNameOptionDescription and added TrxReportFileNameMustNotBeEmpty. Regenerated all 13 xlf files via dotnet msbuild .../Microsoft.Testing.Extensions.TrxReport.csproj /t:UpdateXlf. Legacy TrxReportFileNameShouldNotContainPath kept in place to minimize localization churn.

Verification

  • build.cmd -c Release -pack succeeds.
  • Microsoft.Testing.Extensions.UnitTests: 297/297 pass on net9.0 and net462.
  • Acceptance: 28 TrxTests, 30 HelpInfo tests, 6 MSTest TrxReport tests pass.

Amaury Levé and others added 2 commits May 20, 2026 20:06
… and refined guidance

- Add repository layout overview (MTP, TestFramework, Adapter, Analyzers, SDK, tests, eng)

- Add build/test command table and how to run a single test via --filter-uid / --treenode-filter

- Document UpdateXlf MSBuild target and PlatformResources.cs IS_MTP_UNIT_TESTS caveat

- Correct testing guidance: assertion style is per-project (BannedSymbols.txt)

- Note TestContainer convention and [DoNotParallelize] requirement for shared-asset acceptance tests

- Pull TODO comment policy from CONTRIBUTING.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Today the --report-trx-filename option only accepts a bare file name; any
path component fails validation with 'file name argument must not contain
path'. The original restriction predated placeholder support and was meant
to avoid stomping on result files when multiple test projects targeted the
same TestResults folder. Placeholder support (#5364) now lets users
disambiguate per-project/tfm, so it is safe to lift the restriction.

This change:

- Removes the path rejection in TrxReportGeneratorCommandLine. The .trx
  extension check is now applied to the leaf file name so paths like
  'subdir/report.trx' still validate. A new error message rejects inputs
  whose leaf file name is empty (e.g. 'sub/').
- Updates TrxReportEngine to resolve placeholders on the full input and
  then sanitize only the leaf file name with the existing invalid-char
  scrubber, so path separators in the directory portion are preserved.
- Combines the sanitized name with the test results directory using
  Path.Combine, which short-circuits to the user's path when absolute and
  nests under the test results directory when relative.
- Calls IFileSystem.CreateDirectory on the parent directory before opening
  the stream so missing intermediate directories are created automatically.
- Updates the option description, refreshes the help/info acceptance test
  expectations, and adds unit and acceptance coverage for relative, nested
  and absolute paths plus the new empty-file-name validation.

Fixes #5634.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 20, 2026 19:57
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 updates the TRX report filename option (--report-trx-filename) to accept paths (relative or absolute), aligning with placeholder support and enabling users to direct TRX output into nested or external directories.

Changes:

  • Updated TRX filename validation to allow relative/absolute paths while enforcing non-empty leaf file name and .trx extension.
  • Updated TRX report generation to preserve directory components, sanitize only the leaf filename, and create intermediate directories.
  • Updated unit + acceptance tests, help/info expectations, and localized resources for the new behavior/wording.
Show a summary per file
File Description
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs Adds unit coverage for relative/absolute paths and leaf-only sanitization behavior.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportGeneratorCommandLineTests.cs Updates validation tests to cover relative/absolute paths and empty-leaf rejection.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs Converts prior “path should fail” acceptance cases into success cases for relative/absolute paths.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs Updates help/info expected text for --report-trx-filename description.
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs Preserves directory portion, sanitizes only leaf filename, combines with results dir, and ensures directories exist.
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCommandLine.cs Relaxes validation to allow paths; enforces non-empty leaf + .trx extension.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/ExtensionResources.resx Updates option description and adds new “leaf must not be empty” message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.cs.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.de.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.es.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.fr.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.it.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ja.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ko.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.pl.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.pt-BR.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ru.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.tr.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.zh-Hans.xlf Regenerated localization entries for updated description + new validation message.
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.zh-Hant.xlf Regenerated localization entries for updated description + new validation message.
.github/copilot-instructions.md Expands contributor guidance (repo layout, build/test commands, localization + testing notes, TODO policy).

Copilot's findings

  • Files reviewed: 21/21 changed files
  • Comments generated: 3

Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

Review Summary — PR #8406 "Allow paths in --report-trx-filename"

Overall the PR is well-structured: the validation change is clean, the engine correctly splits directory + leaf before sanitising, CreateDirectory is called upfront, and the xlf files were regenerated rather than hand-edited. Tests cover the new happy and error paths.

Dimension results

# Dimension Result
1 Algorithmic Correctness ⚠️ See inline — backslash path has different semantics on Linux vs Windows
2 Threading & Concurrency ✅ LGTM
3 Security & IPC Contract Safety ⚠️ ../foo.trx now silently escapes the test-results directory — intentional but undocumented
4 Public API & Binary Compatibility ✅ LGTM — no public surface changed
5 Performance & Allocations ✅ LGTM
6 Cross-TFM Compatibility ✅ LGTM — only Path.* and string.* APIs used
7 Resource & IDisposable Management ✅ LGTM
8 Defensive Coding at Boundaries ✅ LGTM
9 Localization & Resources ✅ LGTM — new resource added to .resx, xlf regenerated, old string retained
10 Test Isolation ✅ LGTM — acceptance tests use Guid.NewGuid() paths and clean up in finally
11 Assertion Quality ✅ LGTM — MSTest Assert.* used in the unit-test project (correct for this project)
12 Flakiness Patterns ✅ LGTM
13 Test Completeness & Coverage ✅ LGTM — relative, absolute, empty-leaf, and extension cases covered
14 Data-Driven Test Coverage ⚠️ See inline — "sub\\foo.trx" DataRow has platform-specific behaviour
15 Code Structure & Simplification ✅ LGTM — final TrxCommandLine.cs is clean (no dead code)
16 Naming & Conventions ✅ LGTM
17 Documentation Accuracy ✅ LGTM — TrxReportFileNameOptionDescription updated accurately
18 Analyzer Quality N/A
19 IPC Wire Compatibility N/A
20 Build Infrastructure & Dependencies ✅ LGTM
21 Scope & PR Discipline ✅ LGTM — single concern, references issue #5634

Notable findings (non-blocking)

  1. [DataRow("sub\\foo.trx")] — on Linux this is treated as a bare filename with a literal \ character, not a sub-directory path. Either remove or annotate as Windows-only.
  2. [DataRow("../foo.trx")] — is valid and will silently write the TRX file outside the test results directory (one level up). This is intentional per the PR but deserves a comment in the code.
  3. RetryWhenIOExceptionAsync + explicit path — a pre-existing issue made more reachable: retries on a fixed explicit path spin for up to 5 s before re-throwing an IOException. Not a blocker.

Generated by Expert Code Review (on open) for issue #8406 · ● 11.7M

Evangelink and others added 2 commits May 21, 2026 09:59
Copilot AI review requested due to automatic review settings May 21, 2026 08:35
@Evangelink
Copy link
Copy Markdown
Member Author

Addressed the three actionable Copilot review comments in 7f7f3af and pushed the update. ./build.cmd completed successfully with 0 warnings and 0 errors.

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.

Copilot's findings

  • Files reviewed: 21/21 changed files
  • Comments generated: 1

@Evangelink
Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 21, 2026

@copilot resolve the merge conflicts in this pull request

Conflicts are resolved in commit 7d83aa8 after merging origin/main into this branch and fixing all merge markers.

Evangelink and others added 2 commits May 21, 2026 18:21
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 21, 2026 16:29
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.

Copilot's findings

  • Files reviewed: 21/21 changed files
  • Comments generated: 2

@@ -132,8 +144,20 @@ public TrxReportEngine(
}

string outputDirectory = _configuration.GetTestResultDirectory(); // add var for this
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Removed in 726b7f4.

Evangelink and others added 4 commits May 21, 2026 18:48
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Reject Windows drive-relative paths (e.g. `C:foo.trx`) that are
  rooted but not fully qualified and would silently escape the test
  results directory.
- Simplify `EscapesResultsDirectory` to use `Any` and a single
  shared separator array, replacing the foreach loop and removing a
  tautological comparison flagged by github-code-quality.
- Drop the stray `// add var for this` leftover comment in
  `TrxReportEngine`.
- Add a Windows-only unit test for drive-relative inputs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 22, 2026 09:18
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.

Copilot's findings

  • Files reviewed: 21/21 changed files
  • Comments generated: 5

Comment on lines +69 to +71
<target state="new">The name of the generated TRX report. May include a relative or absolute path; relative paths are resolved against the test results directory and missing directories are created.
Supports the following placeholders: {pname} (test application name), {pid} (process ID), {asm} (entry assembly name), {tfm} (target framework moniker), {time} (timestamp).
Example: MyReport_{tfm}.trx</target>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Restored in dc49329. The previous translated value is back in place and marked as state="needs-review-translation" so the localization team can re-review the updated source text without regressing the existing translation.

Comment on lines +69 to +71
<target state="new">The name of the generated TRX report. May include a relative or absolute path; relative paths are resolved against the test results directory and missing directories are created.
Supports the following placeholders: {pname} (test application name), {pid} (process ID), {asm} (entry assembly name), {tfm} (target framework moniker), {time} (timestamp).
Example: MyReport_{tfm}.trx</target>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Restored in dc49329. The previous translated value is back in place and marked as state="needs-review-translation" so the localization team can re-review the updated source text without regressing the existing translation.

Address PR feedback: tr/ru/pt-BR/pl/it xlf files had previous translated
<target> values overwritten with the new English source and state=new.
Restore the prior localized strings and mark them as
needs-review-translation so the source-text update can be re-reviewed by
the localization team without regressing the existing translations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink merged commit a6d4ab9 into main May 22, 2026
32 of 42 checks passed
@Evangelink Evangelink deleted the dev/amauryleve/trx-filename-path branch May 22, 2026 11:00
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.

TRX file name output should support path

3 participants