From 5e05c2f472d53302757707cbe7df67ad3d500045 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Oct 2026 20:29:26 +0000 Subject: [PATCH 1/3] Initial plan From 3f13b7b710e803553d25b1dcbc9a2552920e9a25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Oct 2026 20:51:21 +0000 Subject: [PATCH 2/3] Isolate subdirectory bundle test extraction from shared caches Co-authored-by: agocke <515774+agocke@users.noreply.github.com> --- .../AppHost.Bundle.Tests/BundledAppWithSubDirs.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs b/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs index 6f20384803e142..e63d5bb7c6a194 100644 --- a/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs +++ b/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs @@ -25,6 +25,7 @@ private FluentAssertions.AndConstraint RunTheApp(string CommandResult result = Command.Create(path) .EnableTracingAndCaptureOutputs() .DotNetRoot(selfContained ? null : HostTestContext.BuiltDotNet.BinPath) + .EnvironmentVariable(Constants.BundleExtractBase.EnvironmentVariable, Path.Combine(Path.GetDirectoryName(path), "extract")) .Execute(); if (deleteApp) { @@ -64,7 +65,7 @@ private static void DeleteExtractionDirectory(CommandResult result) [InlineData(BundleOptions.BundleAllContent)] public void FrameworkDependent(BundleOptions options) { - var singleFile = sharedTestState.FrameworkDependentApp.Bundle(options); + var singleFile = sharedTestState.FrameworkDependentApp.Bundle(options, out Manifest manifest); // Run the bundled app bool shouldExtract = options.HasFlag(BundleOptions.BundleAllContent); @@ -73,6 +74,10 @@ public void FrameworkDependent(BundleOptions options) if (shouldExtract) { + sharedTestState.FrameworkDependentApp + .GetExtractionDir(Path.Combine(Path.GetDirectoryName(singleFile), "extract"), manifest) + .Should().Exist(); + // Run the bundled app again (reuse extracted files) RunTheApp(singleFile, selfContained: false) .And.ReuseExtraction(); @@ -86,7 +91,7 @@ public void FrameworkDependent(BundleOptions options) [InlineData(BundleOptions.BundleAllContent | BundleOptions.EnableCompression)] public void SelfContained(BundleOptions options) { - var singleFile = sharedTestState.SelfContainedApp.Bundle(options); + var singleFile = sharedTestState.SelfContainedApp.Bundle(options, out Manifest manifest); // Run the bundled app bool shouldExtract = options.HasFlag(BundleOptions.BundleAllContent); @@ -95,6 +100,10 @@ public void SelfContained(BundleOptions options) if (shouldExtract) { + sharedTestState.SelfContainedApp + .GetExtractionDir(Path.Combine(Path.GetDirectoryName(singleFile), "extract"), manifest) + .Should().Exist(); + // Run the bundled app again (reuse extracted files) RunTheApp(singleFile, selfContained: true) .And.ReuseExtraction(); From f1f575f3a3968f4e016a7a9038f238d1f8b752e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Oct 2026 20:56:48 +0000 Subject: [PATCH 3/3] Preserve long Windows paths for isolated bundle extraction Co-authored-by: agocke <515774+agocke@users.noreply.github.com> --- .../BundledAppWithSubDirs.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs b/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs index e63d5bb7c6a194..7acfba3aaaee2f 100644 --- a/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs +++ b/src/installer/tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs @@ -25,7 +25,7 @@ private FluentAssertions.AndConstraint RunTheApp(string CommandResult result = Command.Create(path) .EnableTracingAndCaptureOutputs() .DotNetRoot(selfContained ? null : HostTestContext.BuiltDotNet.BinPath) - .EnvironmentVariable(Constants.BundleExtractBase.EnvironmentVariable, Path.Combine(Path.GetDirectoryName(path), "extract")) + .EnvironmentVariable(Constants.BundleExtractBase.EnvironmentVariable, GetExtractionRootPath(path)) .Execute(); if (deleteApp) { @@ -40,6 +40,20 @@ private FluentAssertions.AndConstraint RunTheApp(string .And.HaveStdOutContaining("Wow! We now say hello to the big world and you."); } + private static string GetExtractionRootPath(string path) + { + string extractionRoot = Path.Combine(Path.GetDirectoryName(path), "extract"); + // Native extraction must support the long-name content even when the test artifact path exceeds MAX_PATH. + if (OperatingSystem.IsWindows() && !extractionRoot.StartsWith(@"\\?\", StringComparison.Ordinal)) + { + extractionRoot = extractionRoot.StartsWith(@"\\", StringComparison.Ordinal) + ? @"\\?\UNC\" + extractionRoot[2..] + : @"\\?\" + extractionRoot; + } + + return extractionRoot; + } + private static void DeleteExtractionDirectory(CommandResult result) { Assert.False(string.IsNullOrEmpty(result.StdErr), "Attempted to get extraction directory from empty stderr. Ensure tracing was enabled and stderr captured."); @@ -75,7 +89,7 @@ public void FrameworkDependent(BundleOptions options) if (shouldExtract) { sharedTestState.FrameworkDependentApp - .GetExtractionDir(Path.Combine(Path.GetDirectoryName(singleFile), "extract"), manifest) + .GetExtractionDir(GetExtractionRootPath(singleFile), manifest) .Should().Exist(); // Run the bundled app again (reuse extracted files) @@ -101,7 +115,7 @@ public void SelfContained(BundleOptions options) if (shouldExtract) { sharedTestState.SelfContainedApp - .GetExtractionDir(Path.Combine(Path.GetDirectoryName(singleFile), "extract"), manifest) + .GetExtractionDir(GetExtractionRootPath(singleFile), manifest) .Should().Exist(); // Run the bundled app again (reuse extracted files)