From 2237b0bea2de0b35117bc151e2188d8bbf9433f0 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 10 Aug 2021 18:16:16 -0700 Subject: [PATCH 1/3] Add a new shadowcopy test --- .../IIS.FunctionalTests/ShadowCopyTests.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs index 1a449c9bf991..d0a04906223c 100644 --- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs @@ -172,6 +172,42 @@ public async Task ShadowCopyE2EWorksWithFolderPresent() Assert.True(response.IsSuccessStatusCode); } + [ConditionalFact] + public async Task ShadowCopyE2EWorksWithOldFoldersPresent() + { + using var directory = TempDirectory.Create(); + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + deploymentParameters.HandlerSettings["experimentalEnableShadowCopy"] = "true"; + deploymentParameters.HandlerSettings["shadowCopyDirectory"] = directory.DirectoryPath; + var deploymentResult = await DeployAsync(deploymentParameters); + + // Start with 1 to exercise the incremental logic + DirectoryCopy(deploymentResult.ContentRoot, Path.Combine(directory.DirectoryPath, "1"), copySubDirs: true); + + var response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.True(response.IsSuccessStatusCode); + + using var secondTempDir = TempDirectory.Create(); + + // copy back and forth to cause file change notifications. + DirectoryCopy(deploymentResult.ContentRoot, secondTempDir.DirectoryPath, copySubDirs: true); + DirectoryCopy(secondTempDir.DirectoryPath, deploymentResult.ContentRoot, copySubDirs: true); + + response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "0")), "Expected 0 shadow copy directory to be skipped"); + + Assert.False(response.IsSuccessStatusCode); + Assert.Equal("Application Shutting Down", response.ReasonPhrase); + + // This shutdown should trigger a copy to the next highest directory, which will be 2 + await deploymentResult.AssertRecycledAsync(); + + Assert.True(Directory.Exists(Path.Combine(directory.DirectoryPath, "2")), "Expected 2 shadow copy directory"); + + response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.True(response.IsSuccessStatusCode); + } + [ConditionalFact] [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H2, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task ShadowCopyIgnoresItsOwnDirectoryWithRelativePathSegmentWhenCopying() From f329d9798681c39f36e5a9b1e6c7155ef99b4e19 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 10 Aug 2021 18:25:55 -0700 Subject: [PATCH 2/3] Add cleanup variant --- .../IIS.FunctionalTests/ShadowCopyTests.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs index d0a04906223c..917d008124d8 100644 --- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs @@ -208,6 +208,49 @@ public async Task ShadowCopyE2EWorksWithOldFoldersPresent() Assert.True(response.IsSuccessStatusCode); } + [ConditionalFact] + public async Task ShadowCopyCleansUpOlderFolders() + { + using var directory = TempDirectory.Create(); + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + deploymentParameters.HandlerSettings["experimentalEnableShadowCopy"] = "true"; + deploymentParameters.HandlerSettings["shadowCopyDirectory"] = directory.DirectoryPath; + var deploymentResult = await DeployAsync(deploymentParameters); + + // Start with a bunch of junk + DirectoryCopy(deploymentResult.ContentRoot, Path.Combine(directory.DirectoryPath, "1"), copySubDirs: true); + DirectoryCopy(deploymentResult.ContentRoot, Path.Combine(directory.DirectoryPath, "3"), copySubDirs: true); + DirectoryCopy(deploymentResult.ContentRoot, Path.Combine(directory.DirectoryPath, "10"), copySubDirs: true); + + var response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.True(response.IsSuccessStatusCode); + + using var secondTempDir = TempDirectory.Create(); + + // copy back and forth to cause file change notifications. + DirectoryCopy(deploymentResult.ContentRoot, secondTempDir.DirectoryPath, copySubDirs: true); + DirectoryCopy(secondTempDir.DirectoryPath, deploymentResult.ContentRoot, copySubDirs: true); + + response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "0")), "Expected 0 shadow copy directory to be skipped"); + + Assert.False(response.IsSuccessStatusCode); + Assert.Equal("Application Shutting Down", response.ReasonPhrase); + + // This shutdown should trigger a copy to the next highest directory, which will be 11 + await deploymentResult.AssertRecycledAsync(); + + Assert.True(Directory.Exists(Path.Combine(directory.DirectoryPath, "11")), "Expected 11 shadow copy directory"); + + response = await deploymentResult.HttpClient.GetAsync("Wow!"); + Assert.True(response.IsSuccessStatusCode); + + // Verify old directories were cleaned up + Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "1")), "Expected 1 shadow copy directory to be deleted"); + Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "3")), "Expected 3 shadow copy directory to be deleted"); + } + + [ConditionalFact] [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H2, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task ShadowCopyIgnoresItsOwnDirectoryWithRelativePathSegmentWhenCopying() From d2cf0e086861fea29c5bdf03702ec0a7e2546804 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 11 Aug 2021 13:11:18 -0700 Subject: [PATCH 3/3] Handle more situations --- .../test/IIS.FunctionalTests/ShadowCopyTests.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs index 917d008124d8..375bf607eaed 100644 --- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs @@ -196,8 +196,11 @@ public async Task ShadowCopyE2EWorksWithOldFoldersPresent() response = await deploymentResult.HttpClient.GetAsync("Wow!"); Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "0")), "Expected 0 shadow copy directory to be skipped"); - Assert.False(response.IsSuccessStatusCode); - Assert.Equal("Application Shutting Down", response.ReasonPhrase); + // Depending on timing, this could result in a shutdown failure, but sometimes it succeeds, handle both situations + if (!response.IsSuccessStatusCode) + { + Assert.Equal("Application Shutting Down", response.ReasonPhrase); + } // This shutdown should trigger a copy to the next highest directory, which will be 2 await deploymentResult.AssertRecycledAsync(); @@ -234,8 +237,11 @@ public async Task ShadowCopyCleansUpOlderFolders() response = await deploymentResult.HttpClient.GetAsync("Wow!"); Assert.False(Directory.Exists(Path.Combine(directory.DirectoryPath, "0")), "Expected 0 shadow copy directory to be skipped"); - Assert.False(response.IsSuccessStatusCode); - Assert.Equal("Application Shutting Down", response.ReasonPhrase); + // Depending on timing, this could result in a shutdown failure, but sometimes it succeeds, handle both situations + if (!response.IsSuccessStatusCode) + { + Assert.Equal("Application Shutting Down", response.ReasonPhrase); + } // This shutdown should trigger a copy to the next highest directory, which will be 11 await deploymentResult.AssertRecycledAsync();