// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. namespace WixToolsetTest.BurnE2E { using System; using Microsoft.Win32; using WixTestTools; using WixToolset.Mba.Core; public class TestBAController : IDisposable { public TestBAController(WixTestContext testContext, bool x64 = false) { this.TestGroupName = testContext.TestGroupName; this.BaseRegKeyPath = x64 ? @"Software\WiX\Tests" : @"Software\WOW6432Node\WiX\Tests"; this.TestBaseRegKeyPath = String.Format(@"{0}\TestBAControl\{1}", this.BaseRegKeyPath, this.TestGroupName); } private string BaseRegKeyPath { get; } private string TestBaseRegKeyPath { get; } public string TestGroupName { get; } /// /// Sets a test value in the registry to communicate with the TestBA. /// /// Name of the value to set. /// Value to set. If this is null, the value is removed. public void SetBurnTestValue(string name, string value) { using (var testKey = Registry.LocalMachine.CreateSubKey(this.TestBaseRegKeyPath)) { if (String.IsNullOrEmpty(value)) { testKey.DeleteValue(name, false); } else { testKey.SetValue(name, value); } } } public void SetExplicitlyElevateAndPlanFromOnElevateBegin(string value = "true") { this.SetBurnTestValue("ExplicitlyElevateAndPlanFromOnElevateBegin", value); } public void SetForceKeepRegistration(string value = "true") { this.SetBurnTestValue("ForceKeepRegistration", value); } public void SetImmediatelyQuit(string value = "true") { this.SetBurnTestValue("ImmediatelyQuit", value); } public void SetQuitAfterDetect(string value = "true") { this.SetBurnTestValue("QuitAfterDetect", value); } /// /// Slows the cache progress of a package. /// /// Package identity. /// Sets or removes the delay on a package being cached. public void SetPackageSlowCache(string packageId, int? delay) { this.SetPackageState(packageId, "SlowCache", delay.HasValue ? delay.ToString() : null); } /// /// Cancels the cache of a package at a particular progress point. /// /// Package identity. /// Sets or removes the cancel progress on a package being cached. public void SetPackageCancelCacheAtProgress(string packageId, int? cancelPoint) { this.SetPackageState(packageId, "CancelCacheAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null); } /// /// Slows the execute progress of a package. /// /// Package identity. /// Sets or removes the delay on a package being executed. public void SetPackageSlowExecute(string packageId, int? delay) { this.SetPackageState(packageId, "SlowExecute", delay.HasValue ? delay.ToString() : null); } /// /// Cancels the execute of a package at a particular progress point. /// /// Package identity. /// Sets or removes the cancel progress on a package being executed. public void SetPackageCancelExecuteAtProgress(string packageId, int? cancelPoint) { this.SetPackageState(packageId, "CancelExecuteAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null); } /// /// Cancels the execute of a package at the next progess after the specified MSI action start. /// /// Package identity. /// Sets or removes the cancel progress on a package being executed. public void SetPackageCancelExecuteAtActionStart(string packageId, string actionName) { this.SetPackageState(packageId, "CancelExecuteAtActionStart", actionName); } /// /// Cancels the execute of a package at a particular OnProgress point. /// /// Package identity. /// Sets or removes the cancel OnProgress point on a package being executed. public void SetPackageCancelOnProgressAtProgress(string packageId, int? cancelPoint) { this.SetPackageState(packageId, "CancelOnProgressAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null); } /// /// Retries the files in use one or more times before canceling. /// /// Package identity. /// Sets or removes the retry count on a package's file in use message. public void SetPackageRetryExecuteFilesInUse(string packageId, int? retryCount) { this.SetPackageState(packageId, "RetryExecuteFilesInUse", retryCount.HasValue ? retryCount.ToString() : null); } /// /// Sets the requested state for a package that the TestBA will return to the engine during plan. /// /// Package identity. /// State to request. public void SetPackageRequestedState(string packageId, RequestState state) { this.SetPackageState(packageId, "Requested", state.ToString()); } /// /// Sets the requested state for a package that the TestBA will return to the engine during plan. /// /// Package identity. /// State to request. public void SetPackageFeatureState(string packageId, string featureId, FeatureState state) { this.SetPackageState(packageId, String.Concat(featureId, "Requested"), state.ToString()); } /// /// Requests the BA to log the test registry value for the specified package. /// /// /// public void SetPackageRecordTestRegistryValue(string packageId, string value = "true") { this.SetPackageState(packageId, "RecordTestRegistryValue", value); } public void SetPackageProcessCancelAction(string packageId, BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION action) { this.SetPackageState(packageId, "ProcessCancelAction", action.ToString()); } /// /// Sets the number of times to re-run the Detect phase. /// /// Number of times to run Detect (after the first, normal, Detect). public void SetRedetectCount(int redetectCount) { this.SetPackageState(null, "RedetectCount", redetectCount.ToString()); } /// /// Resets the state for a package that the TestBA will return to the engine during plan. /// /// Package identity. public void ResetPackageStates(string packageId) { var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty); Registry.LocalMachine.DeleteSubKey(key); } public void SetVerifyArguments(string verifyArguments) { this.SetBurnTestValue("VerifyArguments", verifyArguments); } private void SetPackageState(string packageId, string name, string value) { var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty); using (var packageKey = Registry.LocalMachine.CreateSubKey(key)) { if (String.IsNullOrEmpty(value)) { packageKey.DeleteValue(name, false); } else { packageKey.SetValue(name, value); } } } public void Dispose() { Registry.LocalMachine.DeleteSubKeyTree($@"{this.BaseRegKeyPath}\{this.TestGroupName}", false); Registry.LocalMachine.DeleteSubKeyTree($@"{this.BaseRegKeyPath}\TestBAControl", false); } } }