From 9061e0a42f2940d87981ca9931b55d289177ee78 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 18 Sep 2023 20:46:03 -0400 Subject: [PATCH 1/4] Refactor workload garbage collection tests, add test for side-by-side manifest collection --- .../TestProjects/SampleManifest/Sample2.json | 4 +- .../SampleManifest/Sample2_v2.json | 82 +++++ .../SampleManifest/Sample2_v3.json | 82 +++++ .../GivenFileBasedWorkloadInstall.cs | 101 +----- .../WorkloadGarbageCollectionTests.cs | 317 ++++++++++++++++++ 5 files changed, 486 insertions(+), 100 deletions(-) create mode 100644 src/Assets/TestProjects/SampleManifest/Sample2_v2.json create mode 100644 src/Assets/TestProjects/SampleManifest/Sample2_v3.json create mode 100644 src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs diff --git a/src/Assets/TestProjects/SampleManifest/Sample2.json b/src/Assets/TestProjects/SampleManifest/Sample2.json index ee8cc0b7a84f..c0d8578f2146 100644 --- a/src/Assets/TestProjects/SampleManifest/Sample2.json +++ b/src/Assets/TestProjects/SampleManifest/Sample2.json @@ -1,5 +1,5 @@ { - "version": "5.0.0-preview1", + "version": "1.0.0", "workloads": { "xamarin-android": { "description": "Create, build and run Android apps", @@ -58,7 +58,7 @@ "version": "8.4.0" }, "Xamarin.Android.Runtime": { - "kind": "framework", + "kind": "library", "version": "8.4.7.4" }, "Xamarin.Android.BuildTools": { diff --git a/src/Assets/TestProjects/SampleManifest/Sample2_v2.json b/src/Assets/TestProjects/SampleManifest/Sample2_v2.json new file mode 100644 index 000000000000..5ea2c44d96bf --- /dev/null +++ b/src/Assets/TestProjects/SampleManifest/Sample2_v2.json @@ -0,0 +1,82 @@ +{ + "version": "2.0.0", + "workloads": { + "xamarin-android": { + "description": "Create, build and run Android apps", + "kind": "dev", + "packs": [ + "Xamarin.Android.Templates" + ], + "extends": [ + "xamarin-android-build" + ] + }, + "xamarin-android-build": { + "description": "Build and run Android apps", + "packs": [ + "Xamarin.Android.Sdk", + "Xamarin.Android.Framework", + "Xamarin.Android.Runtime" + ] + }, + "android-sdk-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.Sdk" + ] + }, + "android-templates-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.Templates" + ] + }, + "android-buildtools-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.BuildTools" + ] + }, + "xamarin-empty-mock": { + "description": "Empty mock workload for testing", + "kind": "dev", + "packs": [], + "extends": [] + } + }, + "packs": { + "Xamarin.Android.Sdk": { + "kind": "sdk", + "version": "8.4.7" + }, + "Xamarin.Android.Templates": { + "kind": "template", + "version": "1.1.0" + }, + "Xamarin.Android.Framework": { + "kind": "framework", + "version": "8.5.0" + }, + "Xamarin.Android.Runtime": { + "kind": "library", + "version": "8.5.0.1" + }, + "Xamarin.Android.BuildTools": { + "version": "8.5.0", + "kind": "sdk", + "alias-to": { + "osx": "Xamarin.Android.BuildTools.MacHost", + "win": "Xamarin.Android.BuildTools.WinHost", + "linux": "Xamarin.Android.BuildTools.LinuxHost" + } + }, + "Test.Pack.A": { + "version": "1.0.0", + "kind": "sdk" + }, + "Test.Pack.B": { + "version": "2.0.0", + "kind": "framework" + } + } +} diff --git a/src/Assets/TestProjects/SampleManifest/Sample2_v3.json b/src/Assets/TestProjects/SampleManifest/Sample2_v3.json new file mode 100644 index 000000000000..b12995ea4c8c --- /dev/null +++ b/src/Assets/TestProjects/SampleManifest/Sample2_v3.json @@ -0,0 +1,82 @@ +{ + "version": "3.0.0", + "workloads": { + "xamarin-android": { + "description": "Create, build and run Android apps", + "kind": "dev", + "packs": [ + "Xamarin.Android.Templates" + ], + "extends": [ + "xamarin-android-build" + ] + }, + "xamarin-android-build": { + "description": "Build and run Android apps", + "packs": [ + "Xamarin.Android.Sdk", + "Xamarin.Android.Framework", + "Xamarin.Android.Runtime" + ] + }, + "android-sdk-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.Sdk" + ] + }, + "android-templates-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.Templates" + ] + }, + "android-buildtools-workload":{ + "description": "Test workload", + "packs": [ + "Xamarin.Android.BuildTools" + ] + }, + "xamarin-empty-mock": { + "description": "Empty mock workload for testing", + "kind": "dev", + "packs": [], + "extends": [] + } + }, + "packs": { + "Xamarin.Android.Sdk": { + "kind": "sdk", + "version": "8.4.7" + }, + "Xamarin.Android.Templates": { + "kind": "template", + "version": "1.2.0" + }, + "Xamarin.Android.Framework": { + "kind": "framework", + "version": "8.6.0" + }, + "Xamarin.Android.Runtime": { + "kind": "library", + "version": "8.6.0.0" + }, + "Xamarin.Android.BuildTools": { + "version": "8.6.0", + "kind": "sdk", + "alias-to": { + "osx": "Xamarin.Android.BuildTools.MacHost", + "win": "Xamarin.Android.BuildTools.WinHost", + "linux": "Xamarin.Android.BuildTools.LinuxHost" + } + }, + "Test.Pack.A": { + "version": "1.0.0", + "kind": "sdk" + }, + "Test.Pack.B": { + "version": "2.0.0", + "kind": "framework" + } + } +} diff --git a/src/Tests/dotnet-workload-install.Tests/GivenFileBasedWorkloadInstall.cs b/src/Tests/dotnet-workload-install.Tests/GivenFileBasedWorkloadInstall.cs index 64820fc7cc8e..3a98644e69ee 100644 --- a/src/Tests/dotnet-workload-install.Tests/GivenFileBasedWorkloadInstall.cs +++ b/src/Tests/dotnet-workload-install.Tests/GivenFileBasedWorkloadInstall.cs @@ -220,101 +220,6 @@ public void GivenManagedInstallItCanRollBackInstallFailures() Directory.Exists(Path.Combine(dotnetRoot, "packs", packId, packVersion)).Should().BeFalse(); } - [Fact] - public void GivenManagedInstallItCanGarbageCollect() - { - var (dotnetRoot, installer, _, getResolver) = GetTestInstaller(); - var packs = new PackInfo[] - { - CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Library, Path.Combine(dotnetRoot, "library-packs", "Xamarin.Android.Sdk.8.4.7.nupkg"), "Xamarin.Android.Sdk"), - CreatePackInfo("Xamarin.Android.Framework", "8.4.0", WorkloadPackKind.Framework, Path.Combine(dotnetRoot, "packs", "Xamarin.Android.Framework", "8.4.0"), "Xamarin.Android.Framework") - }; - var sdkVersions = new WorkloadId[] { new WorkloadId("6.0.100"), new WorkloadId("6.0.300") }; - - // Write fake packs - var installedPacksPath = Path.Combine(dotnetRoot, "metadata", "workloads", "InstalledPacks", "v1"); - foreach (var sdkVersion in sdkVersions) - { - foreach (var pack in packs) - { - var packRecordPath = Path.Combine(installedPacksPath, pack.Id, pack.Version, sdkVersion); - Directory.CreateDirectory(Path.GetDirectoryName(packRecordPath)); - var packRecordContents = JsonSerializer.Serialize(pack); - File.WriteAllText(packRecordPath, packRecordContents); - if (pack.Kind == WorkloadPackKind.Library) - { - Directory.CreateDirectory(Path.GetDirectoryName(pack.Path)); - using var _ = File.Create(pack.Path); - } - else - { - Directory.CreateDirectory(pack.Path); - } - } - } - // Write fake install record for 6.0.300 - var workloadsRecordPath = Path.Combine(dotnetRoot, "metadata", "workloads", sdkVersions[1], "InstalledWorkloads"); - Directory.CreateDirectory(workloadsRecordPath); - File.Create(Path.Combine(workloadsRecordPath, "xamarin-empty-mock")); - - installer.GarbageCollect(getResolver); - - Directory.EnumerateFileSystemEntries(installedPacksPath) - .Should() - .BeEmpty(); - foreach (var pack in packs) - { - if (pack.Kind == WorkloadPackKind.Library) - { - File.Exists(pack.Path).Should().BeFalse(); - } - else - { - Directory.Exists(pack.Path) - .Should() - .BeFalse(); - } - } - } - - [Fact] - public void GivenManagedInstallItCanGarbageCollectPacksMissingFromManifest() - { - var (dotnetRoot, installer, _, getResolver) = GetTestInstaller(); - // Define packs that don't show up in the manifest - var packs = new PackInfo[] - { - CreatePackInfo("Xamarin.Android.Sdk.fake", "8.4.7", WorkloadPackKind.Framework, Path.Combine(dotnetRoot, "packs", "Xamarin.Android.Sdk.fake", "8.4.7"), "Xamarin.Android.Sdk.fake"), - CreatePackInfo("Xamarin.Android.Framework.mock", "8.4", WorkloadPackKind.Framework, Path.Combine(dotnetRoot, "packs", "Xamarin.Android.Framework.mock", "8.4"), "Xamarin.Android.Framework.mock") - }; - var sdkVersions = new WorkloadId[] { new WorkloadId("6.0.100"), new WorkloadId("6.0.300") }; - - // Write fake packs - var installedPacksPath = Path.Combine(dotnetRoot, "metadata", "workloads", "InstalledPacks", "v1"); - foreach (var sdkVersion in sdkVersions) - { - foreach (var pack in packs) - { - var packRecordPath = Path.Combine(installedPacksPath, pack.Id, pack.Version, sdkVersion); - Directory.CreateDirectory(Path.GetDirectoryName(packRecordPath)); - File.WriteAllText(packRecordPath, JsonSerializer.Serialize(pack)); - Directory.CreateDirectory(pack.Path); - } - } - - installer.GarbageCollect(getResolver); - - Directory.EnumerateFileSystemEntries(installedPacksPath) - .Should() - .BeEmpty(); - foreach (var pack in packs) - { - Directory.Exists(pack.Path) - .Should() - .BeFalse(); - } - } - [Fact] public void GivenManagedInstallItDoesNotRemovePacksWithInstallRecords() { @@ -484,11 +389,11 @@ public void GivenManagedInstallItCanErrorsWhenMissingOfflineCache() var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot); var sdkFeatureBand = new SdkFeatureBand("6.0.300"); - IWorkloadResolver GetResolver(string sdkVersion) + IWorkloadResolver GetResolver(string workloadSetVersion) { - if (sdkVersion != null && !sdkFeatureBand.Equals(new SdkFeatureBand(sdkVersion))) + if (workloadSetVersion != null && !sdkFeatureBand.Equals(new SdkFeatureBand(workloadSetVersion))) { - throw new NotSupportedException("Mock doesn't support creating resolver for different feature bands: " + sdkVersion); + throw new NotSupportedException("Mock doesn't support creating resolver for different feature bands: " + workloadSetVersion); } return workloadResolver; } diff --git a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs new file mode 100644 index 000000000000..fbab3f803f71 --- /dev/null +++ b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs @@ -0,0 +1,317 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using ManifestReaderTests; +using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Workloads.Workload.Install; +using Microsoft.NET.Sdk.WorkloadManifestReader; +using NuGet.Versioning; +using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; +using Microsoft.Extensions.EnvironmentAbstractions; +using System.Text.Json; +using Microsoft.TemplateEngine.Edge.Constraints; + +namespace Microsoft.DotNet.Cli.Workload.Install.Tests +{ + public class WorkloadGarbageCollectionTests : SdkTest + { + private readonly BufferedReporter _reporter; + private string _testDirectory; + private string _dotnetRoot; + + public WorkloadGarbageCollectionTests(ITestOutputHelper log) : base(log) + { + _reporter = new BufferedReporter(); + } + + [Fact] + public void GivenManagedInstallItCanGarbageCollect() + { + CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + + var (installer, getResolver) = GetTestInstaller(); + var packsToKeep = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk), + CreatePackInfo("Xamarin.Android.Framework", "8.5.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.5.0.1", WorkloadPackKind.Library) + }; + + var packsToCollect = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Framework", "8.4.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.4.7.4", WorkloadPackKind.Library) + }; + var sdkVersions = new [] { "6.0.100", "6.0.300" }; + + // Write packs + foreach (var sdkVersion in sdkVersions) + { + foreach (var pack in packsToKeep.Concat(packsToCollect)) + { + CreateInstalledPack(pack, sdkVersion); + } + } + + // Write workload install record for 6.0.300 + var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", sdkVersions[1], "InstalledWorkloads"); + Directory.CreateDirectory(workloadsRecordPath); + File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); + + installer.GarbageCollect(getResolver); + + foreach (var pack in packsToCollect) + { + PackShouldExist(pack, false); + PackRecord(pack, "6.0.100").Should().NotExist(); + PackRecord(pack, "6.0.300").Should().NotExist(); + } + foreach (var pack in packsToKeep) + { + PackShouldExist(pack, true); + PackRecord(pack, "6.0.100").Should().NotExist(); + PackRecord(pack, "6.0.300").Should().Exist(); + } + } + + [Fact] + public void GivenManagedInstallItCanGarbageCollectPacksMissingFromManifest() + { + CreateMockManifest("TestManifest", "1.0.0"); + var (installer, getResolver) = GetTestInstaller(); + // Define packs that don't show up in the manifest + var packs = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Sdk.fake", "8.4.7", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Framework.mock", "8.4", WorkloadPackKind.Framework) + }; + var sdkVersions = new WorkloadId[] { new WorkloadId("6.0.100"), new WorkloadId("6.0.300") }; + + // Write fake packs + var installedPacksPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "InstalledPacks", "v1"); + foreach (var sdkVersion in sdkVersions) + { + foreach (var pack in packs) + { + CreateInstalledPack(pack, sdkVersion); + } + } + + installer.GarbageCollect(getResolver); + + Directory.EnumerateFileSystemEntries(installedPacksPath) + .Should() + .BeEmpty(); + foreach (var pack in packs) + { + PackShouldExist(pack, false); + } + } + + [Fact] + public void GarbageCollectManifests() + { + CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + CreateMockManifest("TestManifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + + CreateManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300"); + CreateManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300"); + + var (installer, getResolver) = GetTestInstaller("6.0.300"); + + var packsToKeep = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk), + CreatePackInfo("Xamarin.Android.Framework", "8.6.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.6.0.0", WorkloadPackKind.Library) + }; + + var packsToCollect = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Framework", "8.4.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.4.7.4", WorkloadPackKind.Library) + }; + + foreach (var pack in packsToKeep.Concat(packsToCollect)) + { + CreateInstalledPack(pack, "6.0.300"); + } + + // Write workload install record for 6.0.300 + var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); + Directory.CreateDirectory(workloadsRecordPath); + File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); + + installer.GarbageCollect(getResolver); + + foreach (var pack in packsToCollect) + { + PackShouldExist(pack, false); + PackRecord(pack, "6.0.300").Should().NotExist(); + } + foreach (var pack in packsToKeep) + { + PackShouldExist(pack, true); + PackRecord(pack, "6.0.300").Should().Exist(); + } + + ManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300").Should().NotExist(); + ManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300").Should().Exist(); + + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "TestManifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "2.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); + } + + // TODO: + // Garbage collect with install state with manifests + // Garbage collect workload sets + // Garbage collect with install state with workload set + // Don't garbage collect baseline workload set + + void PackShouldExist(PackInfo pack, bool shouldExist) + { + if (pack.Kind == WorkloadPackKind.Library) + { + if (shouldExist) + { + new FileInfo(pack.Path).Should().Exist(); + } + else + { + new FileInfo(pack.Path).Should().NotExist(); + } + } + else + { + if (shouldExist) + { + new DirectoryInfo(pack.Path).Should().Exist(); + } + else + { + new DirectoryInfo(pack.Path).Should().NotExist(); + } + } + } + + PackInfo CreatePackInfo(string id, string version, WorkloadPackKind kind, string resolvedPackageId = null) + { + if (resolvedPackageId == null) + { + resolvedPackageId = id; + } + + string path; + if (kind == WorkloadPackKind.Library) + { + path = Path.Combine(_dotnetRoot, "library-packs", $"resolvedPackageId.{version}.nupkg"); + } + else + { + path = Path.Combine(_dotnetRoot, "packs", id, version); + } + + return new PackInfo(new WorkloadPackId(id), version, kind, path, resolvedPackageId); + } + + FileInfo PackRecord(PackInfo pack, string sdkFeatureBand) + { + var installedPacksPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "InstalledPacks", "v1"); + var packRecordPath = Path.Combine(installedPacksPath, pack.Id, pack.Version, sdkFeatureBand); + return new FileInfo(packRecordPath); + } + + + private void CreateInstalledPack(PackInfo pack, string sdkFeatureBand) + { + // Write pack installation record + var packRecordPath = PackRecord(pack, sdkFeatureBand); + Directory.CreateDirectory(Path.GetDirectoryName(packRecordPath.FullName)); + var packRecordContents = JsonSerializer.Serialize(pack); + File.WriteAllText(packRecordPath.FullName, packRecordContents); + + // Create fake pack install + if (pack.Kind == WorkloadPackKind.Library) + { + Directory.CreateDirectory(Path.GetDirectoryName(pack.Path)); + using var _ = File.Create(pack.Path); + } + else + { + Directory.CreateDirectory(pack.Path); + } + } + + private void CreateDotnetRoot([CallerMemberName]string testName = "", string identifier = "") + { + if (_dotnetRoot == null) + { + _testDirectory = _testAssetsManager.CreateTestDirectory(testName, identifier: identifier).Path; + _dotnetRoot = Path.Combine(_testDirectory, "dotnet"); + } + } + + private void CreateMockManifest(string manifestId, string manifestVersion, string featureBand = "6.0.300", bool useVersionFolder = true, + string sourceManifestName = "Sample2.json", [CallerMemberName] string testName = "", string identifier = "") + { + CreateDotnetRoot(testName, identifier); + + var manifestDirectory = Path.Combine(_dotnetRoot, "sdk-manifests", featureBand, manifestId); + if (useVersionFolder) + { + manifestDirectory = Path.Combine(manifestDirectory, manifestVersion); + } + + Directory.CreateDirectory(manifestDirectory); + + string manifestSourcePath = Path.Combine(_testAssetsManager.GetAndValidateTestProjectDirectory("SampleManifest"), sourceManifestName); + + File.Copy(manifestSourcePath, Path.Combine(manifestDirectory, "WorkloadManifest.json")); + } + + private FileInfo ManifestRecord(string manifestId, string manifestVersion, string manifestFeatureBand, string referencingFeatureBand) + { + return new FileInfo(Path.Combine(_dotnetRoot, "metadata", "workloads", "InstalledManifests", "v1", manifestId.ToLowerInvariant(), manifestVersion, manifestFeatureBand, referencingFeatureBand)); + } + + private void CreateManifestRecord(string manifestId, string manifestVersion, string manifestFeatureBand, string referencingFeatureBand) + { + var path = ManifestRecord(manifestId, manifestVersion, manifestFeatureBand, referencingFeatureBand); + path.Directory.Create(); + using var _ = path.Create(); + } + + private (FileBasedInstaller, Func) GetTestInstaller(string sdkVersion = "6.0.300", [CallerMemberName] string testName = "", string identifier = "") + { + CreateDotnetRoot(testName, identifier); + var sdkFeatureBand = new SdkFeatureBand(sdkVersion); + + INuGetPackageDownloader nugetInstaller = new MockNuGetPackageDownloader(_dotnetRoot, manifestDownload: true); + + var manifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetRoot, sdkVersion, userProfileDir: null, globalJsonPath: null); + + var workloadResolver = WorkloadResolver.CreateForTests(manifestProvider, _dotnetRoot); + + + IWorkloadResolver GetResolver(string workloadSetVersion) + { + if (workloadSetVersion != null && !sdkFeatureBand.Equals(new SdkFeatureBand(workloadSetVersion))) + { + throw new NotSupportedException("Mock doesn't support creating resolver for different feature bands: " + workloadSetVersion); + } + return workloadResolver; + } + + var installer = new FileBasedInstaller(_reporter, sdkFeatureBand, workloadResolver, userProfileDir: _testDirectory, nugetInstaller, _dotnetRoot, packageSourceLocation: null); + + return (installer, GetResolver); + } + } +} From ccc71f2fe3031f7667ae470c7eab9605838f9694 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 4 Oct 2023 15:13:50 -0400 Subject: [PATCH 2/4] Add test for workload garbage collection with install state --- ...kDirectoryWorkloadManifestProviderTests.cs | 2 +- .../WorkloadGarbageCollectionTests.cs | 80 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index b6bd4bda6343..b9a921981fcc 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -1233,7 +1233,7 @@ private void CreateMockWorkloadSet(string manifestRoot, string featureBand, stri private string CreateMockInstallState(string featureBand, string installStateContents) { - var installStateFolder = Path.Combine(_fakeDotnetRootDirectory!, "metadata", "workloads", "8.0.200", "InstallState"); + var installStateFolder = Path.Combine(_fakeDotnetRootDirectory!, "metadata", "workloads", featureBand, "InstallState"); Directory.CreateDirectory(installStateFolder); string installStatePath = Path.Combine(installStateFolder, "default.json"); diff --git a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs index fbab3f803f71..5c644e473699 100644 --- a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs +++ b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs @@ -169,8 +169,74 @@ public void GarbageCollectManifests() new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); } - // TODO: - // Garbage collect with install state with manifests + [Fact] + public void GarbageCollectManifestsWithInstallState() + { + CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + CreateMockManifest("TestManifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + + CreateManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300"); + CreateManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300"); + + CreateInstallState("6.0.300", + """ + { + "manifests": { + "TestManifest": "2.0.0/6.0.300", + } + } + """); + + var (installer, getResolver) = GetTestInstaller("6.0.300"); + + var packsToKeep = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk), + CreatePackInfo("Xamarin.Android.Framework", "8.5.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.5.0.1", WorkloadPackKind.Library) + }; + + var packsToCollect = new PackInfo[] + { + CreatePackInfo("Xamarin.Android.Framework", "8.6.0", WorkloadPackKind.Framework), + CreatePackInfo("Xamarin.Android.Runtime", "8.6.0.0", WorkloadPackKind.Library) + }; + + foreach (var pack in packsToKeep.Concat(packsToCollect)) + { + CreateInstalledPack(pack, "6.0.300"); + } + + // Write workload install record for 6.0.300 + var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); + Directory.CreateDirectory(workloadsRecordPath); + File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); + + installer.GarbageCollect(getResolver); + + foreach (var pack in packsToCollect) + { + PackShouldExist(pack, false); + PackRecord(pack, "6.0.300").Should().NotExist(); + } + foreach (var pack in packsToKeep) + { + PackShouldExist(pack, true); + PackRecord(pack, "6.0.300").Should().Exist(); + } + + ManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300").Should().Exist(); + ManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300").Should().NotExist(); + + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "TestManifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "2.0.0", "WorkloadManifest.json")).Should().Exist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "3.0.0", "WorkloadManifest.json")).Should().NotExist(); + } + + // Additional scenarios to add tests for once workload sets are added: // Garbage collect workload sets // Garbage collect with install state with workload set // Don't garbage collect baseline workload set @@ -249,6 +315,16 @@ private void CreateInstalledPack(PackInfo pack, string sdkFeatureBand) } } + private void CreateInstallState(string featureBand, string installStateContents) + { + var installStateFolder = Path.Combine(_dotnetRoot!, "metadata", "workloads", featureBand, "InstallState"); + Directory.CreateDirectory(installStateFolder); + + string installStatePath = Path.Combine(installStateFolder, "default.json"); + + File.WriteAllText(installStatePath, installStateContents); + } + private void CreateDotnetRoot([CallerMemberName]string testName = "", string identifier = "") { if (_dotnetRoot == null) From 33ca6b435952f18ac2516d4e2b5fa7a155442d48 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 4 Oct 2023 21:18:55 -0400 Subject: [PATCH 3/4] Use lowercase manifest ID for tests --- .../WorkloadGarbageCollectionTests.cs | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs index 5c644e473699..5392f752aaff 100644 --- a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs +++ b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs @@ -29,8 +29,8 @@ public WorkloadGarbageCollectionTests(ITestOutputHelper log) : base(log) [Fact] public void GivenManagedInstallItCanGarbageCollect() { - CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); - CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + CreateMockManifest("testmanifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("testmanifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); var (installer, getResolver) = GetTestInstaller(); var packsToKeep = new PackInfo[] @@ -80,7 +80,7 @@ public void GivenManagedInstallItCanGarbageCollect() [Fact] public void GivenManagedInstallItCanGarbageCollectPacksMissingFromManifest() { - CreateMockManifest("TestManifest", "1.0.0"); + CreateMockManifest("testmanifest", "1.0.0"); var (installer, getResolver) = GetTestInstaller(); // Define packs that don't show up in the manifest var packs = new PackInfo[] @@ -114,13 +114,13 @@ public void GivenManagedInstallItCanGarbageCollectPacksMissingFromManifest() [Fact] public void GarbageCollectManifests() { - CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); - CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); - CreateMockManifest("TestManifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + CreateMockManifest("testmanifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("testmanifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + CreateMockManifest("testmanifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); - CreateManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300"); - CreateManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300"); - CreateManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300"); + CreateManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300"); var (installer, getResolver) = GetTestInstaller("6.0.300"); @@ -160,31 +160,31 @@ public void GarbageCollectManifests() PackRecord(pack, "6.0.300").Should().Exist(); } - ManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); - ManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300").Should().NotExist(); - ManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300").Should().Exist(); + ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().Exist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "TestManifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "2.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); } [Fact] public void GarbageCollectManifestsWithInstallState() { - CreateMockManifest("TestManifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); - CreateMockManifest("TestManifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); - CreateMockManifest("TestManifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + CreateMockManifest("testmanifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); + CreateMockManifest("testmanifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); + CreateMockManifest("testmanifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); - CreateManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300"); - CreateManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300"); - CreateManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300"); + CreateManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300"); + CreateManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300"); CreateInstallState("6.0.300", """ { "manifests": { - "TestManifest": "2.0.0/6.0.300", + "testmanifest": "2.0.0/6.0.300", } } """); @@ -227,13 +227,13 @@ public void GarbageCollectManifestsWithInstallState() PackRecord(pack, "6.0.300").Should().Exist(); } - ManifestRecord("TestManifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); - ManifestRecord("TestManifest", "2.0.0", "6.0.300", "6.0.300").Should().Exist(); - ManifestRecord("TestManifest", "3.0.0", "6.0.300", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().Exist(); + ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "TestManifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "2.0.0", "WorkloadManifest.json")).Should().Exist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "TestManifest", "3.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().Exist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().NotExist(); } // Additional scenarios to add tests for once workload sets are added: From c5f04a2c75993c46ca64466fcccb392c7d9374ca Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 12 Oct 2023 16:56:01 -0400 Subject: [PATCH 4/4] Code review feedback --- .../WorkloadGarbageCollectionTests.cs | 80 ++++++++++++------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs index 5392f752aaff..7946e7e3ce5a 100644 --- a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs +++ b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs @@ -114,16 +114,25 @@ public void GivenManagedInstallItCanGarbageCollectPacksMissingFromManifest() [Fact] public void GarbageCollectManifests() { + // ARRANGE + // Create different versions of a manifest, one with a previous feature band CreateMockManifest("testmanifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); CreateMockManifest("testmanifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); CreateMockManifest("testmanifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + // Create manifest installation records (all for "current" version of SDK: 6.0.300) CreateManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300"); CreateManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300"); CreateManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300"); var (installer, getResolver) = GetTestInstaller("6.0.300"); + // Write workload install record for xamarin-android-build workload for 6.0.300 + var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); + Directory.CreateDirectory(workloadsRecordPath); + File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); + + // These packs are referenced by xamarin-android-build from the 3.0 manifest, which is the latest one and therefore the one that will be kept var packsToKeep = new PackInfo[] { CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk), @@ -131,55 +140,62 @@ public void GarbageCollectManifests() CreatePackInfo("Xamarin.Android.Runtime", "8.6.0.0", WorkloadPackKind.Library) }; + // These packs are referenced by earlier versions of the manifest, and should be garbage collected var packsToCollect = new PackInfo[] { CreatePackInfo("Xamarin.Android.Framework", "8.4.0", WorkloadPackKind.Framework), CreatePackInfo("Xamarin.Android.Runtime", "8.4.7.4", WorkloadPackKind.Library) }; + // Create packs and installation records foreach (var pack in packsToKeep.Concat(packsToCollect)) { CreateInstalledPack(pack, "6.0.300"); } - // Write workload install record for 6.0.300 - var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); - Directory.CreateDirectory(workloadsRecordPath); - File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); - + // ACT: garbage collect installer.GarbageCollect(getResolver); + // ASSERT + + // Only the latest manifest version and its installation record should be kept + ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().Exist(); + + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); + + // Packs which should be collected should be removed, as well as their installation records foreach (var pack in packsToCollect) { PackShouldExist(pack, false); PackRecord(pack, "6.0.300").Should().NotExist(); } + // Packs which should be kept should still exist, as well as their installation records foreach (var pack in packsToKeep) { PackShouldExist(pack, true); PackRecord(pack, "6.0.300").Should().Exist(); } - - ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); - ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().NotExist(); - ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().Exist(); - - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().Exist(); } [Fact] public void GarbageCollectManifestsWithInstallState() { + // ARRANGE + // Create different versions of a manifest, one with a previous feature band CreateMockManifest("testmanifest", "1.0.0", "6.0.100", sourceManifestName: @"Sample2.json"); CreateMockManifest("testmanifest", "2.0.0", "6.0.300", sourceManifestName: @"Sample2_v2.json"); CreateMockManifest("testmanifest", "3.0.0", "6.0.300", sourceManifestName: @"Sample2_v3.json"); + // Create manifest installation records (all for "current" version of SDK: 6.0.300) CreateManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300"); CreateManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300"); CreateManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300"); + // Create install state pinning the 2.0.0 version of the manifest CreateInstallState("6.0.300", """ { @@ -191,6 +207,12 @@ public void GarbageCollectManifestsWithInstallState() var (installer, getResolver) = GetTestInstaller("6.0.300"); + // Write workload install record for xamarin-android-build workload for 6.0.300 + var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); + Directory.CreateDirectory(workloadsRecordPath); + File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); + + // These packs are referenced by xamarin-android-build from the 2.0 manifest, which is the one that should be kept due to the install state var packsToKeep = new PackInfo[] { CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk), @@ -198,45 +220,49 @@ public void GarbageCollectManifestsWithInstallState() CreatePackInfo("Xamarin.Android.Runtime", "8.5.0.1", WorkloadPackKind.Library) }; + // These packs are referenced by version 3.0 of the manifest, and should be garbage collected var packsToCollect = new PackInfo[] { CreatePackInfo("Xamarin.Android.Framework", "8.6.0", WorkloadPackKind.Framework), CreatePackInfo("Xamarin.Android.Runtime", "8.6.0.0", WorkloadPackKind.Library) }; + // Create packs and installation records foreach (var pack in packsToKeep.Concat(packsToCollect)) { CreateInstalledPack(pack, "6.0.300"); } - // Write workload install record for 6.0.300 - var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads"); - Directory.CreateDirectory(workloadsRecordPath); - File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")); - + // ACT: garbage collect installer.GarbageCollect(getResolver); + // ASSERT + + // Only the pinned manifest version (2.0.0) and its installation record should be kept + ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); + ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().Exist(); + ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().NotExist(); + + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().Exist(); + new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().NotExist(); + + // Packs which should be collected should be removed, as well as their installation records foreach (var pack in packsToCollect) { PackShouldExist(pack, false); PackRecord(pack, "6.0.300").Should().NotExist(); } + // Packs which should be kept should still exist, as well as their installation records foreach (var pack in packsToKeep) { PackShouldExist(pack, true); PackRecord(pack, "6.0.300").Should().Exist(); } - ManifestRecord("testmanifest", "1.0.0", "6.0.100", "6.0.300").Should().NotExist(); - ManifestRecord("testmanifest", "2.0.0", "6.0.300", "6.0.300").Should().Exist(); - ManifestRecord("testmanifest", "3.0.0", "6.0.300", "6.0.300").Should().NotExist(); - - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.100", "testmanifest", "1.0.0", "WorkloadManifest.json")).Should().NotExist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "2.0.0", "WorkloadManifest.json")).Should().Exist(); - new FileInfo(Path.Combine(_dotnetRoot, "sdk-manifests", "6.0.300", "testmanifest", "3.0.0", "WorkloadManifest.json")).Should().NotExist(); } - // Additional scenarios to add tests for once workload sets are added: + // TODO: Additional scenarios to add tests for once workload sets are added: // Garbage collect workload sets // Garbage collect with install state with workload set // Don't garbage collect baseline workload set @@ -277,7 +303,7 @@ PackInfo CreatePackInfo(string id, string version, WorkloadPackKind kind, string string path; if (kind == WorkloadPackKind.Library) { - path = Path.Combine(_dotnetRoot, "library-packs", $"resolvedPackageId.{version}.nupkg"); + path = Path.Combine(_dotnetRoot, "library-packs", $"{resolvedPackageId}.{version}.nupkg"); } else {