Skip to content

Enable method-level parallelization for true unit test projects#55090

Open
Evangelink wants to merge 5 commits into
mainfrom
dev/amauryleve/enable-unittest-method-parallelization
Open

Enable method-level parallelization for true unit test projects#55090
Evangelink wants to merge 5 commits into
mainfrom
dev/amauryleve/enable-unittest-method-parallelization

Conversation

@Evangelink

Copy link
Copy Markdown
Member

What

Opt two genuine unit-test projects back in to method-level test parallelization:

  • test/containerize.UnitTests
  • test/Microsoft.NET.Build.Containers.UnitTests

The repo-wide default in test/Directory.Build.props sets MSTestParallelizeScope=None, which emits [assembly: DoNotParallelize] and fully serializes every MSTest project. These two projects are true unit tests (no disk/CWD dependence, no shared process-global state), so they can safely run methods in parallel.

Why it's safe

I audited both projects for shared-state hazards (environment variables, current-directory mutation, fixed temp paths, mutable statics):

  • containerize.UnitTests — single class, pure parsing tests; temp dirs are keyed per test. No shared state.

  • Microsoft.NET.Build.Containers.UnitTests — the only real hazard is two classes that mutate process-global environment variables. Those are now marked [DoNotParallelize] so they run in MSTest's serial phase:

    • AuthHandshakeMessageHandlerTests (registry credential vars + REGISTRY_AUTH_FILE)
    • DockerDaemonTests (DOCKER_HOST)

    The rest use fakes (RegistryTests' SetEnvironmentVariable throws), read-only statics, and per-test HttpClient instances.

Verification

Both projects build clean (0 warnings, with MSTestAnalysisMode=Recommended active) and the generated AssemblyInfo emits [assembly: Parallelize(Scope = MethodLevel)]. Full test execution runs in CI (the repo's self-built runtime isn't available locally).

The repo-wide default (test/Directory.Build.props) sets MSTestParallelizeScope
to None, fully serializing every MSTest project. The containerize.UnitTests and
Microsoft.NET.Build.Containers.UnitTests projects are genuine unit tests with no
shared process-global state, so opt them back in to MethodLevel parallelization.

The two classes in Containers.UnitTests that mutate process-global environment
variables (AuthHandshakeMessageHandlerTests, DockerDaemonTests) are marked
[DoNotParallelize] so they run serially under the method-level pool.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 09:56
@Evangelink Evangelink requested a review from a team as a code owner July 1, 2026 09:56

Copilot AI 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.

Pull request overview

This pull request opts two MSTest.Sdk-based unit test projects back into method-level parallel execution by overriding the repo-wide MSTestParallelizeScope=None default, and adds [DoNotParallelize] to the few test classes that mutate process-global environment variables.

Changes:

  • Enable MSTestParallelizeScope=MethodLevel for test/containerize.UnitTests.
  • Enable MSTestParallelizeScope=MethodLevel for test/Microsoft.NET.Build.Containers.UnitTests.
  • Mark environment-variable-mutating test classes as [DoNotParallelize] in the containers unit test project.
Show a summary per file
File Description
test/Microsoft.NET.Build.Containers.UnitTests/Microsoft.NET.Build.Containers.UnitTests.csproj Opt the project into MSTest method-level parallelization via MSTestParallelizeScope=MethodLevel.
test/Microsoft.NET.Build.Containers.UnitTests/DockerDaemonTests.cs Add [DoNotParallelize] to avoid concurrency issues due to DOCKER_HOST mutation.
test/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs Add [DoNotParallelize] to avoid concurrency issues due to registry-related env var mutations.
test/containerize.UnitTests/containerize.UnitTests.csproj Opt the project into MSTest method-level parallelization via MSTestParallelizeScope=MethodLevel.

Copilot's findings

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

Comment thread test/Microsoft.NET.Build.Containers.UnitTests/DockerDaemonTests.cs
Comment thread test/containerize.UnitTests/containerize.UnitTests.csproj Outdated
Evangelink and others added 2 commits July 1, 2026 12:10
Address review feedback: capture and restore process-global environment
variables in a finally block so a thrown assertion or a value already set on
the test host cannot leak into subsequent tests.

- GetDockerCredentialsFromEnvironment_ReturnsCorrectValues now restores the
  registry credential vars in finally.
- Authenticate now captures and restores REGISTRY_AUTH_FILE.
- DockerDaemonTests restores the original DOCKER_HOST instead of clearing it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@MichaelSimons

Copy link
Copy Markdown
Member

Is it reasonable to request more than one validation run prior to merging to validate stability in the affected tests?

@Evangelink

Copy link
Copy Markdown
Member Author

Is it reasonable to request more than one validation run prior to merging to validate stability in the affected tests?

Absolutely! I'll ping when I have 5 passing runs

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