private void AssertUpdateSchedule(IEnumerable <MockPackageSpec> installed, IEnumerable <MockPackageSpec> uninstalled) { bool anyUpdateExpected = installed.Any() || uninstalled.Any(); bool updateScheduleExists = File.Exists(this.workEnv.UpdateFilePath); // Assert that the existence of an update file reflects whether we expect an update if (!anyUpdateExpected) { Assert.IsFalse(updateScheduleExists); return; } else { Assert.IsTrue(updateScheduleExists); } // Load the update schedule to check its contents PackageUpdateSchedule applyScript = PackageUpdateSchedule.Load(this.workEnv.UpdateFilePath); List <XElement> updateItems = applyScript.Items.ToList(); // Assert that every install has a matching copy for each of its files. HashSet <string> writtenFiles = new HashSet <string>(); foreach (MockPackageSpec package in installed) { foreach (var pair in package.LocalMapping) { this.AssertUpdateScheduleCopy( updateItems, package.Name, pair.Key, pair.Value); // Note that an install can supersede a previous uninstall by copying a // file into the same location. Keep track of all written files to check this. bool uniqueCopy = writtenFiles.Add(pair.Value); // Assert that we don't copy multiple files to the same target location. // The package manager should take care of resolving this up front. Assert.IsTrue(uniqueCopy); } } // Assert that every uninstall has a matching delete for each of its files. foreach (MockPackageSpec package in uninstalled) { foreach (var pair in package.LocalMapping) { // If the file we expect to see deleted was overwritten instead, skip // the assert to account for update situations where an uninstall is // immediately followed by an install. if (writtenFiles.Contains(pair.Value)) { continue; } this.AssertUpdateScheduleDelete( updateItems, package.Name, pair.Value); } } }
private void SetupPackagesForTest(PackageManager packageManager, IEnumerable <MockPackageSpec> setup) { try { // Install all required packages foreach (MockPackageSpec package in setup) { PackageInfo packageInfo = packageManager.GetPackage(package.Name); if (packageInfo == null || packageInfo.Name != package.Name) { Assert.Inconclusive( "Failed to create the required package setup for the test. Unable to retrieve package '{0}'", package.Name); } packageManager.InstallPackage(packageInfo.Name); } // Make sure all required packages are really there foreach (MockPackageSpec package in setup) { // Skip checking non-Duality packages, as they do not show up in // the local package setup and thus would always fail this check. bool isDualityPackage = package.Tags.Contains(PackageManager.DualityTag); if (!isDualityPackage) { continue; } LocalPackage localPackage = packageManager.LocalSetup.GetPackage(package.Name); if (localPackage == null) { Assert.Inconclusive( "Failed to create the required package setup for the test. Install failed for package '{0}'", package.Name); } } // Make sure that the install didn't leave the setup out of sync with the install if (packageManager.IsPackageSyncRequired) { Assert.Inconclusive( "Failed to create the required package setup for the test. " + "Local setup out of sync with installs."); } // Apply all scheduled copy and delete operations immediately if (File.Exists(this.workEnv.UpdateFilePath)) { PackageUpdateSchedule applyScript = PackageUpdateSchedule.Load(this.workEnv.UpdateFilePath); applyScript.ApplyChanges(applyScript.Items); // Get rid of the other scheduled updates File.Delete(this.workEnv.UpdateFilePath); } } catch (Exception e) { Assert.Inconclusive( "Failed to create the required package setup for the test because an exception occurred: {0}", e); } }