diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs index 0f5960faefa79..897408f0a3647 100644 --- a/src/installer/tests/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs +++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs @@ -201,17 +201,58 @@ private void Bundle_extraction_can_recover_missing_files() extractDir.Should().HaveFiles(extractedFiles); } + [Fact] + private void Bundle_extraction_to_nonexisting_default() + { + string nonExistentPath = Path.Combine( + sharedTestState.DefaultBundledAppFixture.TestProject.OutputDirectory, + "nonexistent"); + + string defaultExpansionEnvVariable = OperatingSystem.IsWindows() ? "TMP" : "HOME"; + string expectedErrorMessagePart = OperatingSystem.IsWindows() ? + $"Failed to determine default extraction location. Check if 'TMP'" : + $"Default extraction directory [{nonExistentPath}] either doesn't exist or is not accessible for read/write."; + + Command.Create(sharedTestState.DefaultBundledAppExecutablePath) + .CaptureStdErr() + .CaptureStdOut() + .EnvironmentVariable(defaultExpansionEnvVariable, nonExistentPath) + .Execute().Should().Fail() + .And.HaveStdErrContaining(expectedErrorMessagePart); + } + + [Fact] + [SkipOnPlatform(TestPlatforms.Windows, "On Windows the default extraction path is determined by calling GetTempPath which looks at multiple places and can't really be undefined.")] + private void Bundle_extraction_default_undefined() + { + Command.Create(sharedTestState.DefaultBundledAppExecutablePath) + .CaptureStdErr() + .CaptureStdOut() + .EnvironmentVariable("HOME", null) + .Execute().Should().Fail() + .And.HaveStdErrContaining("Failed to determine default extraction location. Environment variable '$HOME' is not defined."); + } + public class SharedTestState : SharedTestStateBase, IDisposable { - public TestProjectFixture TestFixture { get; set; } + public TestProjectFixture TestFixture { get; } + + public TestProjectFixture DefaultBundledAppFixture { get; } + public string DefaultBundledAppExecutablePath { get; } + public Bundler DefaultBundledAppBundler { get; } public SharedTestState() { TestFixture = PreparePublishedSelfContainedTestProject("StandaloneApp"); + + DefaultBundledAppFixture = TestFixture.Copy(); + DefaultBundledAppBundler = BundleSelfContainedApp(DefaultBundledAppFixture, out var singleFile, BundleOptions.BundleNativeBinaries); + DefaultBundledAppExecutablePath = singleFile; } public void Dispose() { + DefaultBundledAppFixture.Dispose(); TestFixture.Dispose(); } } diff --git a/src/native/corehost/hostmisc/pal.unix.cpp b/src/native/corehost/hostmisc/pal.unix.cpp index ef644bdf0d7a3..6f247f096cc99 100644 --- a/src/native/corehost/hostmisc/pal.unix.cpp +++ b/src/native/corehost/hostmisc/pal.unix.cpp @@ -341,7 +341,18 @@ bool get_extraction_base_parent_directory(pal::string_t& directory) // check for the POSIX standard environment variable if (pal::getenv(_X("HOME"), &directory)) { - return is_read_write_able_directory(directory); + if (is_read_write_able_directory(directory)) + { + return true; + } + else + { + trace::error(_X("Default extraction directory [%s] either doesn't exist or is not accessible for read/write."), directory.c_str()); + } + } + else + { + trace::error(_X("Failed to determine default extraction location. Environment variable '$HOME' is not defined.")); } return false; @@ -367,6 +378,7 @@ bool pal::get_default_bundle_extraction_base_dir(pal::string_t& extraction_dir) } else if (errno != EEXIST) { + trace::error(_X("Failed to create default extraction directory [%s]. %s"), extraction_dir.c_str(), pal::strerror(errno)); return false; } diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index 2a964f06868e7..e50ebdc9313d0 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -573,6 +573,7 @@ bool pal::get_default_bundle_extraction_base_dir(pal::string_t& extraction_dir) { if (!get_extraction_base_parent_directory(extraction_dir)) { + trace::error(_X("Failed to determine default extraction location. Check if 'TMP' or 'TEMP' points to existing path.")); return false; } @@ -588,6 +589,7 @@ bool pal::get_default_bundle_extraction_base_dir(pal::string_t& extraction_dir) if (CreateDirectoryW(extraction_dir.c_str(), NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS) { + trace::error(_X("Failed to create default extraction directory [%s]. %s, error code: %d"), extraction_dir.c_str(), pal::strerror(errno), GetLastError()); return false; }