From 1c9f1d26afc54f5d9fe834345042ae75c835cf2d Mon Sep 17 00:00:00 2001 From: Hao Kung <HaoK@users.noreply.github.com> Date: Wed, 11 Aug 2021 16:45:26 -0700 Subject: [PATCH] Add a new shadowcopy test (#35249) --- .../IIS.FunctionalTests/ShadowCopyTests.cs | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs index 1a449c9bf99..375bf607eae 100644 --- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/ShadowCopyTests.cs @@ -172,6 +172,91 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests 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"); + + // 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(); + + 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] + 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"); + + // 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(); + + 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() -- GitLab