Fix TestRunDirectories crash on Android with relative/empty paths#7787
Conversation
Continuation of microsoft#7772. On .NET for Android, `Assembly.Location` returns a relative path like `"AndroidTest1.dll"` (MonoVM) or an empty string (CoreCLR). `Path.GetDirectoryName` returns `""` for these inputs, and then `Directory.CreateDirectory("")` throws `ArgumentException`. This would fail in Release mode on Android, or if the "fast deployment" feature is disabled. Guard against empty/relative paths by checking the result of `Path.GetDirectoryName` and falling back to the standard `RootDeploymentDirectory/Out` path. Full stack trace from AZDO build (https://dev.azure.com/dnceng-public/public/_build/results?buildId=1392743): INSTRUMENTATION_RESULT: error=System.ArgumentException: The value cannot be an empty string. (Parameter 'path') at System.ArgumentException.ThrowNullOrEmptyException(String argument, String paramName) at System.ArgumentException.ThrowIfNullOrEmpty(String argument, String paramName) at System.IO.Directory.CreateDirectory(String path) at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities.FileUtility.CreateDirectoryIfNotExists(String directory) at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities.DeploymentUtilityBase.CreateDeploymentDirectories(IRunContext runContext, String firstTestSource) at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestDeployment.Deploy(IEnumerable`1 testCases, IRunContext runContext, IFrameworkHandle frameworkHandle, ITestSourceHandler testSourceHandler, TestRunCancellationToken cancellationToken) at Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestExecutor.RunTestsAsync(...) at Microsoft.VisualStudio.TestTools.UnitTesting.MSTestBridgedTestFramework.SynchronizedRunTestsAsync(...) at Microsoft.Testing.Extensions.VSTestBridge.SynchronizedSingleSessionVSTestBridgedTestFramework.ExecuteRequestAsync(...) at Microsoft.Testing.Platform.Builder.TestApplication.RunAsync() at DotNetNewAndroidTestMonoVM.TestInstrumentation.<OnStart>b__2_0() INSTRUMENTATION_CODE: 0 Related: dotnet/android#11195, microsoft#7769 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes an Android-specific crash in MSTest adapter deployment directory creation when Assembly.Location is empty or relative (Android CoreCLR/MonoVM), by ensuring OutDirectory falls back to the standard <RootDeploymentDirectory>\Out path.
Changes:
- Update
TestRunDirectoriesto ignore empty/relative (no directory component)firstTestSourcevalues when computingOutDirectory. - Add unit tests covering
firstTestSource == ""andfirstTestSource == "MyTests.dll"fallback behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs |
Adds guarded computation of OutDirectory to avoid Directory.CreateDirectory("") on Android scenarios. |
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/TestRunDirectoriesTests.cs |
Adds regression tests validating fallback behavior for empty/relative firstTestSource. |
Evangelink
left a comment
There was a problem hiding this comment.
@jonathanpeppers would you mind helping me setup some E2E test for android so we can have something to catch issues/regressions? I am all good with having it as a follow-up.
Evangelink
left a comment
There was a problem hiding this comment.
I'm moving forward with a merge, please keep raising issues/PR if you face other problems. I renew my request for some E2E test :)
Thank you!
@Evangelink I wouldn't recommend doing it here, just because booting Android emulators are pretty flaky. We do have an end-to-end test in the Android repo where I found this. Are the packages here pushed to Maestro/darc? The dotnet/android repo could consume builds weekly (maybe not daily), and that would be pretty easy to setup. |
|
Yes, look at the |
|
Ok, I see MSTest 4.3.0-preview.26224.2 on the ".NET Core Tooling Dev" darc channel, "test-tools" NuGet feed. I'll give it a try. |
|
This will let me dogfood the fix here as well, thanks: |
Continuation of #7772.
On .NET for Android,
Assembly.Locationreturns a relative path like"AndroidTest1.dll"(MonoVM) or an empty string (CoreCLR).Path.GetDirectoryNamereturns""for these inputs, and thenDirectory.CreateDirectory("")throwsArgumentException.This would fail in Release mode on Android, or if the "fast deployment" feature is disabled.
Guard against empty/relative paths by checking the result of
Path.GetDirectoryNameand falling back to the standardRootDeploymentDirectory/Outpath.Full stack trace from AZDO build
(https://dev.azure.com/dnceng-public/public/_build/results?buildId=1392743):
Related: dotnet/android#11195 (random PR I saw this), #7769
/cc @nohwnd