From fb54576f1d05e82ba47cd718c4c4f8b3bad624c9 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 18 Mar 2022 20:15:33 -0500 Subject: Give BA process id and option to wait for cancelled process to exit. --- src/test/burn/TestBA/TestBA.cs | 91 ++++++++++++++-------- .../TestData/FailureTests/BundleD/BundleD.wixproj | 19 +++++ .../burn/TestData/FailureTests/BundleD/BundleD.wxs | 19 +++++ .../burn/WixToolsetTest.BurnE2E/FailureTests.cs | 42 ++++++++++ .../WixToolsetTest.BurnE2E/TestBAController.cs | 15 ++++ 5 files changed, 155 insertions(+), 31 deletions(-) create mode 100644 src/test/burn/TestData/FailureTests/BundleD/BundleD.wixproj create mode 100644 src/test/burn/TestData/FailureTests/BundleD/BundleD.wxs (limited to 'src/test') diff --git a/src/test/burn/TestBA/TestBA.cs b/src/test/burn/TestBA/TestBA.cs index 3688e028..c219ce9c 100644 --- a/src/test/burn/TestBA/TestBA.cs +++ b/src/test/burn/TestBA/TestBA.cs @@ -21,7 +21,7 @@ namespace WixToolset.Test.BA private Form dummyWindow; private IntPtr windowHandle; private LaunchAction action; - private ManualResetEvent wait; + private readonly ManualResetEvent wait; private int result; private string updateBundlePath; @@ -397,6 +397,35 @@ namespace WixToolset.Test.BA } } + protected override void OnExecutePackageComplete(ExecutePackageCompleteEventArgs args) + { + bool logTestRegistryValue; + string recordTestRegistryValue = this.ReadPackageAction(args.PackageId, "RecordTestRegistryValue"); + if (!String.IsNullOrEmpty(recordTestRegistryValue) && Boolean.TryParse(recordTestRegistryValue, out logTestRegistryValue) && logTestRegistryValue) + { + var value = this.ReadTestRegistryValue(args.PackageId); + this.Log("TestRegistryValue: {0}, Version, '{1}'", args.PackageId, value); + } + } + + protected override void OnExecuteProcessCancel(ExecuteProcessCancelEventArgs args) + { + BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION action; + string actionValue = this.ReadPackageAction(args.PackageId, "ProcessCancelAction"); + if (actionValue != null && TryParseEnum(actionValue, out action)) + { + args.Action = action; + } + + if (args.Action == BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION.Abandon) + { + // Give time to the process to start before its files are deleted. + Thread.Sleep(2000); + } + + this.Log("OnExecuteProcessCancel({0})", args.Action); + } + protected override void OnExecuteFilesInUse(ExecuteFilesInUseEventArgs args) { this.Log("OnExecuteFilesInUse() - package: {0}, source: {1}, retries remaining: {2}, data: {3}", args.PackageId, args.Source, this.retryExecuteFilesInUse, String.Join(", ", args.Files.ToArray())); @@ -488,43 +517,34 @@ namespace WixToolset.Test.BA private void TestVariables() { // First make sure we can check and get standard variables of each type. + if (this.Engine.ContainsVariable("WindowsFolder")) { - string value = null; - if (this.Engine.ContainsVariable("WindowsFolder")) - { - value = this.Engine.GetVariableString("WindowsFolder"); - this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a string variable: WindowsFolder"); - } - else - { - throw new Exception("Engine did not define a standard variable: WindowsFolder"); - } + string value = this.Engine.GetVariableString("WindowsFolder"); + this.Engine.Log(LogLevel.Verbose, String.Format("TEST: Successfully retrieved a string variable: WindowsFolder '{0}'", value)); + } + else + { + throw new Exception("Engine did not define a standard variable: WindowsFolder"); } + if (this.Engine.ContainsVariable("NTProductType")) { - long value = 0; - if (this.Engine.ContainsVariable("NTProductType")) - { - value = this.Engine.GetVariableNumeric("NTProductType"); - this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a numeric variable: NTProductType"); - } - else - { - throw new Exception("Engine did not define a standard variable: NTProductType"); - } + long value = this.Engine.GetVariableNumeric("NTProductType"); + this.Engine.Log(LogLevel.Verbose, String.Format("TEST: Successfully retrieved a numeric variable: NTProductType '{0}'", value)); + } + else + { + throw new Exception("Engine did not define a standard variable: NTProductType"); } + if (this.Engine.ContainsVariable("VersionMsi")) { - string value = null; - if (this.Engine.ContainsVariable("VersionMsi")) - { - value = this.Engine.GetVariableVersion("VersionMsi"); - this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a version variable: VersionMsi"); - } - else - { - throw new Exception("Engine did not define a standard variable: VersionMsi"); - } + string value = this.Engine.GetVariableVersion("VersionMsi"); + this.Engine.Log(LogLevel.Verbose, String.Format("TEST: Successfully retrieved a version variable: VersionMsi '{0}'", value)); + } + else + { + throw new Exception("Engine did not define a standard variable: VersionMsi"); } // Now validate that Contians returns false for non-existant variables of each type. @@ -596,6 +616,15 @@ namespace WixToolset.Test.BA } } + private string ReadTestRegistryValue(string name) + { + string testName = this.Engine.GetVariableString("TestGroupName"); + using (RegistryKey testKey = Registry.LocalMachine.OpenSubKey(String.Format(@"Software\WiX\Tests\{0}\{1}", testName, name))) + { + return testKey == null ? null : testKey.GetValue("Version") as string; + } + } + private static bool TryParseEnum(string value, out T t) { try diff --git a/src/test/burn/TestData/FailureTests/BundleD/BundleD.wixproj b/src/test/burn/TestData/FailureTests/BundleD/BundleD.wixproj new file mode 100644 index 00000000..7b7408c6 --- /dev/null +++ b/src/test/burn/TestData/FailureTests/BundleD/BundleD.wixproj @@ -0,0 +1,19 @@ + + + + Bundle + {3C1A4842-81AC-4C90-8B35-A5E18F034C8D} + 1.0.0.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/burn/TestData/FailureTests/BundleD/BundleD.wxs b/src/test/burn/TestData/FailureTests/BundleD/BundleD.wxs new file mode 100644 index 00000000..ca70236d --- /dev/null +++ b/src/test/burn/TestData/FailureTests/BundleD/BundleD.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs index d8428a54..bbc0b387 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs @@ -2,7 +2,9 @@ namespace WixToolsetTest.BurnE2E { + using System.Threading; using WixTestTools; + using WixToolset.Mba.Core; using Xunit; using Xunit.Abstractions; @@ -10,6 +12,46 @@ namespace WixToolsetTest.BurnE2E { public FailureTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } + [Fact] + public void CanCancelExePackageAndAbandonIt() + { + var bundleD = this.CreateBundleInstaller("BundleD"); + var testBAController = this.CreateTestBAController(); + + // Cancel package ExeA after it starts. + testBAController.SetPackageCancelExecuteAtProgress("ExeA", 1); + testBAController.SetPackageRecordTestRegistryValue("ExeA"); + + var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); + bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); + + Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: ExeA, Version, ''")); + + // Make sure ExeA finishes running. + Thread.Sleep(3000); + + bundleD.VerifyExeTestRegistryValue("ExeA", "1.0.0.0"); + } + + [Fact] + public void CanCancelExePackageAndWaitUntilItCompletes() + { + var bundleD = this.CreateBundleInstaller("BundleD"); + var testBAController = this.CreateTestBAController(); + + // Cancel package ExeA after it starts. + testBAController.SetPackageCancelExecuteAtProgress("ExeA", 1); + testBAController.SetPackageProcessCancelAction("ExeA", BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION.Wait); + testBAController.SetPackageRecordTestRegistryValue("ExeA"); + + var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); + bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); + + Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: ExeA, Version, '1.0.0.0'")); + + bundleD.VerifyExeTestRegistryValue("ExeA", "1.0.0.0"); + } + [Fact] public void CanCancelMsiPackageVeryEarly() { diff --git a/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs b/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs index d2e8a1ca..fa553919 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs @@ -147,6 +147,21 @@ namespace WixToolsetTest.BurnE2E 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. /// -- cgit v1.2.3-55-g6feb