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.
When you run dotnet test with VSTest in a container, the SDK now needs a writable base directory for private test-session files. In Linux containers, test runs can show warnings about the artifacts directory. On Nano Server, test runs can fail. This change affects the .NET 8, .NET 9, .NET 10, and .NET 11 SDKs.
Version introduced
.NET SDK 11.0.100, 10.0.404, 10.0.115, 9.0.321, 9.0.124, 8.0.428, and 8.0.134
Previous behavior
Previously, dotnet test with VSTest didn't print artifacts-directory warnings in Linux containers. On Nano Server, test runs didn't depend on the current user's Local AppData directory.
New behavior
Starting in the SDK versions listed in Version introduced, the SDK creates a new private directory for each test run. VSTest stores the test-session files that attachment post-processing needs in that directory. The default base directory is /run/user/<uid> on Linux and Local AppData on Windows, where <uid> is the effective user ID of the process. Containers often don't have these locations.
Linux containers
On Linux, the SDK doesn't create the base directory, and it doesn't fall back to /tmp. Instead, it runs VSTest without an artifacts directory, and VSTest tries the same missing base directory.
If the test run produces no attachments, dotnet test prints the following warning:
VSTEST_ARTIFACTS_DIRECTORY environment variable was not found, falling back to a user-private temporary directory. This is most likely caused by an outdated Microsoft.NET.Test.Sdk package reference in the test project.
The advice about the Microsoft.NET.Test.Sdk package can be misleading. A missing /run/user/<uid> directory causes this warning even when the SDK and the package are up to date.
If the test run produces attachments, for example a coverage report from --collect:"XPlat Code Coverage", dotnet test prints the following warning instead:
The test session artifacts were not saved: The user-private temporary directory '/run/user/0' does not exist.
The path contains the current user ID. Other directory verification failures use the same The test session artifacts were not saved: prefix, followed by the reason.
In both cases, the tests continue to run, and a passing run can exit with code 0. If VSTest can't save the session files, the SDK skips attachment post-processing. The original output files from the data collector aren't deleted.
Nano Server containers
On Windows, if the SDK can't resolve the Local AppData directory, the test run stops. This failure can occur with or without a data collector. The SDK prints the following error:
Could not determine a private base directory for the test run: the current user's local application data folder does not exist or could not be resolved. Set the VSTEST_ARTIFACTS_BASE_DIRECTORY environment variable to the directory the artifacts directory should be created under.
Type of breaking change
This change is a behavioral change.
Reason for change
To improve security, the SDK stores test-session files in a private directory that only the current user can access. For more information, see dotnet/sdk issue #57029.
Recommended action
To fix the warnings and the Nano Server failures, set the VSTEST_ARTIFACTS_BASE_DIRECTORY environment variable before you run dotnet test. Use /tmp on Linux and C:\Windows\Temp on Nano Server. Set this variable in the container image or in the CI step that runs the tests.
The official .NET SDK container images set this variable. If your image is based on mcr.microsoft.com/dotnet/sdk, you don't need to set it yourself.
Linux shell:
export VSTEST_ARTIFACTS_BASE_DIRECTORY=/tmp
dotnet test
PowerShell on Nano Server:
$env:VSTEST_ARTIFACTS_BASE_DIRECTORY = 'C:\Windows\Temp'
dotnet test
Linux Dockerfile:
ENV VSTEST_ARTIFACTS_BASE_DIRECTORY=/tmp
Nano Server Dockerfile, with the default backslash escape character:
ENV VSTEST_ARTIFACTS_BASE_DIRECTORY="C:\\Windows\\Temp"
For a docker run command, add -e VSTEST_ARTIFACTS_BASE_DIRECTORY=/tmp on Linux or -e "VSTEST_ARTIFACTS_BASE_DIRECTORY=C:\Windows\Temp" on Windows.
Keep the following points in mind:
- The test process must be able to write to the base directory. The directory doesn't need to exist. The SDK creates missing parent directories if the test process has permission to create them.
- Set
VSTEST_ARTIFACTS_BASE_DIRECTORY, notVSTEST_ARTIFACTS_DIRECTORY. The SDK setsVSTEST_ARTIFACTS_DIRECTORYand passes it to VSTest. - On Linux,
TMPDIRandXDG_RUNTIME_DIRdon't change the default base directory.
A shared base directory such as /tmp is safe because the SDK doesn't write session files to it directly. For each run, the SDK creates a subdirectory with a random name:
- On Linux, the SDK creates the subdirectory with mode
0700, so only its owner can access it. The sticky bit on/tmpprevents other users from deleting or renaming it. - On Windows, the SDK creates the subdirectory with an access control list (ACL) that grants access only to the owner and doesn't inherit permissions from the base directory.
These protections isolate different users. They don't isolate processes that run as the same user, and they don't block root or administrators. Don't remove the normal protections of the base directory.
Affected APIs
None.