GivenDotnetWorkloadUninstall.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. using ManifestReaderTests;
  4. using Microsoft.DotNet.Cli.NuGetPackageDownloader;
  5. using Microsoft.DotNet.Cli.Utils;
  6. using Microsoft.DotNet.Cli.Workload.Install.Tests;
  7. using Microsoft.DotNet.Workloads.Workload;
  8. using Microsoft.DotNet.Workloads.Workload.Install;
  9. using Microsoft.DotNet.Workloads.Workload.Uninstall;
  10. using Microsoft.NET.Sdk.WorkloadManifestReader;
  11. namespace Microsoft.DotNet.Cli.Workload.Uninstall.Tests
  12. {
  13. public class GivenDotnetWorkloadUninstall : SdkTest
  14. {
  15. private readonly BufferedReporter _reporter;
  16. private readonly string _manifestPath;
  17. private string SetUpMockWorkloadToUninstall(string fakeWorkloadNameToInstall, string sdkFeatureVersion, string testDirectory, bool userLocal)
  18. {
  19. var dotnetRoot = Path.Combine(testDirectory, "dotnet");
  20. var userProfileDir = Path.Combine(testDirectory, "user-profile");
  21. string installRoot = userLocal ? userProfileDir : dotnetRoot;
  22. if (userLocal)
  23. {
  24. WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion);
  25. }
  26. InstallWorkload(fakeWorkloadNameToInstall, testDirectory, sdkFeatureVersion);
  27. // Assert install was successful
  28. var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  29. installPacks.Count().Should().Be(2);
  30. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", fakeWorkloadNameToInstall))
  31. .Should().BeTrue();
  32. var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  33. packRecordDirs.Count().Should().Be(3);
  34. return installRoot;
  35. }
  36. public GivenDotnetWorkloadUninstall(ITestOutputHelper log) : base(log)
  37. {
  38. _reporter = new BufferedReporter();
  39. _manifestPath = Path.Combine(_testAssetsManager.GetAndValidateTestProjectDirectory("SampleManifest"), "MockWorkloadsSample.json");
  40. }
  41. [Fact]
  42. public void GivenWorkloadUninstallItErrorsWhenWorkloadIsNotInstalled()
  43. {
  44. var testDirectory = _testAssetsManager.CreateTestDirectory().Path;
  45. var exceptionThrown = Assert.Throws<GracefulException>(() => UninstallWorkload("mock-1", testDirectory, "6.0.100"));
  46. exceptionThrown.Message.Should().Contain("mock-1");
  47. }
  48. [Theory]
  49. [InlineData(true)]
  50. [InlineData(false)]
  51. public void GivenWorkloadUninstallItCanUninstallWorkload(bool userLocal)
  52. {
  53. var installingWorkload = "mock-1";
  54. var sdkFeatureVersion = "6.0.100";
  55. var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path;
  56. var installRoot = SetUpMockWorkloadToUninstall(installingWorkload, sdkFeatureVersion, testDirectory, userLocal);
  57. UninstallWorkload(installingWorkload, testDirectory, sdkFeatureVersion);
  58. // Assert uninstall was successful
  59. var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  60. installPacks.Count().Should().Be(0);
  61. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload))
  62. .Should().BeFalse();
  63. var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  64. packRecordDirs.Count().Should().Be(0);
  65. }
  66. [Fact]
  67. public void GivenWorkloadUninstallItWorksWithVerbosityFlag()
  68. {
  69. bool userLocal = true; // The locality doesnt really matter as we just want to make sure the flag(s) are supported.
  70. var installingWorkload = "mock-1";
  71. var sdkFeatureVersion = "6.0.100";
  72. var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path;
  73. SetUpMockWorkloadToUninstall(installingWorkload, sdkFeatureVersion, testDirectory, userLocal);
  74. string[] args = { "--verbosity", "diag" };
  75. var exitCode = UninstallWorkload(installingWorkload, testDirectory, sdkFeatureVersion, args);
  76. exitCode.Should().Be(0, "The exit code of workload uninstall should be 0 to indicate success when the flag was added.");
  77. }
  78. [Theory]
  79. [InlineData(true)]
  80. [InlineData(false)]
  81. public void GivenWorkloadUninstallItCanUninstallOnlySpecifiedWorkload(bool userLocal)
  82. {
  83. var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path;
  84. var dotnetRoot = Path.Combine(testDirectory, "dotnet");
  85. var userProfileDir = Path.Combine(testDirectory, "user-profile");
  86. var sdkFeatureVersion = "6.0.100";
  87. var installedWorkload = "mock-1";
  88. var uninstallingWorkload = "mock-2";
  89. string installRoot = userLocal ? userProfileDir : dotnetRoot;
  90. if (userLocal)
  91. {
  92. WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion);
  93. }
  94. InstallWorkload(installedWorkload, testDirectory, sdkFeatureVersion);
  95. InstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion);
  96. // Assert installs were successful
  97. var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  98. installPacks.Count().Should().Be(3);
  99. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installedWorkload))
  100. .Should().BeTrue();
  101. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  102. .Should().BeTrue();
  103. var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  104. packRecordDirs.Count().Should().Be(4);
  105. UninstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion);
  106. // Assert uninstall was successful, other workload is still installed
  107. installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  108. installPacks.Count().Should().Be(2);
  109. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  110. .Should().BeFalse();
  111. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installedWorkload))
  112. .Should().BeTrue();
  113. packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  114. packRecordDirs.Count().Should().Be(3);
  115. }
  116. [Theory]
  117. [InlineData(true)]
  118. [InlineData(false)]
  119. public void GivenWorkloadUninstallItCanUninstallOnlySpecifiedFeatureBand(bool userLocal)
  120. {
  121. var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path;
  122. var dotnetRoot = Path.Combine(testDirectory, "dotnet");
  123. var userProfileDir = Path.Combine(testDirectory, "user-profile");
  124. var prevSdkFeatureVersion = "5.0.100";
  125. var sdkFeatureVersion = "6.0.100";
  126. var uninstallingWorkload = "mock-1";
  127. static void CreateFile(string path)
  128. {
  129. string directory = Path.GetDirectoryName(path);
  130. Directory.CreateDirectory(directory);
  131. using var _ = File.Create(path);
  132. }
  133. // Create fake SDK directories (so garbage collector will see them as installed versions)
  134. CreateFile(Path.Combine(dotnetRoot, "sdk", prevSdkFeatureVersion, "dotnet.dll"));
  135. CreateFile(Path.Combine(dotnetRoot, "sdk", sdkFeatureVersion, "dotnet.dll"));
  136. string installRoot = userLocal ? userProfileDir : dotnetRoot;
  137. if (userLocal)
  138. {
  139. WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion);
  140. WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, prevSdkFeatureVersion);
  141. }
  142. InstallWorkload(uninstallingWorkload, testDirectory, prevSdkFeatureVersion);
  143. InstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion);
  144. // Assert installs were successful
  145. var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  146. installPacks.Count().Should().Be(2);
  147. File.Exists(Path.Combine(installRoot, "metadata", "workloads", prevSdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  148. .Should().BeTrue();
  149. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  150. .Should().BeTrue();
  151. var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  152. packRecordDirs.Count().Should().Be(3);
  153. var featureBandMarkerFiles = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"))
  154. .SelectMany(packIdDirs => Directory.GetDirectories(packIdDirs))
  155. .SelectMany(packVersionDirs => Directory.GetFiles(packVersionDirs));
  156. featureBandMarkerFiles.Count().Should().Be(6); // 3 packs x 2 feature bands
  157. UninstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion);
  158. // Assert uninstall was successful, other workload is still installed
  159. installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs"));
  160. installPacks.Count().Should().Be(2);
  161. File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  162. .Should().BeFalse();
  163. File.Exists(Path.Combine(installRoot, "metadata", "workloads", prevSdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload))
  164. .Should().BeTrue();
  165. packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"));
  166. packRecordDirs.Count().Should().Be(3);
  167. }
  168. private void InstallWorkload(string installingWorkload, string testDirectory, string sdkFeatureVersion)
  169. {
  170. var dotnetRoot = Path.Combine(testDirectory, "dotnet");
  171. var userProfileDir = Path.Combine(testDirectory, "user-profile");
  172. bool userLocal = WorkloadFileBasedInstall.IsUserLocal(dotnetRoot, sdkFeatureVersion);
  173. var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir);
  174. var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot);
  175. var manifestUpdater = new MockWorkloadManifestUpdater();
  176. var installParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "install", installingWorkload });
  177. var workloadResolverFactory = new MockWorkloadResolverFactory(dotnetRoot, sdkFeatureVersion, workloadResolver, userProfileDir);
  178. var installCommand = new WorkloadInstallCommand(installParseResult, reporter: _reporter, workloadResolverFactory, nugetPackageDownloader: nugetDownloader,
  179. workloadManifestUpdater: manifestUpdater, tempDirPath: testDirectory);
  180. installCommand.Execute();
  181. }
  182. private int UninstallWorkload(string uninstallingWorkload, string testDirectory, string sdkFeatureVersion, string[] args = null)
  183. {
  184. var dotnetRoot = Path.Combine(testDirectory, "dotnet");
  185. var userProfileDir = Path.Combine(testDirectory, "user-profile");
  186. bool userLocal = WorkloadFileBasedInstall.IsUserLocal(dotnetRoot, sdkFeatureVersion);
  187. var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir);
  188. var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot);
  189. var command = new List<string> { "dotnet", "workload", "uninstall", uninstallingWorkload };
  190. if (args != null)
  191. {
  192. command.AddRange(args);
  193. }
  194. var uninstallParseResult = Parser.Instance.Parse(command);
  195. var workloadResolverFactory = new MockWorkloadResolverFactory(dotnetRoot, sdkFeatureVersion, workloadResolver, userProfileDir);
  196. var uninstallCommand = new WorkloadUninstallCommand(uninstallParseResult, reporter: _reporter, workloadResolverFactory, nugetDownloader);
  197. return uninstallCommand.Execute();
  198. }
  199. }
  200. }