Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
| Property | Value |
|---|---|
| Rule ID | MSTEST0076 |
| Title | Avoid mutating process-wide culture in a parallelized test |
| Category | Usage |
| Fix is breaking or non-breaking | Non-breaking |
| Enabled by default | Yes |
| Default severity | Info |
| Introduced in version | 4.4.0 (preview) |
| Is there a code fix | No |
Note
This analyzer activates only when assembly parallelization is syntactically enabled, for example through [assembly: Parallelize] without a matching [assembly: DoNotParallelize], or when a .editorconfig file sets mstest_parallel_safety_mode = always. The analyzer can't detect parallelization that's enabled only through .runsettings or MSBuild properties such as MSTestParallelizeWorkers. Set the .editorconfig option if you configure parallelization that way and still want this analyzer to run.
Cause
A test, or a class-scoped fixture method it runs under, assigns DefaultThreadCurrentCulture or DefaultThreadCurrentUICulture without a matching [ResourceLock] or [DoNotParallelize].
Rule description
CultureInfo.DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture set the default culture for the whole process, so every concurrently running test observes the change, and formatting or parsing can be corrupted. The per-thread and ambient forms, Thread.CurrentThread.CurrentCulture/CurrentUICulture and CultureInfo.CurrentCulture/CurrentUICulture, aren't flagged: on modern .NET they assign an AsyncLocal-backed value that flows with the execution context, so they don't corrupt sibling tests.
[TestMethod]
public void SetsCulture()
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; // Violation
}
Because the flagged setters are process-wide, restoring the previous value in a finally block doesn't help: concurrently running tests still observe the changed culture for the duration of the mutation.
How to fix violations
Add [DoNotParallelize] on the test, or avoid mutating process-wide culture and use the per-thread or ambient culture properties instead.
[DoNotParallelize]
[TestMethod]
public void SetsCulture()
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
}
No well-known [ResourceLock] key exists for culture, so a declared [ResourceLock] of any kind is treated as an acknowledgment that you've coordinated culture access, and this rule stays silent.
When to suppress warnings
Don't suppress warnings from this rule without opting out of parallelization or switching to the per-thread culture properties, because doing so leaves the mutation racing silently against concurrently running tests.
Suppress a warning
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
#pragma warning disable MSTEST0076
// The code that's violating the rule is on this line.
#pragma warning restore MSTEST0076
To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.MSTEST0076.severity = none
For more information, see How to suppress code analysis warnings.