aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/test/burn/BurnE2ETests.sln79
-rw-r--r--src/test/burn/Directory.Build.props29
-rw-r--r--src/test/burn/Directory.Build.targets50
-rw-r--r--src/test/burn/README.md50
-rw-r--r--src/test/burn/TestBA/Hresult.cs22
-rw-r--r--src/test/burn/TestBA/MessagePump.cs39
-rw-r--r--src/test/burn/TestBA/TestBA.BootstrapperCore.config18
-rw-r--r--src/test/burn/TestBA/TestBA.cs613
-rw-r--r--src/test/burn/TestBA/TestBA.csproj24
-rw-r--r--src/test/burn/TestBA/TestBAFactory.cs22
-rw-r--r--src/test/burn/TestBA/TestBA_x64.csproj24
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wixproj17
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wxs10
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wixproj18
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wxs10
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleB/BundleB.wixproj19
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleB_x64/BundleB_x64.wixproj21
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleC/BundleC.wixproj20
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/BundleC_x64/BundleC_x64.wixproj21
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/PackageA/PackageA.wixproj10
-rw-r--r--src/test/burn/TestData/BasicFunctionalityTests/PackageA_x64/PackageA_x64.wixproj10
-rw-r--r--src/test/burn/TestData/CacheTests/BundleA/BundleA.wixproj19
-rw-r--r--src/test/burn/TestData/CacheTests/BundleA/BundleA.wxs11
-rw-r--r--src/test/burn/TestData/CacheTests/BundleB/BundleB.wixproj19
-rw-r--r--src/test/burn/TestData/CacheTests/BundleB/BundleB.wxs11
-rw-r--r--src/test/burn/TestData/CacheTests/BundleC/BundleC.wixproj26
-rw-r--r--src/test/burn/TestData/CacheTests/BundleC/BundleC.wxs12
-rw-r--r--src/test/burn/TestData/CacheTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/CacheTests/PackageB/PackageB.wixproj9
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleAv1/BundleA.props11
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wixproj16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wxs21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wixproj16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wxs21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleB/Bundle.wxs40
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleB/BundleB.wixproj18
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleB/BundleB.wxs22
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleC/BundleC.wixproj22
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleC/BundleC.wxs12
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleD/BundleD.wixproj22
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleD/BundleD.wxs12
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleE/BundleE.wixproj21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs19
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs12
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs22
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj20
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchA.props11
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wixproj16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wxs13
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wixproj17
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wxs16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleHv1/BundleH.props10
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wxs11
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wixproj16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wxs11
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wixproj21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wxs12
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wixproj21
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wxs16
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleKv1/BundleK.props10
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wixproj12
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wxs10
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wixproj15
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wxs10
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleL/BundleL.wixproj20
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleL/BundleL.wxs10
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props12
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj7
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageAv1/ProductComponents.wxs16
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageB/PackageB.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageB/ProductComponents.wxs18
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageC/PackageC.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageDv1/Package.wxs63
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageDv1/PackageD.props7
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageDv1/PackageDv1.wixproj7
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageDv2/PackageDv2.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageEv1/PackageE.props12
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageEv1/PackageEv1.wixproj7
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageEv1/ProductComponents.wxs16
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageEv1_0_1/PackageEv1_0_1.wixproj13
-rw-r--r--src/test/burn/TestData/DependencyTests/PackageF/PackageF.wixproj9
-rw-r--r--src/test/burn/TestData/DependencyTests/PatchA/PatchA.wixproj15
-rw-r--r--src/test/burn/TestData/DependencyTests/PatchA/PatchA.wxs22
-rw-r--r--src/test/burn/TestData/DependencyTests/PatchB/PatchB.wixproj15
-rw-r--r--src/test/burn/TestData/DependencyTests/PatchB/PatchB.wxs21
-rw-r--r--src/test/burn/TestData/ElevationTests/BundleA/BundleA.wixproj18
-rw-r--r--src/test/burn/TestData/ElevationTests/BundleA/BundleA.wxs10
-rw-r--r--src/test/burn/TestData/ElevationTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/FailureTests/BundleA/BundleA.wixproj19
-rw-r--r--src/test/burn/TestData/FailureTests/BundleA/BundleA.wxs11
-rw-r--r--src/test/burn/TestData/FailureTests/BundleB/Bundle.wxs26
-rw-r--r--src/test/burn/TestData/FailureTests/BundleB/BundleB.wixproj16
-rw-r--r--src/test/burn/TestData/FailureTests/BundleC/BundleC.wixproj19
-rw-r--r--src/test/burn/TestData/FailureTests/BundleC/BundleC.wxs11
-rw-r--r--src/test/burn/TestData/FailureTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/FailureTests/PackageB/PackageB.wixproj9
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs40
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props7
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj12
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs10
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj18
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs10
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs40
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props7
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj12
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs10
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj18
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs10
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props9
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj7
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props9
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj4
-rw-r--r--src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj7
-rw-r--r--src/test/burn/TestData/LayoutTests/BundleA/Bundle.wxs42
-rw-r--r--src/test/burn/TestData/LayoutTests/BundleA/BundleA.wixproj23
-rw-r--r--src/test/burn/TestData/LayoutTests/BundleA/BundleA.wxs26
-rw-r--r--src/test/burn/TestData/LayoutTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleA.props12
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wixproj12
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wxs13
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wixproj15
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wxs13
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleB.props13
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wixproj11
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wxs10
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wixproj18
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wxs13
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageA/PackageA.wixproj10
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageB.props9
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageBv1.wixproj7
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageBv2/PackageBv2.wixproj7
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageC.props9
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageCv1.wixproj7
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageCv2/PackageCv2.wixproj7
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageD/PackageD.wixproj9
-rw-r--r--src/test/burn/TestData/MsiTransactionTests/PackageF/PackageF.wixproj12
-rw-r--r--src/test/burn/TestData/PatchTests/BundleA/BundleA.wixproj19
-rw-r--r--src/test/burn/TestData/PatchTests/BundleA/BundleA.wxs9
-rw-r--r--src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wixproj19
-rw-r--r--src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wxs9
-rw-r--r--src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wixproj20
-rw-r--r--src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wxs10
-rw-r--r--src/test/burn/TestData/PatchTests/PackageAv1/PackageA.props13
-rw-r--r--src/test/burn/TestData/PatchTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/test/burn/TestData/PatchTests/PackageAv1/ProductComponents.wxs15
-rw-r--r--src/test/burn/TestData/PatchTests/PackageAv1_0_1/PackageAv1_0_1.wixproj10
-rw-r--r--src/test/burn/TestData/PatchTests/PatchA/PatchA.wixproj12
-rw-r--r--src/test/burn/TestData/PatchTests/PatchA/PatchA.wxs24
-rw-r--r--src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wixproj12
-rw-r--r--src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wxs23
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj21
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs22
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleA/bad.runtimeconfig.json10
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj21
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs21
-rw-r--r--src/test/burn/TestData/PrereqBaTests/BundleB/bad.config17
-rw-r--r--src/test/burn/TestData/PrereqBaTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/PrereqBaTests/PackageB/PackageB.wixproj9
-rw-r--r--src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj12
-rw-r--r--src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wixproj18
-rw-r--r--src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wxs10
-rw-r--r--src/test/burn/TestData/RegistrationTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wixproj20
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wxs15
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/PackageA/PackageA.wixproj9
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/PackageB/PackageB.wixproj9
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/PackageC/PackageC.wixproj9
-rw-r--r--src/test/burn/TestData/RollbackBoundaryTests/PackageF/PackageF.wixproj12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wixproj19
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wxs12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wixproj19
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wxs12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wixproj20
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wxs13
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wixproj21
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wxs14
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wixproj19
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wxs12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wixproj18
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wxs9
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wixproj18
-rw-r--r--src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wxs9
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv0_9_0/PackageAv0_9_0.wixproj10
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageA.props11
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.props7
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv1/ProductComponents.wxs15
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageAv1_0_1/PackageAv1_0_1.wixproj10
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageB.props12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageBv1.wixproj4
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageBv1/ProductComponents.wxs15
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PackageBv1_0_1/PackageBv1_0_1.wixproj10
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wixproj12
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wxs22
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wixproj14
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wxs27
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wixproj14
-rw-r--r--src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wxs26
-rw-r--r--src/test/burn/TestData/Templates/Bundle.wxs47
-rw-r--r--src/test/burn/TestData/Templates/Package.wxs62
-rw-r--r--src/test/burn/TestData/Templates/PackageFail.wxs50
-rw-r--r--src/test/burn/TestData/Templates/PackagePerUser.wxs62
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib/TestBA.wxs30
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib/TestExe.wxs9
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib/testbawixlib.wixproj19
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestBA_x64.wxs30
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestExe_x64.wxs9
-rw-r--r--src/test/burn/TestData/TestBA/TestBAWixlib_x64/testbawixlib_x64.wixproj20
-rw-r--r--src/test/burn/TestData/TestData.proj25
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleA.props10
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj12
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs10
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj15
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs10
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs42
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleB.props7
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj18
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs10
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml32
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml51
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj18
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs10
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageA.props9
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj7
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageB.props9
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj4
-rw-r--r--src/test/burn/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj7
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleA.props10
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wixproj12
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wxs10
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wixproj15
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wxs10
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageA.props9
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv2/PackageAv2.wixproj7
-rw-r--r--src/test/burn/TestExe/NetfxTask.cs295
-rw-r--r--src/test/burn/TestExe/Program.cs74
-rw-r--r--src/test/burn/TestExe/Task.cs209
-rw-r--r--src/test/burn/TestExe/TestExe.csproj20
-rw-r--r--src/test/burn/TestExe/TestExe_x64.csproj17
-rw-r--r--src/test/burn/TestExe/app.config10
-rw-r--r--src/test/burn/Wix.Build.props11
-rw-r--r--src/test/burn/Wix.Build.targets17
-rw-r--r--src/test/burn/WixTestTools/BundleInstaller.cs197
-rw-r--r--src/test/burn/WixTestTools/BundleRegistration.cs182
-rw-r--r--src/test/burn/WixTestTools/BundleVerifier.cs156
-rw-r--r--src/test/burn/WixTestTools/LogVerifier.cs252
-rw-r--r--src/test/burn/WixTestTools/MSIExec.cs753
-rw-r--r--src/test/burn/WixTestTools/MsiUtilities.cs47
-rw-r--r--src/test/burn/WixTestTools/PackageInstaller.cs104
-rw-r--r--src/test/burn/WixTestTools/PackageVerifier.cs81
-rw-r--r--src/test/burn/WixTestTools/TestTool.cs245
-rw-r--r--src/test/burn/WixTestTools/WixTestBase.cs19
-rw-r--r--src/test/burn/WixTestTools/WixTestContext.cs75
-rw-r--r--src/test/burn/WixTestTools/WixTestTools.csproj21
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/BasicFunctionalityTests.cs176
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/BurnE2EFixture.cs28
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs63
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/CacheTests.cs133
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs611
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs30
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs112
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs469
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/IWebServer.cs20
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/LayoutTests.cs68
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/MsiTransactionTests.cs128
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/PatchTests.cs137
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs76
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/RegistrationTests.cs78
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs52
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/SlipstreamTests.cs353
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs187
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/UpdateBundleTests.cs245
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs36
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs70
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj33
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/runtests.cmd2
-rw-r--r--src/test/burn/appveyor.cmd11
-rw-r--r--src/test/burn/appveyor.yml27
-rw-r--r--src/test/burn/global.json8
-rw-r--r--src/test/burn/nuget.config16
288 files changed, 10484 insertions, 0 deletions
diff --git a/src/test/burn/BurnE2ETests.sln b/src/test/burn/BurnE2ETests.sln
new file mode 100644
index 00000000..7cdb0cf0
--- /dev/null
+++ b/src/test/burn/BurnE2ETests.sln
@@ -0,0 +1,79 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio Version 16
4VisualStudioVersion = 16.0.29503.13
5MinimumVisualStudioVersion = 10.0.40219.1
6Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestBA", "src\TestBA\TestBA.csproj", "{04022D35-6D75-49D0-91D2-4208E09DBA6D}"
7EndProject
8Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestExe", "src\TestExe\TestExe.csproj", "{B038B342-BE42-4951-82A9-7789412CF37F}"
9EndProject
10Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixTestTools", "src\WixTestTools\WixTestTools.csproj", "{3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}"
11EndProject
12Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.BurnE2E", "src\WixToolsetTest.BurnE2E\WixToolsetTest.BurnE2E.csproj", "{FED9D707-E5C3-4867-87B0-FABDB5EB0823}"
13EndProject
14Global
15 GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 Debug|Any CPU = Debug|Any CPU
17 Debug|x64 = Debug|x64
18 Debug|x86 = Debug|x86
19 Release|Any CPU = Release|Any CPU
20 Release|x64 = Release|x64
21 Release|x86 = Release|x86
22 EndGlobalSection
23 GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|x64.ActiveCfg = Debug|Any CPU
27 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|x64.Build.0 = Debug|Any CPU
28 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|x86.ActiveCfg = Debug|Any CPU
29 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Debug|x86.Build.0 = Debug|Any CPU
30 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|Any CPU.Build.0 = Release|Any CPU
32 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|x64.ActiveCfg = Release|Any CPU
33 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|x64.Build.0 = Release|Any CPU
34 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|x86.ActiveCfg = Release|Any CPU
35 {04022D35-6D75-49D0-91D2-4208E09DBA6D}.Release|x86.Build.0 = Release|Any CPU
36 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|x64.ActiveCfg = Debug|Any CPU
39 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|x64.Build.0 = Debug|Any CPU
40 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|x86.ActiveCfg = Debug|Any CPU
41 {B038B342-BE42-4951-82A9-7789412CF37F}.Debug|x86.Build.0 = Debug|Any CPU
42 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|Any CPU.Build.0 = Release|Any CPU
44 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|x64.ActiveCfg = Release|Any CPU
45 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|x64.Build.0 = Release|Any CPU
46 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|x86.ActiveCfg = Release|Any CPU
47 {B038B342-BE42-4951-82A9-7789412CF37F}.Release|x86.Build.0 = Release|Any CPU
48 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|x64.ActiveCfg = Debug|Any CPU
51 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|x64.Build.0 = Debug|Any CPU
52 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|x86.ActiveCfg = Debug|Any CPU
53 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Debug|x86.Build.0 = Debug|Any CPU
54 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
55 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|Any CPU.Build.0 = Release|Any CPU
56 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x64.ActiveCfg = Release|Any CPU
57 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x64.Build.0 = Release|Any CPU
58 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x86.ActiveCfg = Release|Any CPU
59 {3D3B02F3-79B6-4BD5-AD49-2889DA3849A7}.Release|x86.Build.0 = Release|Any CPU
60 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|Any CPU.Build.0 = Debug|Any CPU
62 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.ActiveCfg = Debug|Any CPU
63 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x64.Build.0 = Debug|Any CPU
64 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.ActiveCfg = Debug|Any CPU
65 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Debug|x86.Build.0 = Debug|Any CPU
66 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.ActiveCfg = Release|Any CPU
67 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|Any CPU.Build.0 = Release|Any CPU
68 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.ActiveCfg = Release|Any CPU
69 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x64.Build.0 = Release|Any CPU
70 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.ActiveCfg = Release|Any CPU
71 {FED9D707-E5C3-4867-87B0-FABDB5EB0823}.Release|x86.Build.0 = Release|Any CPU
72 EndGlobalSection
73 GlobalSection(SolutionProperties) = preSolution
74 HideSolutionNode = FALSE
75 EndGlobalSection
76 GlobalSection(ExtensibilityGlobals) = postSolution
77 SolutionGuid = {74DE2EED-ECAA-4FDD-9792-9D3B0C0C1321}
78 EndGlobalSection
79EndGlobal
diff --git a/src/test/burn/Directory.Build.props b/src/test/burn/Directory.Build.props
new file mode 100644
index 00000000..f83cc154
--- /dev/null
+++ b/src/test/burn/Directory.Build.props
@@ -0,0 +1,29 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.props
5 then update all of the repos.
6-->
7<Project>
8 <PropertyGroup>
9 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
10 <EnableSourceLink Condition=" '$(NCrunch)' == '1' ">false</EnableSourceLink>
11 <MSBuildWarningsAsMessages>MSB3246</MSBuildWarningsAsMessages>
12
13 <ProjectName Condition=" '$(ProjectName)' == '' ">$(MSBuildProjectName)</ProjectName>
14 <BaseOutputPath>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\))</BaseOutputPath>
15 <BaseIntermediateOutputPath>$(BaseOutputPath)obj\$(ProjectName)\</BaseIntermediateOutputPath>
16 <OutputPath>$(BaseOutputPath)$(Configuration)\</OutputPath>
17
18 <Authors>WiX Toolset Team</Authors>
19 <Company>WiX Toolset</Company>
20 <Copyright>Copyright (c) .NET Foundation and contributors. All rights reserved.</Copyright>
21 <PackageLicenseExpression>MS-RL</PackageLicenseExpression>
22 <Product>WiX Toolset</Product>
23 </PropertyGroup>
24
25 <Import Project="CSharp.Build.props" Condition=" '$(MSBuildProjectExtension)'=='.csproj' and Exists('CSharp.Build.props') " />
26 <Import Project="Cpp.Build.props" Condition=" Exists('Cpp.Build.props') And '$(MSBuildProjectExtension)'=='.vcxproj' " />
27 <Import Project="Wix.Build.props" Condition=" Exists('Wix.Build.props') And '$(MSBuildProjectExtension)'=='.wixproj' " />
28 <Import Project="Custom.Build.props" Condition=" Exists('Custom.Build.props') " />
29</Project>
diff --git a/src/test/burn/Directory.Build.targets b/src/test/burn/Directory.Build.targets
new file mode 100644
index 00000000..265b5cfd
--- /dev/null
+++ b/src/test/burn/Directory.Build.targets
@@ -0,0 +1,50 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3<!--
4 Do NOT modify this file. Update the canonical version in Home\repo-template\src\Directory.Build.targets
5 then update all of the repos.
6-->
7<!--
8 Replace PackageReferences with ProjectReferences when the projects can be found in .sln.
9 See the original here: https://github.com/dotnet/sdk/issues/1151#issuecomment-385133284
10-->
11<Project>
12 <PropertyGroup>
13 <ReplacePackageReferences>true</ReplacePackageReferences>
14 <TheSolutionPath Condition=" '$(NCrunch)'=='' ">$(SolutionPath)</TheSolutionPath>
15 <TheSolutionPath Condition=" '$(NCrunch)'=='1' ">$(NCrunchOriginalSolutionPath)</TheSolutionPath>
16 </PropertyGroup>
17
18 <Choose>
19 <When Condition="$(ReplacePackageReferences) AND '$(TheSolutionPath)' != '' AND '$(TheSolutionPath)' != '*undefined*' AND Exists('$(TheSolutionPath)')">
20
21 <PropertyGroup>
22 <SolutionFileContent>$([System.IO.File]::ReadAllText($(TheSolutionPath)))</SolutionFileContent>
23 <SmartSolutionDir>$([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) ))</SmartSolutionDir>
24 <RegexPattern>(?&lt;="[PackageName]", ")(.*)(?=", ")</RegexPattern>
25 </PropertyGroup>
26
27 <ItemGroup>
28 <!-- Keep the identity of the PackageReference -->
29 <SmartPackageReference Include="@(PackageReference)">
30 <PackageName>%(Identity)</PackageName>
31 <InSolution>$(SolutionFileContent.Contains('\%(Identity).csproj'))</InSolution>
32 </SmartPackageReference>
33
34 <!-- Filter them by mapping them to another ItemGroup using the WithMetadataValue item function -->
35 <PackageInSolution Include="@(SmartPackageReference->WithMetadataValue('InSolution', True))">
36 <Pattern>$(RegexPattern.Replace('[PackageName]','%(PackageName)') )</Pattern>
37 <SmartPath>$([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)'))</SmartPath>
38 </PackageInSolution>
39
40 <ProjectReference Include="@(PackageInSolution->'$(SmartSolutionDir)\%(SmartPath)' )"/>
41
42 <!-- Remove the package references that are now referenced as projects -->
43 <PackageReference Remove="@(PackageInSolution->'%(PackageName)' )"/>
44 </ItemGroup>
45
46 </When>
47 </Choose>
48
49 <Import Project="Wix.Build.targets" Condition=" Exists('Wix.Build.targets') And '$(MSBuildProjectExtension)'=='.wixproj' " />
50</Project>
diff --git a/src/test/burn/README.md b/src/test/burn/README.md
new file mode 100644
index 00000000..6c6e0dd9
--- /dev/null
+++ b/src/test/burn/README.md
@@ -0,0 +1,50 @@
1# integration
2
3This repo is for building installers, and then executing xunit tests that run them and verify that they worked.
4
5## Running tests
6
7The main focus of these tests is to validate behavior in a real environment.
8Depending on who you talk to, these are integration or system-level or end-to-end (E2E) tests.
9They modify machine state so it's strongly recommended *not* to run these tests on your dev box.
10They should be run on a VM instead, where you can easily roll back.
11
121. Run appveyor.cmd to build everything (the tests will refuse to run).
131. Copy the build\Release\netcoreapp3.1 folder to your VM.
141. Open a command prompt and navigate to the netcoreapp3.1 folder.
151. Run the runtests.cmd file to run the tests.
16
17You can modify the runtests.cmd to run specific tests.
18For example, the following line runs only the specified test:
19
20> dotnet test --filter WixToolsetTest.BurnE2E.BasicFunctionalityTests.CanInstallAndUninstallSimpleBundle WixToolsetTest.BurnE2E.dll
21
22The VM must have:
231. x64 .NET Core SDK of 5.0 or later (for the test runner)
241. Any version of .NET Framework (for the .NET Framework TestBA)
251. x86 .NET Core Desktop Runtime of 5.0 or later (for the .NET Core TestBA)
26
27## Updating dependencies
28
29Use the `updatepackage.ps1` script from https://github.com/wixtoolset/Home.
30For example:
31
32* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Bal.wixext -NewVersion 4.0.91
33* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Data -NewVersion 4.0.199
34* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Dependency.wixext -NewVersion 4.0.25
35* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Mba.Core -NewVersion 4.0.52
36* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.NetFx.wixext -NewVersion 4.0.67
37* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Util.wixext -NewVersion 4.0.82
38* updatepackage.ps1 -TargetFolder path\to\repo -PackageName WixToolset.Sdk -NewVersion 4.0.0-build-0204
39
40## Building with local changes
41
42The micro repo model makes this very difficult and painful.
43The basic idea is to make your changes in each individual repo on the master branch (to get a stable version), commit, and then use appveyor.cmd to build the nuget package.
44Put your custom nuget packages into a folder, and modify each repo's nuget.config with an entry to that folder.
45
46Alternatively, go into the NuGet package cache (%USERPROFILE%\.nuget\packages) and replace the official binaries with your locally built binaries.
47
48Both of those approaches will poison your NuGet package cache, so you probably will want to run the following command to clear it when you're done:
49
50> nuget locals all -clear \ No newline at end of file
diff --git a/src/test/burn/TestBA/Hresult.cs b/src/test/burn/TestBA/Hresult.cs
new file mode 100644
index 00000000..bc1aa8c0
--- /dev/null
+++ b/src/test/burn/TestBA/Hresult.cs
@@ -0,0 +1,22 @@
1// 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.
2
3namespace WixToolset.Test.BA
4{
5 using System;
6
7 /// <summary>
8 /// Utility class to work with HRESULTs
9 /// </summary>
10 internal class Hresult
11 {
12 /// <summary>
13 /// Determines if an HRESULT was a success code or not.
14 /// </summary>
15 /// <param name="status">HRESULT to verify.</param>
16 /// <returns>True if the status is a success code.</returns>
17 public static bool Succeeded(int status)
18 {
19 return status >= 0;
20 }
21 }
22}
diff --git a/src/test/burn/TestBA/MessagePump.cs b/src/test/burn/TestBA/MessagePump.cs
new file mode 100644
index 00000000..21a00349
--- /dev/null
+++ b/src/test/burn/TestBA/MessagePump.cs
@@ -0,0 +1,39 @@
1// 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.
2
3namespace WixToolset.Test.BA
4{
5 using System;
6 using System.Runtime.InteropServices;
7 using System.Windows.Forms;
8
9 public class MessagePump
10 {
11 const uint PM_REMOVE = 1;
12
13 [DllImport("user32.dll", ExactSpelling = true)]
14 [return: MarshalAs(UnmanagedType.Bool)]
15 public static extern bool PeekMessageW(ref Message pMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
16
17 [DllImport("user32.dll", ExactSpelling = true)]
18 [return: MarshalAs(UnmanagedType.Bool)]
19 public static extern bool TranslateMessage(ref Message pMsg);
20
21 [DllImport("user32.dll", ExactSpelling = true)]
22 public static extern IntPtr DispatchMessageW(ref Message pMsg);
23
24 public static void ProcessMessages(int maxMessages)
25 {
26 for (int i = 0; i < maxMessages; i++)
27 {
28 Message message = new Message();
29 if (!PeekMessageW(ref message, IntPtr.Zero, 0, 0, PM_REMOVE))
30 {
31 break;
32 }
33
34 TranslateMessage(ref message);
35 DispatchMessageW(ref message);
36 }
37 }
38 }
39}
diff --git a/src/test/burn/TestBA/TestBA.BootstrapperCore.config b/src/test/burn/TestBA/TestBA.BootstrapperCore.config
new file mode 100644
index 00000000..55876a00
--- /dev/null
+++ b/src/test/burn/TestBA/TestBA.BootstrapperCore.config
@@ -0,0 +1,18 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4
5<configuration>
6 <configSections>
7 <sectionGroup name="wix.bootstrapper" type="WixToolset.Mba.Host.BootstrapperSectionGroup, WixToolset.Mba.Host">
8 <section name="host" type="WixToolset.Mba.Host.HostSection, WixToolset.Mba.Host" />
9 </sectionGroup>
10 </configSections>
11 <startup>
12 <supportedRuntime version="v4.0" />
13 <supportedRuntime version="v2.0.50727" />
14 </startup>
15 <wix.bootstrapper>
16 <host assemblyName="TestBA" />
17 </wix.bootstrapper>
18</configuration>
diff --git a/src/test/burn/TestBA/TestBA.cs b/src/test/burn/TestBA/TestBA.cs
new file mode 100644
index 00000000..09378bc5
--- /dev/null
+++ b/src/test/burn/TestBA/TestBA.cs
@@ -0,0 +1,613 @@
1// 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.
2
3namespace WixToolset.Test.BA
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using System.Threading;
10 using System.Windows.Forms;
11 using Microsoft.Win32;
12 using WixToolset.Mba.Core;
13
14 /// <summary>
15 /// A minimal UX used for testing.
16 /// </summary>
17 public class TestBA : BootstrapperApplication
18 {
19 private const string BurnBundleVersionVariable = "WixBundleVersion";
20
21 private Form dummyWindow;
22 private IntPtr windowHandle;
23 private LaunchAction action;
24 private ManualResetEvent wait;
25 private int result;
26
27 private string updateBundlePath;
28
29 private bool immediatelyQuit;
30 private bool quitAfterDetect;
31 private bool explicitlyElevateAndPlanFromOnElevateBegin;
32 private int redetectRemaining;
33 private int sleepDuringCache;
34 private int cancelCacheAtProgress;
35 private int sleepDuringExecute;
36 private int cancelExecuteAtProgress;
37 private string cancelExecuteActionName;
38 private int cancelOnProgressAtProgress;
39 private int retryExecuteFilesInUse;
40
41 private IBootstrapperCommand Command { get; }
42
43 private IEngine Engine => this.engine;
44
45 /// <summary>
46 /// Initializes test user experience.
47 /// </summary>
48 public TestBA(IEngine engine, IBootstrapperCommand bootstrapperCommand)
49 : base(engine)
50 {
51 this.Command = bootstrapperCommand;
52 this.wait = new ManualResetEvent(false);
53 }
54
55 /// <summary>
56 /// Get the version of the install.
57 /// </summary>
58 public string Version { get; private set; }
59
60 /// <summary>
61 /// Indicates if DetectUpdate found a newer version to update.
62 /// </summary>
63 private bool UpdateAvailable { get; set; }
64
65 /// <summary>
66 /// UI Thread entry point for TestUX.
67 /// </summary>
68 protected override void OnStartup(StartupEventArgs args)
69 {
70 string immediatelyQuit = this.ReadPackageAction(null, "ImmediatelyQuit");
71 if (!String.IsNullOrEmpty(immediatelyQuit) && Boolean.TryParse(immediatelyQuit, out this.immediatelyQuit) && this.immediatelyQuit)
72 {
73 this.Engine.Quit(0);
74 return;
75 }
76
77 base.OnStartup(args);
78
79 this.action = this.Command.Action;
80 this.TestVariables();
81
82 this.Version = this.engine.GetVariableVersion(BurnBundleVersionVariable);
83 this.Log("Version: {0}", this.Version);
84
85 List<string> verifyArguments = this.ReadVerifyArguments();
86
87 foreach (string arg in this.Command.CommandLineArgs)
88 {
89 // If we're not in the update already, process the updatebundle.
90 if (this.Command.Relation != RelationType.Update && arg.StartsWith("-updatebundle:", StringComparison.OrdinalIgnoreCase))
91 {
92 this.updateBundlePath = arg.Substring(14);
93 FileInfo info = new FileInfo(this.updateBundlePath);
94 this.Engine.SetUpdate(this.updateBundlePath, null, info.Length, UpdateHashType.None, null);
95 this.UpdateAvailable = true;
96 this.action = LaunchAction.UpdateReplaceEmbedded;
97 }
98 else if (this.Command.Relation != RelationType.Update && arg.StartsWith("-checkupdate", StringComparison.OrdinalIgnoreCase))
99 {
100 this.action = LaunchAction.UpdateReplace;
101 }
102
103 verifyArguments.Remove(arg);
104 }
105 this.Log("Action: {0}", this.action);
106
107 // If there are any verification arguments left, error out.
108 if (0 < verifyArguments.Count)
109 {
110 foreach (string expectedArg in verifyArguments)
111 {
112 this.Log("Failure. Expected command-line to have argument: {0}", expectedArg);
113 }
114
115 this.Engine.Quit(-1);
116 return;
117 }
118
119 int redetectCount;
120 string redetect = this.ReadPackageAction(null, "RedetectCount");
121 if (String.IsNullOrEmpty(redetect) || !Int32.TryParse(redetect, out redetectCount))
122 {
123 redetectCount = 0;
124 }
125
126 string explicitlyElevateAndPlanFromOnElevateBegin = this.ReadPackageAction(null, "ExplicitlyElevateAndPlanFromOnElevateBegin");
127 if (String.IsNullOrEmpty(explicitlyElevateAndPlanFromOnElevateBegin) || !Boolean.TryParse(explicitlyElevateAndPlanFromOnElevateBegin, out this.explicitlyElevateAndPlanFromOnElevateBegin))
128 {
129 this.explicitlyElevateAndPlanFromOnElevateBegin = false;
130 }
131
132 string quitAfterDetect = this.ReadPackageAction(null, "QuitAfterDetect");
133 if (String.IsNullOrEmpty(quitAfterDetect) || !Boolean.TryParse(quitAfterDetect, out this.quitAfterDetect))
134 {
135 this.quitAfterDetect = false;
136 }
137
138 this.wait.WaitOne();
139
140 this.redetectRemaining = redetectCount;
141 for (int i = -1; i < redetectCount; i++)
142 {
143 this.Engine.Detect(this.windowHandle);
144 }
145 }
146
147 protected override void Run()
148 {
149 this.dummyWindow = new Form();
150 this.windowHandle = this.dummyWindow.Handle;
151
152 this.Log("Running TestBA application");
153 this.wait.Set();
154 Application.Run();
155 }
156
157 private void ShutdownUiThread()
158 {
159 if (this.dummyWindow != null)
160 {
161 this.dummyWindow.Invoke(new Action(Application.ExitThread));
162 this.dummyWindow.Dispose();
163 }
164
165 this.Engine.Quit(this.result & 0xFFFF); // return plain old Win32 error, not HRESULT.
166 }
167
168 protected override void OnDetectUpdateBegin(DetectUpdateBeginEventArgs args)
169 {
170 this.Log("OnDetectUpdateBegin");
171 if (LaunchAction.UpdateReplaceEmbedded == this.action || LaunchAction.UpdateReplace == this.action)
172 {
173 args.Skip = false;
174 }
175 }
176
177 protected override void OnDetectUpdate(DetectUpdateEventArgs e)
178 {
179 // The list of updates is sorted in descending version, so the first callback should be the largest update available.
180 // This update should be either larger than ours (so we are out of date), the same as ours (so we are current)
181 // or smaller than ours (we have a private build).
182 // Enumerate all of the updates anyway in case something's broken.
183 this.Log(String.Format("Potential update v{0} from '{1}'; current version: v{2}", e.Version, e.UpdateLocation, this.Version));
184 if (!this.UpdateAvailable && this.Engine.CompareVersions(e.Version, this.Version) > 0)
185 {
186 this.Log(String.Format("Selected update v{0}", e.Version));
187 this.Engine.SetUpdate(null, e.UpdateLocation, e.Size, UpdateHashType.None, null);
188 this.UpdateAvailable = true;
189 }
190 }
191
192 protected override void OnDetectUpdateComplete(DetectUpdateCompleteEventArgs e)
193 {
194 this.Log("OnDetectUpdateComplete");
195
196 // Failed to process an update, allow the existing bundle to still install.
197 if (!Hresult.Succeeded(e.Status))
198 {
199 this.Log(String.Format("Failed to locate an update, status of 0x{0:X8}, updates disabled.", e.Status));
200 e.IgnoreError = true; // But continue on...
201 }
202 }
203
204 protected override void OnDetectComplete(DetectCompleteEventArgs args)
205 {
206 this.result = args.Status;
207
208 if (Hresult.Succeeded(this.result) &&
209 (this.UpdateAvailable || LaunchAction.UpdateReplaceEmbedded != this.action && LaunchAction.UpdateReplace != this.action))
210 {
211 if (this.redetectRemaining > 0)
212 {
213 this.Log("Completed detection phase: {0} re-runs remaining", this.redetectRemaining--);
214 }
215 else if (this.quitAfterDetect)
216 {
217 this.ShutdownUiThread();
218 }
219 else if (this.explicitlyElevateAndPlanFromOnElevateBegin)
220 {
221 this.Engine.Elevate(this.windowHandle);
222 }
223 else
224 {
225 this.Engine.Plan(this.action);
226 }
227 }
228 else
229 {
230 this.ShutdownUiThread();
231 }
232 }
233
234 protected override void OnDetectRelatedBundle(DetectRelatedBundleEventArgs args)
235 {
236 this.Log("OnDetectRelatedBundle() - id: {0}, missing from cache: {1}", args.ProductCode, args.MissingFromCache);
237 }
238
239 protected override void OnElevateBegin(ElevateBeginEventArgs args)
240 {
241 if (this.explicitlyElevateAndPlanFromOnElevateBegin)
242 {
243 this.Engine.Plan(this.action);
244
245 // Simulate showing some UI since these tests won't actually show the UAC prompt.
246 MessagePump.ProcessMessages(10);
247 }
248 }
249
250 protected override void OnPlanPackageBegin(PlanPackageBeginEventArgs args)
251 {
252 RequestState state;
253 string action = this.ReadPackageAction(args.PackageId, "Requested");
254 if (TryParseEnum<RequestState>(action, out state))
255 {
256 args.State = state;
257 }
258 }
259
260 protected override void OnPlanPatchTarget(PlanPatchTargetEventArgs args)
261 {
262 RequestState state;
263 string action = this.ReadPackageAction(args.PackageId, "Requested");
264 if (TryParseEnum<RequestState>(action, out state))
265 {
266 args.State = state;
267 }
268 }
269
270 protected override void OnPlanMsiFeature(PlanMsiFeatureEventArgs args)
271 {
272 FeatureState state;
273 string action = this.ReadFeatureAction(args.PackageId, args.FeatureId, "Requested");
274 if (TryParseEnum<FeatureState>(action, out state))
275 {
276 args.State = state;
277 }
278 }
279
280 protected override void OnPlanComplete(PlanCompleteEventArgs args)
281 {
282 this.result = args.Status;
283 if (Hresult.Succeeded(this.result))
284 {
285 this.Engine.Apply(this.windowHandle);
286 }
287 else
288 {
289 this.ShutdownUiThread();
290 }
291 }
292
293 protected override void OnCachePackageBegin(CachePackageBeginEventArgs args)
294 {
295 this.Log("OnCachePackageBegin() - package: {0}, payloads to cache: {1}", args.PackageId, args.CachePayloads);
296
297 string slowProgress = this.ReadPackageAction(args.PackageId, "SlowCache");
298 if (String.IsNullOrEmpty(slowProgress) || !Int32.TryParse(slowProgress, out this.sleepDuringCache))
299 {
300 this.sleepDuringCache = 0;
301 }
302 else
303 {
304 this.Log(" SlowCache: {0}", this.sleepDuringCache);
305 }
306
307 string cancelCache = this.ReadPackageAction(args.PackageId, "CancelCacheAtProgress");
308 if (String.IsNullOrEmpty(cancelCache) || !Int32.TryParse(cancelCache, out this.cancelCacheAtProgress))
309 {
310 this.cancelCacheAtProgress = -1;
311 }
312 else
313 {
314 this.Log(" CancelCacheAtProgress: {0}", this.cancelCacheAtProgress);
315 }
316 }
317
318 protected override void OnCacheAcquireProgress(CacheAcquireProgressEventArgs args)
319 {
320 this.Log("OnCacheAcquireProgress() - container/package: {0}, payload: {1}, progress: {2}, total: {3}, overall progress: {4}%", args.PackageOrContainerId, args.PayloadId, args.Progress, args.Total, args.OverallPercentage);
321
322 if (this.cancelCacheAtProgress >= 0 && this.cancelCacheAtProgress <= args.Progress)
323 {
324 args.Cancel = true;
325 this.Log("OnCacheAcquireProgress(cancel)");
326 }
327 else if (this.sleepDuringCache > 0)
328 {
329 this.Log("OnCacheAcquireProgress(sleep {0})", this.sleepDuringCache);
330 Thread.Sleep(this.sleepDuringCache);
331 }
332 }
333
334 protected override void OnCacheContainerOrPayloadVerifyProgress(CacheContainerOrPayloadVerifyProgressEventArgs args)
335 {
336 this.Log("OnCacheContainerOrPayloadVerifyProgress() - container/package: {0}, payload: {1}, progress: {2}, total: {3}, overall progress: {4}%", args.PackageOrContainerId, args.PayloadId, args.Progress, args.Total, args.OverallPercentage);
337 }
338
339 protected override void OnCachePayloadExtractProgress(CachePayloadExtractProgressEventArgs args)
340 {
341 this.Log("OnCachePayloadExtractProgress() - container/package: {0}, payload: {1}, progress: {2}, total: {3}, overall progress: {4}%", args.PackageOrContainerId, args.PayloadId, args.Progress, args.Total, args.OverallPercentage);
342 }
343
344 protected override void OnCacheVerifyProgress(CacheVerifyProgressEventArgs args)
345 {
346 this.Log("OnCacheVerifyProgress() - container/package: {0}, payload: {1}, progress: {2}, total: {3}, overall progress: {4}%, step: {5}", args.PackageOrContainerId, args.PayloadId, args.Progress, args.Total, args.OverallPercentage, args.Step);
347 }
348
349 protected override void OnExecutePackageBegin(ExecutePackageBeginEventArgs args)
350 {
351 this.Log("OnExecutePackageBegin() - package: {0}, rollback: {1}", args.PackageId, !args.ShouldExecute);
352
353 string slowProgress = this.ReadPackageAction(args.PackageId, "SlowExecute");
354 if (String.IsNullOrEmpty(slowProgress) || !Int32.TryParse(slowProgress, out this.sleepDuringExecute))
355 {
356 this.sleepDuringExecute = 0;
357 }
358 else
359 {
360 this.Log(" SlowExecute: {0}", this.sleepDuringExecute);
361 }
362
363 string cancelExecute = this.ReadPackageAction(args.PackageId, "CancelExecuteAtProgress");
364 if (String.IsNullOrEmpty(cancelExecute) || !Int32.TryParse(cancelExecute, out this.cancelExecuteAtProgress))
365 {
366 this.cancelExecuteAtProgress = -1;
367 }
368 else
369 {
370 this.Log(" CancelExecuteAtProgress: {0}", this.cancelExecuteAtProgress);
371 }
372
373 this.cancelExecuteActionName = this.ReadPackageAction(args.PackageId, "CancelExecuteAtActionStart");
374 if (!String.IsNullOrEmpty(this.cancelExecuteActionName))
375 {
376 this.Log(" CancelExecuteAtActionState: {0}", this.cancelExecuteActionName);
377 }
378
379 string cancelOnProgressAtProgress = this.ReadPackageAction(args.PackageId, "CancelOnProgressAtProgress");
380 if (String.IsNullOrEmpty(cancelOnProgressAtProgress) || !Int32.TryParse(cancelOnProgressAtProgress, out this.cancelOnProgressAtProgress))
381 {
382 this.cancelOnProgressAtProgress = -1;
383 }
384 else
385 {
386 this.Log(" CancelOnProgressAtProgress: {0}", this.cancelOnProgressAtProgress);
387 }
388
389 string retryBeforeCancel = this.ReadPackageAction(args.PackageId, "RetryExecuteFilesInUse");
390 if (String.IsNullOrEmpty(retryBeforeCancel) || !Int32.TryParse(retryBeforeCancel, out this.retryExecuteFilesInUse))
391 {
392 this.retryExecuteFilesInUse = 0;
393 }
394 else
395 {
396 this.Log(" RetryExecuteFilesInUse: {0}", this.retryExecuteFilesInUse);
397 }
398 }
399
400 protected override void OnExecuteFilesInUse(ExecuteFilesInUseEventArgs args)
401 {
402 this.Log("OnExecuteFilesInUse() - package: {0}, retries remaining: {1}, data: {2}", args.PackageId, this.retryExecuteFilesInUse, String.Join(", ", args.Files.ToArray()));
403
404 if (this.retryExecuteFilesInUse > 0)
405 {
406 --this.retryExecuteFilesInUse;
407 args.Result = Result.Retry;
408 }
409 else
410 {
411 args.Result = Result.Abort;
412 }
413 }
414
415 protected override void OnExecuteMsiMessage(ExecuteMsiMessageEventArgs args)
416 {
417 this.Log("OnExecuteMsiMessage() - MessageType: {0}, Message: {1}, Data: '{2}'", args.MessageType, args.Message, String.Join("','", args.Data.ToArray()));
418
419 if (!String.IsNullOrEmpty(this.cancelExecuteActionName) && args.MessageType == InstallMessage.ActionStart &&
420 args.Data.Count > 0 && args.Data[0] == this.cancelExecuteActionName)
421 {
422 this.Log("OnExecuteMsiMessage(cancelNextProgress)");
423 this.cancelExecuteAtProgress = 0;
424 }
425 }
426
427 protected override void OnExecuteProgress(ExecuteProgressEventArgs args)
428 {
429 this.Log("OnExecuteProgress() - package: {0}, progress: {1}%, overall progress: {2}%", args.PackageId, args.ProgressPercentage, args.OverallPercentage);
430
431 if (this.cancelExecuteAtProgress >= 0 && this.cancelExecuteAtProgress <= args.ProgressPercentage)
432 {
433 args.Cancel = true;
434 this.Log("OnExecuteProgress(cancel)");
435 }
436 else if (this.sleepDuringExecute > 0)
437 {
438 this.Log("OnExecuteProgress(sleep {0})", this.sleepDuringExecute);
439 Thread.Sleep(this.sleepDuringExecute);
440 }
441 }
442
443 protected override void OnExecutePatchTarget(ExecutePatchTargetEventArgs args)
444 {
445 this.Log("OnExecutePatchTarget - Patch Package: {0}, Target Product Code: {1}", args.PackageId, args.TargetProductCode);
446 }
447
448 protected override void OnProgress(ProgressEventArgs args)
449 {
450 this.Log("OnProgress() - progress: {0}%, overall progress: {1}%", args.ProgressPercentage, args.OverallPercentage);
451 if (this.Command.Display == Display.Embedded)
452 {
453 this.Engine.SendEmbeddedProgress(args.ProgressPercentage, args.OverallPercentage);
454 }
455
456 if (this.cancelOnProgressAtProgress >= 0 && this.cancelOnProgressAtProgress <= args.OverallPercentage)
457 {
458 args.Cancel = true;
459 this.Log("OnProgress(cancel)");
460 }
461 }
462
463 protected override void OnApplyBegin(ApplyBeginEventArgs args)
464 {
465 this.cancelOnProgressAtProgress = -1;
466 this.cancelExecuteAtProgress = -1;
467 this.cancelCacheAtProgress = -1;
468 }
469
470 protected override void OnApplyComplete(ApplyCompleteEventArgs args)
471 {
472 // Output what the privileges are now.
473 this.Log("After elevation: WixBundleElevated = {0}", this.Engine.GetVariableNumeric("WixBundleElevated"));
474
475 this.result = args.Status;
476 this.ShutdownUiThread();
477 }
478
479 protected override void OnSystemShutdown(SystemShutdownEventArgs args)
480 {
481 // Always prevent shutdown.
482 this.Log("Disallowed system request to shut down the bootstrapper application.");
483 args.Cancel = true;
484
485 this.ShutdownUiThread();
486 }
487
488 private void TestVariables()
489 {
490 // First make sure we can check and get standard variables of each type.
491 {
492 string value = null;
493 if (this.Engine.ContainsVariable("WindowsFolder"))
494 {
495 value = this.Engine.GetVariableString("WindowsFolder");
496 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a string variable: WindowsFolder");
497 }
498 else
499 {
500 throw new Exception("Engine did not define a standard variable: WindowsFolder");
501 }
502 }
503
504 {
505 long value = 0;
506 if (this.Engine.ContainsVariable("NTProductType"))
507 {
508 value = this.Engine.GetVariableNumeric("NTProductType");
509 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a numeric variable: NTProductType");
510 }
511 else
512 {
513 throw new Exception("Engine did not define a standard variable: NTProductType");
514 }
515 }
516
517 {
518 string value = null;
519 if (this.Engine.ContainsVariable("VersionMsi"))
520 {
521 value = this.Engine.GetVariableVersion("VersionMsi");
522 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully retrieved a version variable: VersionMsi");
523 }
524 else
525 {
526 throw new Exception("Engine did not define a standard variable: VersionMsi");
527 }
528 }
529
530 // Now validate that Contians returns false for non-existant variables of each type.
531 if (this.Engine.ContainsVariable("TestStringVariableShouldNotExist"))
532 {
533 throw new Exception("Engine defined a variable that should not exist: TestStringVariableShouldNotExist");
534 }
535 else
536 {
537 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully checked for non-existent string variable: TestStringVariableShouldNotExist");
538 }
539
540 if (this.Engine.ContainsVariable("TestNumericVariableShouldNotExist"))
541 {
542 throw new Exception("Engine defined a variable that should not exist: TestNumericVariableShouldNotExist");
543 }
544 else
545 {
546 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully checked for non-existent numeric variable: TestNumericVariableShouldNotExist");
547 }
548
549 if (this.Engine.ContainsVariable("TestVersionVariableShouldNotExist"))
550 {
551 throw new Exception("Engine defined a variable that should not exist: TestVersionVariableShouldNotExist");
552 }
553 else
554 {
555 this.Engine.Log(LogLevel.Verbose, "TEST: Successfully checked for non-existent version variable: TestVersionVariableShouldNotExist");
556 }
557
558 // Output what the initially run privileges were.
559 this.Engine.Log(LogLevel.Verbose, String.Format("TEST: WixBundleElevated = {0}", this.Engine.GetVariableNumeric("WixBundleElevated")));
560 }
561
562 private void Log(string format, params object[] args)
563 {
564 string relation = this.Command.Relation != RelationType.None ? String.Concat(" (", this.Command.Relation.ToString().ToLowerInvariant(), ")") : String.Empty;
565 string message = String.Format(format, args);
566
567 this.Engine.Log(LogLevel.Standard, String.Concat("TESTBA", relation, ": ", message));
568 }
569
570 private List<string> ReadVerifyArguments()
571 {
572 string testName = this.Engine.GetVariableString("TestGroupName");
573 using (RegistryKey testKey = Registry.LocalMachine.OpenSubKey(String.Format(@"Software\WiX\Tests\TestBAControl\{0}", testName)))
574 {
575 string verifyArguments = testKey == null ? null : testKey.GetValue("VerifyArguments") as string;
576 return verifyArguments == null ? new List<string>() : new List<string>(verifyArguments.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
577 }
578 }
579
580 private string ReadPackageAction(string packageId, string state)
581 {
582 string testName = this.Engine.GetVariableString("TestGroupName");
583 using (RegistryKey testKey = Registry.LocalMachine.OpenSubKey(String.Format(@"Software\WiX\Tests\TestBAControl\{0}\{1}", testName, String.IsNullOrEmpty(packageId) ? String.Empty : packageId)))
584 {
585 return testKey == null ? null : testKey.GetValue(state) as string;
586 }
587 }
588
589 private string ReadFeatureAction(string packageId, string featureId, string state)
590 {
591 string testName = this.Engine.GetVariableString("TestGroupName");
592 using (RegistryKey testKey = Registry.LocalMachine.OpenSubKey(String.Format(@"Software\WiX\Tests\TestBAControl\{0}\{1}", testName, packageId)))
593 {
594 string registryName = String.Concat(featureId, state);
595 return testKey == null ? null : testKey.GetValue(registryName) as string;
596 }
597 }
598
599 private static bool TryParseEnum<T>(string value, out T t)
600 {
601 try
602 {
603 t = (T)Enum.Parse(typeof(T), value, true);
604 return true;
605 }
606 catch (ArgumentException) { }
607 catch (OverflowException) { }
608
609 t = default(T);
610 return false;
611 }
612 }
613}
diff --git a/src/test/burn/TestBA/TestBA.csproj b/src/test/burn/TestBA/TestBA.csproj
new file mode 100644
index 00000000..74df28dc
--- /dev/null
+++ b/src/test/burn/TestBA/TestBA.csproj
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFrameworks>net35;net5.0-windows</TargetFrameworks>
7 <AssemblyName>TestBA</AssemblyName>
8 <RootNamespace>WixToolset.Test.BA</RootNamespace>
9 <DebugType>embedded</DebugType>
10 <RuntimeIdentifier>win-x86</RuntimeIdentifier>
11 <EnableDynamicLoading>true</EnableDynamicLoading>
12 <UseWindowsForms>true</UseWindowsForms>
13 <RollForward>Major</RollForward>
14 </PropertyGroup>
15
16 <ItemGroup Condition=" '$(TargetFramework)'=='net35' ">
17 <Content Include="TestBA.BootstrapperCore.config" CopyToOutputDirectory="PreserveNewest" />
18 <Reference Include="System.Windows.Forms" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <PackageReference Include="WixToolset.Mba.Core" Version="4.0.58" />
23 </ItemGroup>
24</Project> \ No newline at end of file
diff --git a/src/test/burn/TestBA/TestBAFactory.cs b/src/test/burn/TestBA/TestBAFactory.cs
new file mode 100644
index 00000000..ba1de367
--- /dev/null
+++ b/src/test/burn/TestBA/TestBAFactory.cs
@@ -0,0 +1,22 @@
1// 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.
2
3[assembly: WixToolset.Mba.Core.BootstrapperApplicationFactory(typeof(WixToolset.Test.BA.TestBAFactory))]
4namespace WixToolset.Test.BA
5{
6 using WixToolset.Mba.Core;
7
8 public class TestBAFactory : BaseBootstrapperApplicationFactory
9 {
10 private static int loadCount = 0;
11
12 protected override IBootstrapperApplication Create(IEngine engine, IBootstrapperCommand bootstrapperCommand)
13 {
14 if (loadCount > 0)
15 {
16 engine.Log(LogLevel.Standard, $"Reloaded {loadCount} time(s)");
17 }
18 ++loadCount;
19 return new TestBA(engine, bootstrapperCommand);
20 }
21 }
22}
diff --git a/src/test/burn/TestBA/TestBA_x64.csproj b/src/test/burn/TestBA/TestBA_x64.csproj
new file mode 100644
index 00000000..1368e0f0
--- /dev/null
+++ b/src/test/burn/TestBA/TestBA_x64.csproj
@@ -0,0 +1,24 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFrameworks>net35;net5.0-windows</TargetFrameworks>
7 <AssemblyName>TestBA</AssemblyName>
8 <RootNamespace>WixToolset.Test.BA</RootNamespace>
9 <DebugType>embedded</DebugType>
10 <RuntimeIdentifier>win-x64</RuntimeIdentifier>
11 <EnableDynamicLoading>true</EnableDynamicLoading>
12 <UseWindowsForms>true</UseWindowsForms>
13 <RollForward>Major</RollForward>
14 </PropertyGroup>
15
16 <ItemGroup Condition=" '$(TargetFramework)'=='net35' ">
17 <Content Include="TestBA.BootstrapperCore.config" CopyToOutputDirectory="PreserveNewest" />
18 <Reference Include="System.Windows.Forms" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <PackageReference Include="WixToolset.Mba.Core" Version="4.0.58" />
23 </ItemGroup>
24</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..591272b3
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wixproj
@@ -0,0 +1,17 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>hyperlinkLicense</BA>
6 <UpgradeCode>{8C7E2C47-1EE7-4BBE-99A2-EAB7F3693F48}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 </ItemGroup>
17</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wxs b/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..bd164a29
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleA/BundleA.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wixproj
new file mode 100644
index 00000000..3f405ce5
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <InstallerPlatform>x64</InstallerPlatform>
6 <BA>hyperlinkLicense</BA>
7 <UpgradeCode>{6E86B95A-24F6-4C89-AF2E-470C0C734FCB}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\PackageA_x64\PackageA_x64.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wxs b/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wxs
new file mode 100644
index 00000000..d34e51b6
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleA_x64/BundleA_x64.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA_x64" SourceFile="$(var.PackageA_x64.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..8ea9afe0
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleB/BundleB.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{02258734-E25E-4A2C-AFC5-55C34F1994CB}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 <Compile Include="..\BundleA\BundleA.wxs" Link="BundleB.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleB_x64/BundleB_x64.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleB_x64/BundleB_x64.wixproj
new file mode 100644
index 00000000..1b1a5006
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleB_x64/BundleB_x64.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>TestBA_x64</BA>
6 <UpgradeCode>{79F45B7A-D990-46E4-819B-078D87C3321A}</UpgradeCode>
7 <InstallerPlatform>x64</InstallerPlatform>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 <Compile Include="..\BundleA_x64\BundleA_x64.wxs" Link="BundleB_x64.wxs" />
12 </ItemGroup>
13 <ItemGroup>
14 <ProjectReference Include="..\PackageA_x64\PackageA_x64.wixproj" />
15 <ProjectReference Include="..\..\TestBA\TestBAWixlib_x64\testbawixlib_x64.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..104a6003
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleC/BundleC.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>TestBAdnc</BA>
6 <UpgradeCode>{DD790BAA-FE9F-4B0D-8AF4-DE4E1D674637}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 <Compile Include="..\BundleA\BundleA.wxs" Link="BundleC.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/BundleC_x64/BundleC_x64.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/BundleC_x64/BundleC_x64.wixproj
new file mode 100644
index 00000000..3b9d7360
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/BundleC_x64/BundleC_x64.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>TestBAdnc_x64</BA>
6 <UpgradeCode>{638D31D0-92BA-4BCD-82F0-7F549820D9AB}</UpgradeCode>
7 <InstallerPlatform>x64</InstallerPlatform>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 <Compile Include="..\BundleA_x64\BundleA_x64.wxs" Link="BundleC_x64.wxs" />
12 </ItemGroup>
13 <ItemGroup>
14 <ProjectReference Include="..\PackageA_x64\PackageA_x64.wixproj" />
15 <ProjectReference Include="..\..\TestBA\TestBAWixlib_x64\testbawixlib_x64.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..9943717c
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/PackageA/PackageA.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <CabPrefix>a</CabPrefix>
5 <UpgradeCode>{7FD50F1B-D134-4365-923C-DFA160F74738}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/BasicFunctionalityTests/PackageA_x64/PackageA_x64.wixproj b/src/test/burn/TestData/BasicFunctionalityTests/PackageA_x64/PackageA_x64.wixproj
new file mode 100644
index 00000000..8dbab284
--- /dev/null
+++ b/src/test/burn/TestData/BasicFunctionalityTests/PackageA_x64/PackageA_x64.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <CabPrefix>a_x64</CabPrefix>
5 <UpgradeCode>{BDB9EF6A-B2DE-4929-9BE3-0CD71BDAEF6E}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/CacheTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/CacheTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..360bcf86
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleA/BundleA.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{C48D0F58-0F8F-461D-A60D-D83E5F35BA8E}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/CacheTests/BundleA/BundleA.wxs b/src/test/burn/TestData/CacheTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..20262187
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleA/BundleA.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" DownloadUrl="$(var.WebServerBaseUrl)BundleA/{2}" />
8 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" DownloadUrl="$(var.WebServerBaseUrl)BundleA/{2}" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/CacheTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/CacheTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..698b1d62
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleB/BundleB.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{3CC71AD2-39F3-4803-A24C-6E6A492B721C}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/CacheTests/BundleB/BundleB.wxs b/src/test/burn/TestData/CacheTests/BundleB/BundleB.wxs
new file mode 100644
index 00000000..95e714ec
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleB/BundleB.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/CacheTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/CacheTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..0acc29c4
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleC/BundleC.wixproj
@@ -0,0 +1,26 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{997BDF9A-2540-42DB-8F86-296BA243194B}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18 <!-- We do this dynamically to avoid committing such a large file to source control. -->
19 <Target Name="CreateLargeFile" AfterTargets="BeforeBuild" Inputs="$(MSBuildProjectFullPath)" Outputs="$(MSBuildProjectDirectory)\fivegb.file">
20 <Exec Command='"$(BaseOutputPath)$(Configuration)\netcoreapp3.1\win-x86\testexe.exe" /lf "fivegb.file|5368709120' WorkingDirectory="$(MSBuildProjectDirectory)" />
21 </Target>
22 <!-- We do this to avoid copying such a large file to the VM to run the tests. -->
23 <Target Name="DeleteLargeFile" AfterTargets="AfterBuild">
24 <Delete Files="$(OutputPath)fivegb.file" />
25 </Target>
26</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/CacheTests/BundleC/BundleC.wxs b/src/test/burn/TestData/CacheTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..ca21cc6e
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/BundleC/BundleC.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)">
8 <Payload SourceFile="fivegb.file" Compressed="no" />
9 </MsiPackage>
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/CacheTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/CacheTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..dd8176ed
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{5D0BD93A-D1D8-4F59-8417-1390B18A6611}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/CacheTests/PackageB/PackageB.wixproj b/src/test/burn/TestData/CacheTests/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..efc57bb6
--- /dev/null
+++ b/src/test/burn/TestData/CacheTests/PackageB/PackageB.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{ADCE5902-224D-4C87-BA31-2D154B37EE22}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv1/BundleA.props b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..256501c7
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleA.props
@@ -0,0 +1,11 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BundleName>BundleA</BundleName>
6 <UpgradeCode>{6950EF3F-674E-4689-A5C8-80D12AB6E34F}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11</Project>
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..3f7882cf
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,16 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <PropertyGroup>
5 <Version>1.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..9218e823
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,21 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
6 <Fragment>
7 <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" />
8
9 <PackageGroup Id="BundlePackages">
10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
11 <ExePackage Id="ExeA" Cache="no" PerMachine="yes"
12 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)"
13 InstallArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
14 RepairArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
15 UninstallArguments="/regd &quot;HKLM\$(var.TestExeRegistryKey),Version&quot;">
16 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
17 <PayloadGroupRef Id="TestExePayloads" />
18 </ExePackage>
19 </PackageGroup>
20 </Fragment>
21</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wixproj b/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wixproj
new file mode 100644
index 00000000..e71ef750
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wixproj
@@ -0,0 +1,16 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wxs b/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wxs
new file mode 100644
index 00000000..1590574f
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleAv1_0_1/BundleAv1_0_1.wxs
@@ -0,0 +1,21 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
6 <Fragment>
7 <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" />
8
9 <PackageGroup Id="BundlePackages">
10 <MsiPackage Id="PackageA" Name="PackageAv1.msi" SourceFile="$(var.PackageAv1_0_1.TargetPath)" />
11 <ExePackage Id="ExeA" Cache="no" PerMachine="yes"
12 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)"
13 InstallArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
14 RepairArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
15 UninstallArguments="/regd &quot;HKLM\$(var.TestExeRegistryKey),Version&quot;">
16 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
17 <PayloadGroupRef Id="TestExePayloads" />
18 </ExePackage>
19 </PackageGroup>
20 </Fragment>
21</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleB/Bundle.wxs b/src/test/burn/TestData/DependencyTests/BundleB/Bundle.wxs
new file mode 100644
index 00000000..8d2dce60
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleB/Bundle.wxs
@@ -0,0 +1,40 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <!-- ProviderKey should be the only thing different from the template -->
9 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProviderKey="WiX.$(var.TestGroupName).$(var.BundleName).B">
10 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
11
12 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
13
14 <?ifdef SoftwareTag?>
15 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
16 <?endif?>
17
18 <?ifndef BA?>
19 <!-- pulled in through the PackageGroupRef below -->
20 <?elseif $(var.BA) = "TestBAdnc"?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "hyperlinkLicense"?>
23 <BootstrapperApplication>
24 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
25 </BootstrapperApplication>
26 <?else?>
27 <BootstrapperApplicationRef Id="$(var.BA)" />
28 <?endif?>
29
30 <Chain>
31 <?ifndef BA?>
32 <PackageGroupRef Id="TestBA" />
33 <?elseif $(var.BA) = "TestBAdnc"?>
34 <PackageGroupRef Id="TestBAdnc" />
35 <?endif?>
36
37 <PackageGroupRef Id="BundlePackages" />
38 </Chain>
39 </Bundle>
40</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..58a613d6
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{228859BB-F917-4F43-A1E0-50C8DCCA92EF}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
11 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
12 </ItemGroup>
13 <ItemGroup>
14 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
15 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
16 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wxs b/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wxs
new file mode 100644
index 00000000..026100fa
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleB/BundleB.wxs
@@ -0,0 +1,22 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
6 <Fragment>
7 <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" />
8
9 <PackageGroup Id="BundlePackages">
10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
11 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
12 <ExePackage Id="ExeA" Cache="no" PerMachine="yes"
13 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)"
14 InstallArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
15 RepairArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
16 UninstallArguments="/regd &quot;HKLM\$(var.TestExeRegistryKey),Version&quot;">
17 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
18 <PayloadGroupRef Id="TestExePayloads" />
19 </ExePackage>
20 </PackageGroup>
21 </Fragment>
22</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..ffa7e897
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wixproj
@@ -0,0 +1,22 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <!-- Same as BundleA -->
6 <UpgradeCode>{6950EF3F-674E-4689-A5C8-80D12AB6E34F}</UpgradeCode>
7 <Version>1.0.1.0</Version>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
14 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
15 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
20 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
21 </ItemGroup>
22</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wxs b/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..2ce8ed44
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleC/BundleC.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)">
7 <SlipstreamMsp Id="PatchA"/>
8 </MsiPackage>
9 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" />
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wixproj b/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wixproj
new file mode 100644
index 00000000..6de1c0c1
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wixproj
@@ -0,0 +1,22 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <!-- Same as BundleA -->
6 <UpgradeCode>{6950EF3F-674E-4689-A5C8-80D12AB6E34F}</UpgradeCode>
7 <Version>1.0.1.0</Version>
8 <SuppressSpecificWarnings>1153</SuppressSpecificWarnings>
9 </PropertyGroup>
10 <ItemGroup>
11 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
12 </ItemGroup>
13 <ItemGroup>
14 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
15 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
20 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
21 </ItemGroup>
22</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wxs b/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wxs
new file mode 100644
index 00000000..8ee40558
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleD/BundleD.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
7 <ExePackage Id="TestExe" Cache="no" PerMachine="yes" Permanent="yes" InstallArguments="/ec 1603">
8 <PayloadGroupRef Id="TestExePayloads" />
9 </ExePackage>
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wixproj b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wixproj
new file mode 100644
index 00000000..cd4e89ca
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{250B4261-E67F-47E0-AB15-209EF58B769D}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
13 <ProjectReference Include="..\PackageC\PackageC.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs
new file mode 100644
index 00000000..204e66ab
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs
@@ -0,0 +1,19 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
6 <Fragment>
7 <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" />
8
9 <PackageGroup Id="BundlePackages">
10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
11 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Vital="no" />
12 <ExePackage Id="ExeA" Cache="no" Vital="no" PerMachine="yes" InstallArguments="/ec 1603"
13 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)">
14 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
15 <PayloadGroupRef Id="TestExePayloads" />
16 </ExePackage>
17 </PackageGroup>
18 </Fragment>
19</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj
new file mode 100644
index 00000000..33154672
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{EC2B2B3F-E57C-45A4-A0E8-762156DAD99D}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
13 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs
new file mode 100644
index 00000000..1347836a
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF/BundleF.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <RelatedBundle Id="583B5ECB-04E6-4837-A30C-A1ADCBE24235" Action="Detect" />
6
7 <PackageGroup Id="BundlePackages">
8 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
9 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs
new file mode 100644
index 00000000..c8ca4a3f
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOn.wxs
@@ -0,0 +1,22 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
6 <Fragment>
7 <RelatedBundle Id="583B5ECB-04E6-4837-A30C-A1ADCBE24235" Action="Addon" />
8 <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" />
9
10 <PackageGroup Id="BundlePackages">
11 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
12 <ExePackage Id="ExeA" Cache="no" PerMachine="yes"
13 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)"
14 InstallArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
15 RepairArguments="/regw &quot;HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)&quot;"
16 UninstallArguments="/regd &quot;HKLM\$(var.TestExeRegistryKey),Version&quot;">
17 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
18 <PayloadGroupRef Id="TestExePayloads" />
19 </ExePackage>
20 </PackageGroup>
21 </Fragment>
22</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj
new file mode 100644
index 00000000..a0708443
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnA/BundleF_AddOnA.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{022D0F5D-D140-47E1-A19A-5B2CEEE52668}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj
new file mode 100644
index 00000000..3c09fd2c
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_AddOnB/BundleF_AddOnB.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{8AB16F34-CA65-46E1-BDC0-08F157B4781C}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\BundleF_AddOnA\BundleF_AddOn.wxs" Link="BundleF_AddOn.wxs" />
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchA.props b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchA.props
new file mode 100644
index 00000000..cbc025ef
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchA.props
@@ -0,0 +1,11 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BundleName>BundleF_PatchA</BundleName>
6 <UpgradeCode>{90F41437-BEF8-4ED8-8902-C5DED74E4F6C}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11</Project>
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wixproj
new file mode 100644
index 00000000..c7d907a2
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wixproj
@@ -0,0 +1,16 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleF_PatchA.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wxs b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wxs
new file mode 100644
index 00000000..8ef8a351
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_1/BundleF_PatchAv1_0_1.wxs
@@ -0,0 +1,13 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <RelatedBundle Id="{EC2B2B3F-E57C-45A4-A0E8-762156DAD99D}" Action="Patch" />
6
7 <PackageGroup Id="BundlePackages">
8 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" PerMachine="yes">
9 <Provides Key="$(var.TestGroupName)_PatchA" Version="$(var.Version)" />
10 </MspPackage>
11 </PackageGroup>
12 </Fragment>
13</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wixproj b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wixproj
new file mode 100644
index 00000000..949309dc
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wixproj
@@ -0,0 +1,17 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleF_PatchAv1_0_1\BundleF_PatchA.props" />
4 <PropertyGroup>
5 <Version>1.0.2.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
9 <ProjectReference Include="..\PatchB\PatchB.wixproj" />
10 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
14 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
15 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
16 </ItemGroup>
17</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wxs b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wxs
new file mode 100644
index 00000000..2b47d5ed
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleF_PatchAv1_0_2/BundleF_PatchAv1_0_2.wxs
@@ -0,0 +1,16 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <RelatedBundle Id="{EC2B2B3F-E57C-45A4-A0E8-762156DAD99D}" Action="Patch" />
6
7 <PackageGroup Id="BundlePackages">
8 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" PerMachine="yes">
9 <Provides Key="$(var.TestGroupName)_PatchA" Version="$(var.Version)" />
10 </MspPackage>
11 <MspPackage Id="PatchB" SourceFile="$(var.PatchB.TargetPath)" PerMachine="yes">
12 <Provides Key="$(var.TestGroupName)_PatchB" Version="$(var.Version)" />
13 </MspPackage>
14 </PackageGroup>
15 </Fragment>
16</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleHv1/BundleH.props b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleH.props
new file mode 100644
index 00000000..14801ec3
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleH.props
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{C5EA6B61-EF32-48E0-A6F9-08EB6D096843}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10</Project>
diff --git a/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wixproj b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wixproj
new file mode 100644
index 00000000..6ff25fcb
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleH.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
6 <ProjectReference Include="..\PackageDv1\PackageDv1.wixproj" />
7 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
11 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wxs b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wxs
new file mode 100644
index 00000000..b553d829
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleHv1/BundleHv1.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" Visible="yes" Permanent="yes" />
8 <MsiPackage Id="PackageD" SourceFile="$(var.PackageDv1.TargetPath)" Visible="yes" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wixproj b/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wixproj
new file mode 100644
index 00000000..794e72bc
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wixproj
@@ -0,0 +1,16 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleHv1\BundleH.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
9 <ProjectReference Include="..\PackageDv2\PackageDv2.wixproj" />
10 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
14 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wxs b/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wxs
new file mode 100644
index 00000000..690f8e7a
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleHv2/BundleHv2.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" Visible="yes" Permanent="yes" />
8 <MsiPackage Id="PackageD" SourceFile="$(var.PackageDv2.TargetPath)" Visible="yes" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wixproj b/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wixproj
new file mode 100644
index 00000000..85fd0f92
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{37BDF884-C24A-4C12-9D0C-421FC30747F2}</UpgradeCode>
6 <Version>1.0.0.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
13 <ProjectReference Include="..\PackageEv1\PackageEv1.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wxs b/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wxs
new file mode 100644
index 00000000..422b4b22
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleJ/BundleJ.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <RelatedBundle Id="{B1617DA6-F824-4B9F-B9B2-A6AFD07A652D}" Action="Detect" />
6
7 <PackageGroup Id="BundlePackages">
8 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
9 <MsiPackage Id="PackageE" SourceFile="$(var.PackageEv1.TargetPath)" />
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wixproj b/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wixproj
new file mode 100644
index 00000000..212ef3d6
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{353B5A34-3B46-424E-8817-25B3D01C8C16}</UpgradeCode>
6 <Version>1.0.1.0</Version>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageEv1_0_1\PackageEv1_0_1.wixproj" />
13 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wxs b/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wxs
new file mode 100644
index 00000000..ddd4d8db
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleJ_Patch/BundleJ_Patch.wxs
@@ -0,0 +1,16 @@
1<!-- 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. -->
2
3<?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?>
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 <Fragment>
7 <RelatedBundle Id="{B1617DA6-F824-4B9F-B9B2-A6AFD07A652D}" Action="Patch" />
8
9 <PackageGroup Id="BundlePackages">
10 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)">
11 <Provides Key="$(var.TestGroupName)_PatchA" Version="$(var.Version)" />
12 </MspPackage>
13 <MsiPackage Id="PackageE" Name="PackageEv1.msi" SourceFile="$(var.PackageEv1_0_1.TargetPath)" />
14 </PackageGroup>
15 </Fragment>
16</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleKv1/BundleK.props b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleK.props
new file mode 100644
index 00000000..15257eb3
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleK.props
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{F7B7CCD8-ACFE-45D8-9EC2-934BBC3BE597}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10</Project>
diff --git a/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wixproj b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wixproj
new file mode 100644
index 00000000..e7abd24a
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleK.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wxs b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wxs
new file mode 100644
index 00000000..c4a85814
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleKv1/BundleKv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wixproj b/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wixproj
new file mode 100644
index 00000000..e9e7478e
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleKv1\BundleK.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wxs b/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wxs
new file mode 100644
index 00000000..c4a85814
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleKv2/BundleKv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wixproj b/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wixproj
new file mode 100644
index 00000000..c5727cf6
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{2EDB07DC-DCCD-419F-AD25-52ABF36B53AE}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PackageC\PackageC.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wxs b/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wxs
new file mode 100644
index 00000000..d3789e63
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/BundleL/BundleL.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
7 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Vital="no" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..8cbe9aa9
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageA</PackageName>
5 <ProductComponentsRef>true</ProductComponentsRef>
6 <ProductCode>{6F171EC9-0774-4974-A8D1-493EF53CAB74}</ProductCode>
7 <UpgradeCode>{45E933B7-B56A-44D5-8EEC-625EC199085E}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..1cac7394
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4 <ItemGroup>
5 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
6 </ItemGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/ProductComponents.wxs b/src/test/burn/TestData/DependencyTests/PackageAv1/ProductComponents.wxs
new file mode 100644
index 00000000..eca7f6b4
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageAv1/ProductComponents.wxs
@@ -0,0 +1,16 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:dep="http://wixtoolset.org/schemas/v4/wxs/dependency">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="FileComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="FileComponent2" Guid="BB609407-F2F4-458D-95F8-BF184D6E8496" Directory="INSTALLFOLDER">
12 <File Source="$(sys.SOURCEFILEPATH)" />
13 <Provides Key="WiX.$(var.TestGroupName).A,v1.0" dep:Check="yes" />
14 </Component>
15 </Fragment>
16</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
new file mode 100644
index 00000000..d395391e
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj
new file mode 100644
index 00000000..e7a497f4
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>1.0.2.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageB/PackageB.wixproj b/src/test/burn/TestData/DependencyTests/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..a82822f8
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageB/PackageB.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <ProductComponentsRef>true</ProductComponentsRef>
5 <UpgradeCode>{E26243B0-F1A2-4E74-A82D-25B306908E78}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageB/ProductComponents.wxs b/src/test/burn/TestData/DependencyTests/PackageB/ProductComponents.wxs
new file mode 100644
index 00000000..b59e53e1
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageB/ProductComponents.wxs
@@ -0,0 +1,18 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:dep="http://wixtoolset.org/schemas/v4/wxs/dependency">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="FileComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="FileComponent2" Guid="A1866388-65B4-4215-A8FB-9A7AADBE4E8E" Directory="INSTALLFOLDER">
12 <File Source="$(sys.SOURCEFILEPATH)" />
13 <Provides>
14 <Requires ProviderKey="WiX.$(var.TestGroupName).A,v1.0" Minimum="1.0.0.0" IncludeMinimum="yes" dep:Enforce="yes" />
15 </Provides>
16 </Component>
17 </Fragment>
18</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PackageC/PackageC.wixproj b/src/test/burn/TestData/DependencyTests/PackageC/PackageC.wixproj
new file mode 100644
index 00000000..ef61d053
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageC/PackageC.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{F21201D4-4782-4658-99C9-2E75D51FCFA6}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
11 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageDv1/Package.wxs b/src/test/burn/TestData/DependencyTests/PackageDv1/Package.wxs
new file mode 100644
index 00000000..e3089c7c
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageDv1/Package.wxs
@@ -0,0 +1,63 @@
1<!-- 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. -->
2
3
4
5<?ifndef Version?>
6<?define Version = 1.0.0.0?>
7<?endif?>
8
9<?ifndef ProductCode?>
10<?define ProductCode = *?>
11<?endif?>
12
13<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:dep="http://wixtoolset.org/schemas/v4/wxs/dependency">
14 <Package Name="~$(var.TestGroupName) - $(var.PackageName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProductCode="$(var.ProductCode)" Scope="perUser">
15 <MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
16 <?ifndef CabPrefix?>
17 <MediaTemplate EmbedCab="yes" />
18 <?else?>
19 <MediaTemplate CabinetTemplate="{0}$(var.CabPrefix).cab" />
20 <?endif?>
21
22 <?ifdef SoftwareTag?>
23 <SoftwareTag Regid="regid.1995-08.com.example" InstallDirectory="LocalAppDataFolder" />
24 <?endif?>
25
26 <PropertyRef Id="TestVersion" />
27
28 <Feature Id="Complete" Level="1">
29 <ComponentRef Id="FileComponent" />
30 <ComponentRef Id="RegistryComponent" />
31 <?ifdef var.ProductComponents?>
32 <ComponentGroupRef Id="ProductComponents" />
33 <?endif?>
34 </Feature>
35 </Package>
36
37 <Fragment>
38 <StandardDirectory Id="ProgramFilesFolder">
39 <Directory Id="WixDir" Name="~Test WiX">
40 <Directory Id="TestDir" Name="$(var.TestGroupName)">
41 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" />
42 </Directory>
43 </Directory>
44 </StandardDirectory>
45 </Fragment>
46
47 <Fragment>
48 <Component Id="FileComponent" Guid="8AEF758B-5890-4490-8485-46BD65616A2B" Directory="INSTALLFOLDER">
49 <File Source="$(sys.SOURCEFILEPATH)" />
50 <Provides Key="WiX.$(var.TestGroupName).D,v1.0" dep:Check="yes" />
51 </Component>
52 </Fragment>
53
54 <Fragment>
55 <Component Id="RegistryComponent" Directory="INSTALLFOLDER">
56 <RegistryValue Root="HKCU" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)" Value="!(bind.Property.TestVersion)" Type="string" />
57 </Component>
58 </Fragment>
59
60 <Fragment>
61 <Property Id="TestVersion" Value="$(var.Version)" />
62 </Fragment>
63</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PackageDv1/PackageD.props b/src/test/burn/TestData/DependencyTests/PackageDv1/PackageD.props
new file mode 100644
index 00000000..999de0de
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageDv1/PackageD.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageD</PackageName>
5 <UpgradeCode>{AD82A938-2F54-45B8-A637-B14D8405A959}</UpgradeCode>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageDv1/PackageDv1.wixproj b/src/test/burn/TestData/DependencyTests/PackageDv1/PackageDv1.wixproj
new file mode 100644
index 00000000..3d9cf384
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageDv1/PackageDv1.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageD.props" />
4 <ItemGroup>
5 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
6 </ItemGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageDv2/PackageDv2.wixproj b/src/test/burn/TestData/DependencyTests/PackageDv2/PackageDv2.wixproj
new file mode 100644
index 00000000..2bb6e8bd
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageDv2/PackageDv2.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageDv1\PackageD.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageDv1\Package.wxs" Link="Package.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageEv1/PackageE.props b/src/test/burn/TestData/DependencyTests/PackageEv1/PackageE.props
new file mode 100644
index 00000000..96f07b8c
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageEv1/PackageE.props
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageE</PackageName>
5 <ProductComponentsRef>true</ProductComponentsRef>
6 <ProductCode>{70FA13C7-0338-483F-A256-E5C83750BDE5}</ProductCode>
7 <UpgradeCode>{212A5698-457E-440F-88CC-98FC49A17378}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageEv1/PackageEv1.wixproj b/src/test/burn/TestData/DependencyTests/PackageEv1/PackageEv1.wixproj
new file mode 100644
index 00000000..091b7b24
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageEv1/PackageEv1.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageE.props" />
4 <ItemGroup>
5 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
6 </ItemGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageEv1/ProductComponents.wxs b/src/test/burn/TestData/DependencyTests/PackageEv1/ProductComponents.wxs
new file mode 100644
index 00000000..d388d2a3
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageEv1/ProductComponents.wxs
@@ -0,0 +1,16 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:dep="http://wixtoolset.org/schemas/v4/wxs/dependency">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="FileComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="FileComponent2" Guid="BB609407-F2F4-458D-95F8-BF184D6E8496" Directory="INSTALLFOLDER">
12 <File Source="$(sys.SOURCEFILEPATH)" />
13 <Provides Key="WiX.$(var.TestGroupName).E,v1.0" dep:Check="yes" />
14 </Component>
15 </Fragment>
16</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PackageEv1_0_1/PackageEv1_0_1.wixproj b/src/test/burn/TestData/DependencyTests/PackageEv1_0_1/PackageEv1_0_1.wixproj
new file mode 100644
index 00000000..1fb93130
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageEv1_0_1/PackageEv1_0_1.wixproj
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageEv1\PackageE.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageEv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/DependencyTests/PackageF/PackageF.wixproj
new file mode 100644
index 00000000..25b610ac
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PackageF/PackageF.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{069AECC6-84DC-4FA4-B506-CD3A9A76F2F4}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wixproj b/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wixproj
new file mode 100644
index 00000000..b6653a19
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wxs b/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wxs
new file mode 100644
index 00000000..acb6f887
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PatchA/PatchA.wxs
@@ -0,0 +1,22 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch A in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch A" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchA" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 </Media>
16
17 <PatchFamily Id="A" Version="$(var.Version)" Supersede="yes">
18 <ComponentRef Id="RegistryComponent"/>
19 <PropertyRef Id="TestVersion"/>
20 </PatchFamily>
21 </Patch>
22</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wixproj b/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wixproj
new file mode 100644
index 00000000..cf28a9c9
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_2\PackageAv1_0_2.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Dependency.wixext" Version="4.0.30" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wxs b/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wxs
new file mode 100644
index 00000000..a906dbc8
--- /dev/null
+++ b/src/test/burn/TestData/DependencyTests/PatchB/PatchB.wxs
@@ -0,0 +1,21 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch B in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch B" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchB" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchB"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_2.TargetDir)$(var.PackageAv1_0_2.TargetName).wixpdb"
14 />
15 </Media>
16
17 <PatchFamily Id="B" Version="$(var.Version)" Supersede="yes">
18 <PropertyRef Id="TestVersion"/>
19 </PatchFamily>
20 </Patch>
21</Wix>
diff --git a/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..a1650507
--- /dev/null
+++ b/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{5DDF6D9F-FF04-40E8-919C-8DD1DCE4B592}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wxs b/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..bd164a29
--- /dev/null
+++ b/src/test/burn/TestData/ElevationTests/BundleA/BundleA.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/ElevationTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/ElevationTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..87f99513
--- /dev/null
+++ b/src/test/burn/TestData/ElevationTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{D803BB11-5B94-42EA-8289-7A17E55699A3}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/FailureTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/FailureTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..321f139c
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleA/BundleA.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{FE5197EB-E324-411E-B3AC-760E566E1000}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/FailureTests/BundleA/BundleA.wxs b/src/test/burn/TestData/FailureTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..95e714ec
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleA/BundleA.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/FailureTests/BundleB/Bundle.wxs b/src/test/burn/TestData/FailureTests/BundleB/Bundle.wxs
new file mode 100644
index 00000000..ea3d029e
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleB/Bundle.wxs
@@ -0,0 +1,26 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
9 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
10
11 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
12
13 <!-- ParallelCache="yes" should be the only thing different from the template -->
14 <Chain ParallelCache="yes">
15 <PackageGroupRef Id="TestBA" />
16
17 <PackageGroupRef Id="BundlePackages" />
18 </Chain>
19 </Bundle>
20 <Fragment>
21 <PackageGroup Id="BundlePackages">
22 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
23 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
24 </PackageGroup>
25 </Fragment>
26</Wix>
diff --git a/src/test/burn/TestData/FailureTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/FailureTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..1a5d5837
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleB/BundleB.wixproj
@@ -0,0 +1,16 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{C60B9483-CE87-4FDA-AE5A-B39A52E956E8}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
9 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
10 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
14 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/FailureTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/FailureTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..60bd5ef7
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleC/BundleC.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{9E9964D0-2120-4358-8136-D4A8727E0C59}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/FailureTests/BundleC/BundleC.wxs b/src/test/burn/TestData/FailureTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..48c4ab72
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/BundleC/BundleC.wxs
@@ -0,0 +1,11 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" Name="MissingNonVital.msi" Vital="no" Compressed="no" />
8 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" />
9 </PackageGroup>
10 </Fragment>
11</Wix>
diff --git a/src/test/burn/TestData/FailureTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/FailureTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..3b0e74e2
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{82FB39B2-56FA-4631-AA03-8B8D3215E6AE}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/FailureTests/PackageB/PackageB.wixproj b/src/test/burn/TestData/FailureTests/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..96f7a031
--- /dev/null
+++ b/src/test/burn/TestData/FailureTests/PackageB/PackageB.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{94160B95-81DD-4DAB-AE2D-246A9E3A108E}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs
new file mode 100644
index 00000000..175d9a1f
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/Bundle.wxs
@@ -0,0 +1,40 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <!-- ProviderKey should be the only thing different from the template -->
9 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProviderKey="~$(var.TestGroupName)_BundleA">
10 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
11
12 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
13
14 <?ifdef SoftwareTag?>
15 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
16 <?endif?>
17
18 <?ifndef BA?>
19 <!-- pulled in through the PackageGroupRef below -->
20 <?elseif $(var.BA) = "TestBAdnc"?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "hyperlinkLicense"?>
23 <BootstrapperApplication>
24 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
25 </BootstrapperApplication>
26 <?else?>
27 <BootstrapperApplicationRef Id="$(var.BA)" />
28 <?endif?>
29
30 <Chain>
31 <?ifndef BA?>
32 <PackageGroupRef Id="TestBA" />
33 <?elseif $(var.BA) = "TestBAdnc"?>
34 <PackageGroupRef Id="TestBAdnc" />
35 <?endif?>
36
37 <PackageGroupRef Id="BundlePackages" />
38 </Chain>
39 </Bundle>
40</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..329ea107
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleA.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{5ACFAE02-DDF0-4F1C-BEAD-1E0998E5CF9B}</UpgradeCode>
6 </PropertyGroup>
7</Project>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..d968e8ab
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..7bf16212
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj
new file mode 100644
index 00000000..a50dbb87
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\BundleAv1\Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs
new file mode 100644
index 00000000..5cbee5a8
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleAv2/BundleAv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs
new file mode 100644
index 00000000..dd305e42
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/Bundle.wxs
@@ -0,0 +1,40 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <!-- ProviderKey should be the only thing different from the template -->
9 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProviderKey="~$(var.TestGroupName)_BundleC">
10 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
11
12 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
13
14 <?ifdef SoftwareTag?>
15 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
16 <?endif?>
17
18 <?ifndef BA?>
19 <!-- pulled in through the PackageGroupRef below -->
20 <?elseif $(var.BA) = "TestBAdnc"?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "hyperlinkLicense"?>
23 <BootstrapperApplication>
24 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
25 </BootstrapperApplication>
26 <?else?>
27 <BootstrapperApplicationRef Id="$(var.BA)" />
28 <?endif?>
29
30 <Chain>
31 <?ifndef BA?>
32 <PackageGroupRef Id="TestBA" />
33 <?elseif $(var.BA) = "TestBAdnc"?>
34 <PackageGroupRef Id="TestBAdnc" />
35 <?endif?>
36
37 <PackageGroupRef Id="BundlePackages" />
38 </Chain>
39 </Bundle>
40</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props
new file mode 100644
index 00000000..73a9bb63
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleC.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{D387D602-533C-495D-B14E-AA9D46AF314B}</UpgradeCode>
6 </PropertyGroup>
7</Project>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj
new file mode 100644
index 00000000..5b025236
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleC.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageCv1\PackageCv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs
new file mode 100644
index 00000000..43e75910
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv1/BundleCv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageC" SourceFile="$(var.PackageCv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj
new file mode 100644
index 00000000..e0512e06
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleCv1\BundleC.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\BundleCv1\Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageCv2\PackageCv2.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs
new file mode 100644
index 00000000..53115c96
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/BundleCv2/BundleCv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageC" SourceFile="$(var.PackageCv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..de83c1f5
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageA.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{F764127F-8893-4483-A136-F53660C32423}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..45d3b2c8
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj
new file mode 100644
index 00000000..b419f663
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageAv2/PackageAv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props
new file mode 100644
index 00000000..91d3bdda
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageC.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{DF1C1C42-F5B9-4167-914B-1AF97E829C48}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackagePerUser.wxs" Link="PackagePerUser.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj
new file mode 100644
index 00000000..45615706
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv1/PackageCv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageC.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj
new file mode 100644
index 00000000..640ad21d
--- /dev/null
+++ b/src/test/burn/TestData/ForwardCompatibleBundleTests/PackageCv2/PackageCv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageCv1\PackageC.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/LayoutTests/BundleA/Bundle.wxs b/src/test/burn/TestData/LayoutTests/BundleA/Bundle.wxs
new file mode 100644
index 00000000..e74b8394
--- /dev/null
+++ b/src/test/burn/TestData/LayoutTests/BundleA/Bundle.wxs
@@ -0,0 +1,42 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
9 <!-- PayloadGroupRef should be the only thing different from the template -->
10 <PayloadGroupRef Id="LayoutOnlyPayloads" />
11
12 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
13
14 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
15
16 <?ifdef SoftwareTag?>
17 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
18 <?endif?>
19
20 <?ifndef BA?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "TestBAdnc"?>
23 <!-- pulled in through the PackageGroupRef below -->
24 <?elseif $(var.BA) = "hyperlinkLicense"?>
25 <BootstrapperApplication>
26 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
27 </BootstrapperApplication>
28 <?else?>
29 <BootstrapperApplicationRef Id="$(var.BA)" />
30 <?endif?>
31
32 <Chain>
33 <?ifndef BA?>
34 <PackageGroupRef Id="TestBA" />
35 <?elseif $(var.BA) = "TestBAdnc"?>
36 <PackageGroupRef Id="TestBAdnc" />
37 <?endif?>
38
39 <PackageGroupRef Id="BundlePackages" />
40 </Chain>
41 </Bundle>
42</Wix>
diff --git a/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..4cf9c875
--- /dev/null
+++ b/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wixproj
@@ -0,0 +1,23 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{D255FA2D-2B4A-4D78-AE90-C09FECD8491E}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 </ItemGroup>
15 <!-- Workaround wix.targets brokenness -->
16 <Target Name="CopyUncompressedFiles" AfterTargets="AfterBuild">
17 <ItemGroup>
18 <UncompressedFiles Include="$(IntermediateOutputPath)\BundleA.wxs" />
19 <UncompressedFiles Include="$(IntermediateOutputPath)\packages.cab" />
20 </ItemGroup>
21 <Copy SourceFiles="@(UncompressedFiles)" DestinationFolder="$(OutputPath)" />
22 </Target>
23</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wxs b/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..ea46c5b2
--- /dev/null
+++ b/src/test/burn/TestData/LayoutTests/BundleA/BundleA.wxs
@@ -0,0 +1,26 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 </PackageGroup>
9
10 <!-- Reenable when fixed
11 <Container Id="PackagesContainer" Name="packages.cab" DownloadUrl="$(var.WebServerBaseUrl)BundleA/{2}">
12 -->
13 <Container Id="PackagesContainer" Name="packages.cab" DownloadUrl="$(var.WebServerBaseUrl)BundleA/packages.cab">
14 <PackageGroupRef Id="BundlePackages" />
15 </Container>
16 </Fragment>
17
18 <Fragment>
19 <PayloadGroup Id="LayoutOnlyPayloads">
20 <Payload Id="LayoutOnlyPayload" SourceFile="$(sys.SOURCEFILEPATH)" Compressed="no" DownloadUrl="$(var.WebServerBaseUrl)BundleA/LayoutOnlyPayload" />
21 <!-- Reenable when fixed
22 <Payload Id="LayoutOnlyPayload" SourceFile="$(sys.SOURCEFILEPATH)" Compressed="no" DownloadUrl="$(var.WebServerBaseUrl)BundleA/{1}" />
23 -->
24 </PayloadGroup>
25 </Fragment>
26</Wix>
diff --git a/src/test/burn/TestData/LayoutTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/LayoutTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..be425985
--- /dev/null
+++ b/src/test/burn/TestData/LayoutTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{CA12F025-6F6F-4E3C-A1D7-FE8CD45A77F5}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleA.props b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..f831fb29
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleA.props
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <SuppressSpecificWarnings>1151</SuppressSpecificWarnings>
6 <BA>hyperlinkLicense</BA>
7 <UpgradeCode>{90ED10D5-B187-4470-B498-05D80DAB729A}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12</Project>
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..cb9f4b89
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
6 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
7 <ProjectReference Include="..\PackageCv1\PackageCv1.wixproj" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..544fe6a6
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,13 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 <RollbackBoundary Transaction="yes" />
9 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
10 <MsiPackage Id="PackageC" SourceFile="$(var.PackageCv1.TargetPath)" />
11 </PackageGroup>
12 </Fragment>
13</Wix>
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wixproj
new file mode 100644
index 00000000..8272c6bd
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageBv2\PackageBv2.wixproj" />
9 <ProjectReference Include="..\PackageCv2\PackageCv2.wixproj" />
10 <ProjectReference Include="..\PackageD\PackageD.wixproj" />
11 </ItemGroup>
12 <ItemGroup>
13 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wxs
new file mode 100644
index 00000000..8623537b
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleAv2/BundleAv2.wxs
@@ -0,0 +1,13 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageD" SourceFile="$(var.PackageD.TargetPath)" />
8 <RollbackBoundary Transaction="yes" />
9 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv2.TargetPath)" />
10 <MsiPackage Id="PackageC" SourceFile="$(var.PackageCv2.TargetPath)" />
11 </PackageGroup>
12 </Fragment>
13</Wix>
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleB.props b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleB.props
new file mode 100644
index 00000000..87b402e4
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleB.props
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{552FD011-4DD6-42B2-A4C6-AD1417C829B2}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
12 </ItemGroup>
13</Project>
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wixproj b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wixproj
new file mode 100644
index 00000000..1a56957b
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wixproj
@@ -0,0 +1,11 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleB.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
6 </ItemGroup>
7 <ItemGroup>
8 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
9 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
10 </ItemGroup>
11</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wxs b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wxs
new file mode 100644
index 00000000..00d927ec
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleBv1/BundleBv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wixproj b/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wixproj
new file mode 100644
index 00000000..e1cb68db
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleBv1\BundleB.props" />
4 <PropertyGroup>
5 <SuppressSpecificWarnings>1151</SuppressSpecificWarnings>
6 <BA>TestBAdnc</BA>
7 <Version>2.0.0.0</Version>
8 </PropertyGroup>
9 <ItemGroup>
10 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
11 <ProjectReference Include="..\PackageBv2\PackageBv2.wixproj" />
12 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wxs b/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wxs
new file mode 100644
index 00000000..d1861e75
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/BundleBv2/BundleBv2.wxs
@@ -0,0 +1,13 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 <RollbackBoundary Transaction="yes" />
9 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv2.TargetPath)" />
10 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
11 </PackageGroup>
12 </Fragment>
13</Wix>
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..2ef7c05e
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageA/PackageA.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <CabPrefix>a</CabPrefix>
5 <UpgradeCode>{7772FCDF-5FDB-497D-B5DF-C6D17D667976}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageB.props b/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageB.props
new file mode 100644
index 00000000..decdfb6a
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageB.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{EAFC0C6B-626E-415C-8132-536FBD19F49B}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageBv1.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageBv1.wixproj
new file mode 100644
index 00000000..6dc1e4d8
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageBv1/PackageBv1.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageB.props" />
4 <PropertyGroup>
5 <CabPrefix>bv1</CabPrefix>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageBv2/PackageBv2.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageBv2/PackageBv2.wixproj
new file mode 100644
index 00000000..126d0f53
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageBv2/PackageBv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageBv1\PackageB.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageC.props b/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageC.props
new file mode 100644
index 00000000..b3d057bd
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageC.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{A18BDC12-DAEC-43EE-87D1-31B2C2BC6269}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageCv1.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageCv1.wixproj
new file mode 100644
index 00000000..617e61c3
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageCv1/PackageCv1.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageC.props" />
4 <PropertyGroup>
5 <CabPrefix>cv1</CabPrefix>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageCv2/PackageCv2.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageCv2/PackageCv2.wixproj
new file mode 100644
index 00000000..640ad21d
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageCv2/PackageCv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageCv1\PackageC.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageD/PackageD.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageD/PackageD.wixproj
new file mode 100644
index 00000000..1df5da24
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageD/PackageD.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{78B072D5-1C23-4895-9C4C-1B52E3C80621}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/MsiTransactionTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/MsiTransactionTests/PackageF/PackageF.wixproj
new file mode 100644
index 00000000..753b054e
--- /dev/null
+++ b/src/test/burn/TestData/MsiTransactionTests/PackageF/PackageF.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{3D59F8F2-8AC5-403E-B6F7-453870DE7063}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/PatchTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..72419d2d
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundleA/BundleA.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <IncludeSoftwareTag>true</IncludeSoftwareTag>
6 <UpgradeCode>{486FC795-69A5-4130-8727-4068F645A0A1}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/BundleA/BundleA.wxs b/src/test/burn/TestData/PatchTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..e3e0f4d7
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundleA/BundleA.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
7 </PackageGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wixproj b/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wixproj
new file mode 100644
index 00000000..a506e843
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <IncludeSoftwareTag>true</IncludeSoftwareTag>
6 <UpgradeCode>{AA083618-6280-44B8-9899-57BCC57906A5}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wxs b/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wxs
new file mode 100644
index 00000000..bf0c0451
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundlePatchA/BundlePatchA.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" PerMachine="yes" />
7 </PackageGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wixproj b/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wixproj
new file mode 100644
index 00000000..9a022091
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <IncludeSoftwareTag>true</IncludeSoftwareTag>
6 <UpgradeCode>{1BE09331-2327-4534-9223-59B54EFAE7A5}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
13 <ProjectReference Include="..\PatchA2\PatchA2.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wxs b/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wxs
new file mode 100644
index 00000000..24063db3
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/BundlePatchA2/BundlePatchA2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" PerMachine="yes" />
7 <MspPackage Id="PatchA2" SourceFile="$(var.PatchA2.TargetPath)" PerMachine="yes" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/PatchTests/PackageAv1/PackageA.props b/src/test/burn/TestData/PatchTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..a9d9b981
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PackageAv1/PackageA.props
@@ -0,0 +1,13 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageA</PackageName>
5 <ProductComponentsRef>true</ProductComponentsRef>
6 <ProductCode>{724F9BA5-DD9D-4851-855E-ECC35B27BF11}</ProductCode>
7 <IncludeSoftwareTag>true</IncludeSoftwareTag>
8 <UpgradeCode>{C56DA396-7A9A-4177-8264-638161CE9EB8}</UpgradeCode>
9 </PropertyGroup>
10 <ItemGroup>
11 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
12 </ItemGroup>
13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/PatchTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..45d3b2c8
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/PackageAv1/ProductComponents.wxs b/src/test/burn/TestData/PatchTests/PackageAv1/ProductComponents.wxs
new file mode 100644
index 00000000..72b5d4bd
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PackageAv1/ProductComponents.wxs
@@ -0,0 +1,15 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="RegistryComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="RegistryComponent2" Directory="INSTALLFOLDER">
12 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)2" Value="!(bind.Property.TestVersion)" Type="string" />
13 </Component>
14 </Fragment>
15</Wix>
diff --git a/src/test/burn/TestData/PatchTests/PackageAv1_0_1/PackageAv1_0_1.wixproj b/src/test/burn/TestData/PatchTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
new file mode 100644
index 00000000..9ceda117
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/PatchA/PatchA.wixproj b/src/test/burn/TestData/PatchTests/PatchA/PatchA.wixproj
new file mode 100644
index 00000000..da9acb5e
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PatchA/PatchA.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/PatchA/PatchA.wxs b/src/test/burn/TestData/PatchTests/PatchA/PatchA.wxs
new file mode 100644
index 00000000..ba961762
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PatchA/PatchA.wxs
@@ -0,0 +1,24 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch A in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch A" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchA" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 </Media>
16
17 <PatchFamily Id="A" Version="$(var.Version)" Supersede="yes">
18 <SoftwareTagRef Regid="regid.1995-08.com.example" />
19
20 <ComponentRef Id="RegistryComponent"/>
21 <PropertyRef Id="TestVersion"/>
22 </PatchFamily>
23 </Patch>
24</Wix>
diff --git a/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wixproj b/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wixproj
new file mode 100644
index 00000000..da9acb5e
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wxs b/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wxs
new file mode 100644
index 00000000..e2aa3e2b
--- /dev/null
+++ b/src/test/burn/TestData/PatchTests/PatchA2/PatchA2.wxs
@@ -0,0 +1,23 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch A2 in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch A2" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchA2" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA2"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 </Media>
16
17 <PatchFamily Id="A2" Version="$(var.Version)" Supersede="yes">
18 <SoftwareTagRef Regid="regid.1995-08.com.example" />
19
20 <ComponentRef Id="RegistryComponent2"/>
21 </PatchFamily>
22 </Patch>
23</Wix>
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..13bb159b
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>BrokenDnc</BA>
6 <UpgradeCode>{A4456636-916A-43A0-87BF-A897C2717A00}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net5.0-windows\win-x86" BindName="dnc5x86" />
13 </ItemGroup>
14 <ItemGroup>
15 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
16 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
17 </ItemGroup>
18 <ItemGroup>
19 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..c903988b
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs
@@ -0,0 +1,22 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
5 <Fragment>
6 <BootstrapperApplication Id="BrokenDnc">
7 <Payload SourceFile="!(bindpath.dnc5x86)\TestBA.deps.json" />
8 <Payload SourceFile="!(bindpath.dnc5x86)\TestBA.dll" bal:BAFactoryAssembly="yes" />
9 <Payload Name="TestBA.runtimeconfig.json" SourceFile="bad.runtimeconfig.json" />
10 <Payload SourceFile="!(bindpath.dnc5x86)\mbanative.dll" />
11 <Payload SourceFile="!(bindpath.dnc5x86)\WixToolset.Mba.Core.dll" />
12 <bal:WixDotNetCoreBootstrapperApplicationHost />
13 </BootstrapperApplication>
14 </Fragment>
15
16 <Fragment>
17 <PackageGroup Id="BundlePackages">
18 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" />
19 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" Cache="always" />
20 </PackageGroup>
21 </Fragment>
22</Wix>
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleA/bad.runtimeconfig.json b/src/test/burn/TestData/PrereqBaTests/BundleA/bad.runtimeconfig.json
new file mode 100644
index 00000000..07a1a830
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleA/bad.runtimeconfig.json
@@ -0,0 +1,10 @@
1{
2 "runtimeOptions": {
3 "tfm": "net5.5",
4 "rollForward": "Disable",
5 "framework": {
6 "name": "Microsoft.WindowsDesktop.App",
7 "version": "5.5.0"
8 }
9 }
10} \ No newline at end of file
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..cfbc77b5
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>BrokenMba</BA>
6 <UpgradeCode>{157A1FBA-3825-4AAA-B13D-F45435A79D64}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net35\win-x86" BindName="net2x86" />
13 </ItemGroup>
14 <ItemGroup>
15 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
16 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
17 </ItemGroup>
18 <ItemGroup>
19 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs
new file mode 100644
index 00000000..603c3aee
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs
@@ -0,0 +1,21 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
5 <Fragment>
6 <BootstrapperApplication Id="BrokenMba">
7 <Payload Name="WixToolset.Mba.Host.config" SourceFile="bad.config" />
8 <Payload SourceFile="!(bindpath.net2x86)\TestBA.dll" />
9 <Payload SourceFile="!(bindpath.net2x86)\mbanative.dll" />
10 <Payload SourceFile="!(bindpath.net2x86)\WixToolset.Mba.Core.dll" />
11 <bal:WixManagedBootstrapperApplicationHost />
12 </BootstrapperApplication>
13 </Fragment>
14
15 <Fragment>
16 <PackageGroup Id="BundlePackages">
17 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" />
18 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
19 </PackageGroup>
20 </Fragment>
21</Wix>
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleB/bad.config b/src/test/burn/TestData/PrereqBaTests/BundleB/bad.config
new file mode 100644
index 00000000..1512e59a
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/BundleB/bad.config
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4
5<configuration>
6 <configSections>
7 <sectionGroup name="wix.bootstrapper" type="WixToolset.Mba.Host.BootstrapperSectionGroup, WixToolset.Mba.Host">
8 <section name="host" type="WixToolset.Mba.Host.HostSection, WixToolset.Mba.Host" />
9 </sectionGroup>
10 </configSections>
11 <startup>
12 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v5.8" />
13 </startup>
14 <wix.bootstrapper>
15 <host assemblyName="TestBA" />
16 </wix.bootstrapper>
17</configuration>
diff --git a/src/test/burn/TestData/PrereqBaTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/PrereqBaTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..d46982fa
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{A13BFF68-61DF-4015-9AD1-03854B5E0212}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PrereqBaTests/PackageB/PackageB.wixproj b/src/test/burn/TestData/PrereqBaTests/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..d5edf338
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/PackageB/PackageB.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{3DD4621A-F7AB-4548-89A8-6DCB0A9BC954}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj
new file mode 100644
index 00000000..0a750fe0
--- /dev/null
+++ b/src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{7DEEE928-CD7F-49AD-8000-2ED6339D8A78}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..a6ccd842
--- /dev/null
+++ b/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{17041020-8A61-4A3B-8FDB-4591CB900049}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wxs b/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..bd164a29
--- /dev/null
+++ b/src/test/burn/TestData/RegistrationTests/BundleA/BundleA.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/RegistrationTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/RegistrationTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..7e5dbb8c
--- /dev/null
+++ b/src/test/burn/TestData/RegistrationTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{BF26D3E4-1D6B-480E-B312-3FECE6363E43}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..648cc934
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <BA>hyperlinkLicense</BA>
6 <UpgradeCode>{E8426C86-D5E4-45FA-B09D-789DC7E5E00A}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
10 </ItemGroup>
11 <ItemGroup>
12 <ProjectReference Include="..\PackageA\PackageA.wixproj" />
13 <ProjectReference Include="..\PackageB\PackageB.wixproj" />
14 <ProjectReference Include="..\PackageC\PackageC.wixproj" />
15 <ProjectReference Include="..\PackageF\PackageF.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wxs b/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..795dc13a
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/BundleA/BundleA.wxs
@@ -0,0 +1,15 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Permanent="yes" /> <!-- TODO: this is a workaround for inability to specify RollbackBoundary as first package, remove when this is fixed -->
8 <RollbackBoundary Id="nonvital" Vital="no" />
9 <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" />
10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" Permanent="yes" />
11 <RollbackBoundary />
12 <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" Permanent="yes" />
13 </PackageGroup>
14 </Fragment>
15</Wix>
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/RollbackBoundaryTests/PackageA/PackageA.wixproj
new file mode 100644
index 00000000..25d9e279
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/PackageA/PackageA.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{14A06CEA-CC9E-478F-AD20-5C9624827090}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/PackageB/PackageB.wixproj b/src/test/burn/TestData/RollbackBoundaryTests/PackageB/PackageB.wixproj
new file mode 100644
index 00000000..2dc4f3a6
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/PackageB/PackageB.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{C0B6E75E-4378-4589-B3C5-A23FFA39F59B}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/PackageC/PackageC.wixproj b/src/test/burn/TestData/RollbackBoundaryTests/PackageC/PackageC.wixproj
new file mode 100644
index 00000000..a4b5134b
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/PackageC/PackageC.wixproj
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{1C977E8F-4E79-4E3B-A5B1-C4B0BE774041}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/RollbackBoundaryTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/RollbackBoundaryTests/PackageF/PackageF.wixproj
new file mode 100644
index 00000000..071c40a0
--- /dev/null
+++ b/src/test/burn/TestData/RollbackBoundaryTests/PackageF/PackageF.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <UpgradeCode>{E348D377-E5E7-44B0-897E-5DC8D401BF80}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" />
8 </ItemGroup>
9 <ItemGroup>
10 <PackageReference Include="WixToolset.Util.wixext" Version="4.0.96" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wixproj
new file mode 100644
index 00000000..b6ab068a
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{62C28DAF-A13E-4F55-ACA1-FB843630789C}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wxs b/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wxs
new file mode 100644
index 00000000..17dc6c05
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleA/BundleA.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" Compressed="no">
7 <SlipstreamMsp Id="PatchA" />
8 </MsiPackage>
9 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" Compressed="no" />
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wixproj
new file mode 100644
index 00000000..ac33c5ad
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{F6BB4AE2-F7D4-4768-8314-3AF694C400E9}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wxs b/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wxs
new file mode 100644
index 00000000..2008fa8b
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleAReverse/BundleAReverse.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" />
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)">
8 <SlipstreamMsp Id="PatchA" />
9 </MsiPackage>
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..3ca849a3
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{604878DE-F0EB-4FE1-B11E-DC19F07F82F5}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
13 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
14 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wxs b/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wxs
new file mode 100644
index 00000000..90ddd258
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleB/BundleB.wxs
@@ -0,0 +1,13 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)">
7 <SlipstreamMsp Id="PatchA" />
8 </MsiPackage>
9 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" />
10 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
11 </PackageGroup>
12 </Fragment>
13</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..377e939c
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wixproj
@@ -0,0 +1,21 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{16B551B5-6EBE-417F-8CB2-50936F079301}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
13 <ProjectReference Include="..\PatchAB\PatchAB.wixproj" />
14 <ProjectReference Include="..\PatchAB2\PatchAB2.wixproj" />
15 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
20 </ItemGroup>
21</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wxs b/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..4702d845
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleC/BundleC.wxs
@@ -0,0 +1,14 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)">
7 <SlipstreamMsp Id="PatchAB" />
8 </MsiPackage>
9 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
10 <MspPackage Id="PatchAB" SourceFile="$(var.PatchAB.TargetPath)" />
11 <MspPackage Id="PatchAB2" SourceFile="$(var.PatchAB2.TargetPath)" PerMachine="default" Slipstream="yes" />
12 </PackageGroup>
13 </Fragment>
14</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wixproj
new file mode 100644
index 00000000..12f11444
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{5372D18C-8C62-4C22-A24B-6BB2FB4AA966}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wxs b/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wxs
new file mode 100644
index 00000000..64bdc1b5
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleD/BundleD.wxs
@@ -0,0 +1,12 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)">
7 <SlipstreamMsp Id="PatchA" />
8 </MsiPackage>
9 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" InstallCondition="WixBundleInstalled = 1" />
10 </PackageGroup>
11 </Fragment>
12</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wixproj
new file mode 100644
index 00000000..193244ca
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{80A9925A-2EC1-4BD5-BB69-2553BF7FCED9}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wxs b/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wxs
new file mode 100644
index 00000000..e3e0f4d7
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleOnlyA/BundleOnlyA.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
7 </PackageGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wixproj b/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wixproj
new file mode 100644
index 00000000..11995ddd
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{9B026C22-924C-4CEA-8726-FD07C1706A9F}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PatchA\PatchA.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wxs b/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wxs
new file mode 100644
index 00000000..88a93d7a
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/BundleOnlyPatchA/BundleOnlyPatchA.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <PackageGroup Id="BundlePackages">
6 <MspPackage Id="PatchA" SourceFile="$(var.PatchA.TargetPath)" />
7 </PackageGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv0_9_0/PackageAv0_9_0.wixproj b/src/test/burn/TestData/SlipstreamTests/PackageAv0_9_0/PackageAv0_9_0.wixproj
new file mode 100644
index 00000000..50aa6ec6
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv0_9_0/PackageAv0_9_0.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>0.9.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageA.props b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..734e0d6d
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageA.props
@@ -0,0 +1,11 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageA</PackageName>
5 <ProductComponentsRef>true</ProductComponentsRef>
6 <UpgradeCode>{DB87BB66-FE5D-4293-81AC-EE313D3F864B}</UpgradeCode>
7 </PropertyGroup>
8 <ItemGroup>
9 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
10 </ItemGroup>
11</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.props b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.props
new file mode 100644
index 00000000..2936f349
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <Import Project="PackageA.props" />
4 <PropertyGroup>
5 <ProductCode>{5FF7F534-3FFC-41E0-80CD-E6361E5E7B7B}</ProductCode>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..e85be384
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageAv1.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv1/ProductComponents.wxs b/src/test/burn/TestData/SlipstreamTests/PackageAv1/ProductComponents.wxs
new file mode 100644
index 00000000..72b5d4bd
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv1/ProductComponents.wxs
@@ -0,0 +1,15 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="RegistryComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="RegistryComponent2" Directory="INSTALLFOLDER">
12 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)2" Value="!(bind.Property.TestVersion)" Type="string" />
13 </Component>
14 </Fragment>
15</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageAv1_0_1/PackageAv1_0_1.wixproj b/src/test/burn/TestData/SlipstreamTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
new file mode 100644
index 00000000..dbce9cfe
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageAv1_0_1/PackageAv1_0_1.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageAv1.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageB.props b/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageB.props
new file mode 100644
index 00000000..920088fb
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageB.props
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <PackageName>PackageB</PackageName>
5 <ProductComponentsRef>true</ProductComponentsRef>
6 <ProductCode>{83B1ADF3-A8DD-41D3-9114-57703DA17754}</ProductCode>
7 <UpgradeCode>{552F8D3B-99E1-4772-8E8C-CC47E5ED5F71}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageBv1.wixproj b/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageBv1.wixproj
new file mode 100644
index 00000000..7b6f83a3
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageBv1/PackageBv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageB.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageBv1/ProductComponents.wxs b/src/test/burn/TestData/SlipstreamTests/PackageBv1/ProductComponents.wxs
new file mode 100644
index 00000000..72b5d4bd
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageBv1/ProductComponents.wxs
@@ -0,0 +1,15 @@
1<!-- 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. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents">
6 <ComponentRef Id="RegistryComponent2" />
7 </ComponentGroup>
8 </Fragment>
9
10 <Fragment>
11 <Component Id="RegistryComponent2" Directory="INSTALLFOLDER">
12 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)2" Value="!(bind.Property.TestVersion)" Type="string" />
13 </Component>
14 </Fragment>
15</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/PackageBv1_0_1/PackageBv1_0_1.wixproj b/src/test/burn/TestData/SlipstreamTests/PackageBv1_0_1/PackageBv1_0_1.wixproj
new file mode 100644
index 00000000..3ec790ad
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PackageBv1_0_1/PackageBv1_0_1.wixproj
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageBv1\PackageB.props" />
4 <PropertyGroup>
5 <Version>1.0.1.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\PackageBv1\ProductComponents.wxs" Link="ProductComponents.wxs" />
9 </ItemGroup>
10</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wixproj b/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wixproj
new file mode 100644
index 00000000..da9acb5e
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wxs b/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wxs
new file mode 100644
index 00000000..7c3818b0
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchA/PatchA.wxs
@@ -0,0 +1,22 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch A in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch A" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchA" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 </Media>
16
17 <PatchFamily Id="A" Version="$(var.Version)" Supersede="yes">
18 <ComponentRef Id="RegistryComponent" />
19 <PropertyRef Id="TestVersion" />
20 </PatchFamily>
21 </Patch>
22</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wixproj b/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wixproj
new file mode 100644
index 00000000..81fa9e12
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wixproj
@@ -0,0 +1,14 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
12 <ProjectReference Include="..\PackageBv1_0_1\PackageBv1_0_1.wixproj" />
13 </ItemGroup>
14</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wxs b/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wxs
new file mode 100644
index 00000000..f700f35c
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchAB/PatchAB.wxs
@@ -0,0 +1,27 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch AB in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch AB" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchAB" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 <PatchBaseline
16 Id="PatchB"
17 BaselineFile="$(var.PackageBv1.TargetDir)$(var.PackageBv1.TargetName).wixpdb"
18 UpdateFile="$(var.PackageBv1_0_1.TargetDir)$(var.PackageBv1_0_1.TargetName).wixpdb"
19 />
20 </Media>
21
22 <PatchFamily Id="AB" Version="$(var.Version)" Supersede="yes">
23 <ComponentRef Id="RegistryComponent" />
24 <PropertyRef Id="TestVersion" />
25 </PatchFamily>
26 </Patch>
27</Wix>
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wixproj b/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wixproj
new file mode 100644
index 00000000..81fa9e12
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wixproj
@@ -0,0 +1,14 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>PatchCreation</OutputType>
5 <TargetExt>.msp</TargetExt>
6 <SuppressSpecificWarnings>1079</SuppressSpecificWarnings>
7 </PropertyGroup>
8 <ItemGroup>
9 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
10 <ProjectReference Include="..\PackageAv1_0_1\PackageAv1_0_1.wixproj" />
11 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
12 <ProjectReference Include="..\PackageBv1_0_1\PackageBv1_0_1.wixproj" />
13 </ItemGroup>
14</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wxs b/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wxs
new file mode 100644
index 00000000..ebd5bed0
--- /dev/null
+++ b/src/test/burn/TestData/SlipstreamTests/PatchAB2/PatchAB2.wxs
@@ -0,0 +1,26 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Patch AllowRemoval="yes" Classification="Update" Description="Patch AB2 in test $(var.TestGroupName)" DisplayName="$(var.TestGroupName) - Patch AB2" Manufacturer="Example Corporation" MinorUpdateTargetRTM="yes">
9 <Media Id="100" Cabinet="PatchAB2" EmbedCab="yes">
10 <PatchBaseline
11 Id="PatchA"
12 BaselineFile="$(var.PackageAv1.TargetDir)$(var.PackageAv1.TargetName).wixpdb"
13 UpdateFile="$(var.PackageAv1_0_1.TargetDir)$(var.PackageAv1_0_1.TargetName).wixpdb"
14 />
15 <PatchBaseline
16 Id="PatchB"
17 BaselineFile="$(var.PackageBv1.TargetDir)$(var.PackageBv1.TargetName).wixpdb"
18 UpdateFile="$(var.PackageBv1_0_1.TargetDir)$(var.PackageBv1_0_1.TargetName).wixpdb"
19 />
20 </Media>
21
22 <PatchFamily Id="AB2" Version="$(var.Version)" Supersede="yes">
23 <ComponentRef Id="RegistryComponent2" />
24 </PatchFamily>
25 </Patch>
26</Wix>
diff --git a/src/test/burn/TestData/Templates/Bundle.wxs b/src/test/burn/TestData/Templates/Bundle.wxs
new file mode 100644
index 00000000..06409504
--- /dev/null
+++ b/src/test/burn/TestData/Templates/Bundle.wxs
@@ -0,0 +1,47 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
9 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
10
11 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
12
13 <?ifdef SoftwareTag?>
14 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
15 <?endif?>
16
17 <?ifndef BA?>
18 <!-- pulled in through the PackageGroupRef below -->
19 <?elseif $(var.BA) = "TestBAdnc"?>
20 <!-- pulled in through the PackageGroupRef below -->
21 <?elseif $(var.BA) = "TestBA_x64"?>
22 <!-- pulled in through the PackageGroupRef below -->
23 <?elseif $(var.BA) = "TestBAdnc_x64"?>
24 <!-- pulled in through the PackageGroupRef below -->
25 <?elseif $(var.BA) = "hyperlinkLicense"?>
26 <BootstrapperApplication>
27 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
28 </BootstrapperApplication>
29 <?else?>
30 <BootstrapperApplicationRef Id="$(var.BA)" />
31 <?endif?>
32
33 <Chain>
34 <?ifndef BA?>
35 <PackageGroupRef Id="TestBA" />
36 <?elseif $(var.BA) = "TestBAdnc"?>
37 <PackageGroupRef Id="TestBAdnc" />
38 <?elseif $(var.BA) = "TestBA_x64"?>
39 <PackageGroupRef Id="TestBA_x64" />
40 <?elseif $(var.BA) = "TestBAdnc_x64"?>
41 <PackageGroupRef Id="TestBAdnc_x64" />
42 <?endif?>
43
44 <PackageGroupRef Id="BundlePackages" />
45 </Chain>
46 </Bundle>
47</Wix>
diff --git a/src/test/burn/TestData/Templates/Package.wxs b/src/test/burn/TestData/Templates/Package.wxs
new file mode 100644
index 00000000..48ed5e02
--- /dev/null
+++ b/src/test/burn/TestData/Templates/Package.wxs
@@ -0,0 +1,62 @@
1<!-- 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. -->
2
3
4
5<?ifndef Version?>
6<?define Version = 1.0.0.0?>
7<?endif?>
8
9<?ifndef ProductCode?>
10<?define ProductCode = *?>
11<?endif?>
12
13<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
14 <Package Name="~$(var.TestGroupName) - $(var.PackageName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProductCode="$(var.ProductCode)">
15 <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
16 <?ifndef CabPrefix?>
17 <MediaTemplate EmbedCab="yes" />
18 <?else?>
19 <MediaTemplate CabinetTemplate="{0}$(var.CabPrefix).cab" />
20 <?endif?>
21
22 <?ifdef SoftwareTag?>
23 <SoftwareTag Regid="regid.1995-08.com.example" InstallDirectory="CommonAppDataFolder" />
24 <?endif?>
25
26 <PropertyRef Id="TestVersion" />
27
28 <Feature Id="Complete" Level="1">
29 <ComponentRef Id="FileComponent" />
30 <ComponentRef Id="RegistryComponent" />
31 <?ifdef var.ProductComponents?>
32 <ComponentGroupRef Id="ProductComponents" />
33 <?endif?>
34 </Feature>
35 </Package>
36
37 <Fragment>
38 <StandardDirectory Id="ProgramFiles6432Folder">
39 <Directory Id="WixDir" Name="~Test WiX">
40 <Directory Id="TestDir" Name="$(var.TestGroupName)">
41 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" />
42 </Directory>
43 </Directory>
44 </StandardDirectory>
45 </Fragment>
46
47 <Fragment>
48 <Component Id="FileComponent" Directory="INSTALLFOLDER">
49 <File Source="$(sys.SOURCEFILEPATH)" />
50 </Component>
51 </Fragment>
52
53 <Fragment>
54 <Component Id="RegistryComponent" Directory="INSTALLFOLDER">
55 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)" Value="!(bind.Property.TestVersion)" Type="string" />
56 </Component>
57 </Fragment>
58
59 <Fragment>
60 <Property Id="TestVersion" Value="$(var.Version)" />
61 </Fragment>
62</Wix>
diff --git a/src/test/burn/TestData/Templates/PackageFail.wxs b/src/test/burn/TestData/Templates/PackageFail.wxs
new file mode 100644
index 00000000..0139c22b
--- /dev/null
+++ b/src/test/burn/TestData/Templates/PackageFail.wxs
@@ -0,0 +1,50 @@
1<!-- 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. -->
2
3
4
5<?ifndef Version?>
6<?define Version = 1.0.0.0?>
7<?endif?>
8
9<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
10 <Package Name="~$(var.TestGroupName) - $(var.PackageName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
11 <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
12 <MediaTemplate EmbedCab="yes" />
13
14 <PropertyRef Id="TestVersion" />
15
16 <Feature Id="Complete" Level="1">
17 <ComponentRef Id="FileComponent" />
18 <ComponentRef Id="RegistryComponent" />
19 </Feature>
20
21 <util:FailWhenDeferred />
22 <Property Id="WIXFAILWHENDEFERRED" Secure="yes" Value="1" />
23 </Package>
24
25 <Fragment>
26 <StandardDirectory Id="ProgramFilesFolder">
27 <Directory Id="WixDir" Name="~Test WiX">
28 <Directory Id="TestDir" Name="$(var.TestGroupName)">
29 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" />
30 </Directory>
31 </Directory>
32 </StandardDirectory>
33 </Fragment>
34
35 <Fragment>
36 <Component Id="FileComponent" Directory="INSTALLFOLDER">
37 <File Source="$(sys.SOURCEFILEPATH)" />
38 </Component>
39 </Fragment>
40
41 <Fragment>
42 <Component Id="RegistryComponent" Directory="INSTALLFOLDER">
43 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)" Value="!(bind.Property.TestVersion)" Type="string" />
44 </Component>
45 </Fragment>
46
47 <Fragment>
48 <Property Id="TestVersion" Value="$(var.Version)" />
49 </Fragment>
50</Wix>
diff --git a/src/test/burn/TestData/Templates/PackagePerUser.wxs b/src/test/burn/TestData/Templates/PackagePerUser.wxs
new file mode 100644
index 00000000..5e18fefd
--- /dev/null
+++ b/src/test/burn/TestData/Templates/PackagePerUser.wxs
@@ -0,0 +1,62 @@
1<!-- 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. -->
2
3
4
5<?ifndef Version?>
6<?define Version = 1.0.0.0?>
7<?endif?>
8
9<?ifndef ProductCode?>
10<?define ProductCode = *?>
11<?endif?>
12
13<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
14 <Package Name="~$(var.TestGroupName) - $(var.PackageName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)" Compressed="yes" ProductCode="$(var.ProductCode)" Scope="perUser">
15 <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
16 <?ifndef CabPrefix?>
17 <MediaTemplate EmbedCab="yes" />
18 <?else?>
19 <MediaTemplate CabinetTemplate="{0}$(var.CabPrefix).cab" />
20 <?endif?>
21
22 <?ifdef SoftwareTag?>
23 <SoftwareTag Regid="regid.1995-08.com.example" InstallDirectory="LocalAppDataFolder" />
24 <?endif?>
25
26 <PropertyRef Id="TestVersion" />
27
28 <Feature Id="Complete" Level="1">
29 <ComponentRef Id="FileComponent" />
30 <ComponentRef Id="RegistryComponent" />
31 <?ifdef var.ProductComponents?>
32 <ComponentGroupRef Id="ProductComponents" />
33 <?endif?>
34 </Feature>
35 </Package>
36
37 <Fragment>
38 <StandardDirectory Id="LocalAppDataFolder">
39 <Directory Id="WixDir" Name="~Test WiX">
40 <Directory Id="TestDir" Name="$(var.TestGroupName)">
41 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" />
42 </Directory>
43 </Directory>
44 </StandardDirectory>
45 </Fragment>
46
47 <Fragment>
48 <Component Id="FileComponent" Directory="INSTALLFOLDER">
49 <File Source="$(sys.SOURCEFILEPATH)" />
50 </Component>
51 </Fragment>
52
53 <Fragment>
54 <Component Id="RegistryComponent" Directory="INSTALLFOLDER">
55 <RegistryValue Root="HKCU" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)" Value="!(bind.Property.TestVersion)" Type="string" />
56 </Component>
57 </Fragment>
58
59 <Fragment>
60 <Property Id="TestVersion" Value="$(var.Version)" />
61 </Fragment>
62</Wix>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib/TestBA.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib/TestBA.wxs
new file mode 100644
index 00000000..348a0cbb
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib/TestBA.wxs
@@ -0,0 +1,30 @@
1<!-- 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. -->
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
3 <Fragment>
4 <BootstrapperApplication>
5 <Payload SourceFile="!(bindpath.dnc5x86)\TestBA.deps.json" />
6 <Payload SourceFile="!(bindpath.dnc5x86)\TestBA.dll" bal:BAFactoryAssembly="yes" />
7 <Payload SourceFile="!(bindpath.dnc5x86)\TestBA.runtimeconfig.json" />
8 <Payload SourceFile="!(bindpath.dnc5x86)\mbanative.dll" />
9 <Payload SourceFile="!(bindpath.dnc5x86)\WixToolset.Mba.Core.dll" />
10 <bal:WixDotNetCoreBootstrapperApplicationHost />
11 </BootstrapperApplication>
12
13 <PackageGroup Id="TestBAdnc">
14 <PackageGroupRef Id="NetFx48WebAsPrereq" /> <!-- Yes, this is wrong but we don't have .NET 5 packages yet -->
15 </PackageGroup>
16 </Fragment>
17 <Fragment>
18 <BootstrapperApplication>
19 <Payload Name="WixToolset.Mba.Host.config" SourceFile="!(bindpath.net2x86)\TestBA.BootstrapperCore.config" />
20 <Payload SourceFile="!(bindpath.net2x86)\TestBA.dll" />
21 <Payload SourceFile="!(bindpath.net2x86)\mbanative.dll" />
22 <Payload SourceFile="!(bindpath.net2x86)\WixToolset.Mba.Core.dll" />
23 <bal:WixManagedBootstrapperApplicationHost />
24 </BootstrapperApplication>
25
26 <PackageGroup Id="TestBA">
27 <PackageGroupRef Id="NetFx48WebAsPrereq" />
28 </PackageGroup>
29 </Fragment>
30</Wix>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib/TestExe.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib/TestExe.wxs
new file mode 100644
index 00000000..f27275b0
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib/TestExe.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <PayloadGroup Id="TestExePayloads">
5 <ExePackagePayload SourceFile="!(bindpath.net2x86)\TestExe.exe" />
6 <Payload SourceFile="!(bindpath.net2x86)\TestExe.exe.config" />
7 </PayloadGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib/testbawixlib.wixproj b/src/test/burn/TestData/TestBA/TestBAWixlib/testbawixlib.wixproj
new file mode 100644
index 00000000..ae90dd73
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib/testbawixlib.wixproj
@@ -0,0 +1,19 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Library</OutputType>
5 <BindFiles>true</BindFiles>
6 <Cultures>en-us</Cultures>
7 </PropertyGroup>
8 <ItemGroup>
9 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net35\win-x86" BindName="net2x86" />
10 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net5.0-windows\win-x86" BindName="dnc5x86" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\..\..\TestBA\TestBA.csproj" />
14 <ProjectReference Include="..\..\..\TestExe\TestExe.csproj" />
15 </ItemGroup>
16 <ItemGroup>
17 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestBA_x64.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestBA_x64.wxs
new file mode 100644
index 00000000..078f4f01
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestBA_x64.wxs
@@ -0,0 +1,30 @@
1<!-- 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. -->
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
3 <Fragment>
4 <BootstrapperApplication>
5 <Payload SourceFile="!(bindpath.dnc5x64)\TestBA.deps.json" />
6 <Payload SourceFile="!(bindpath.dnc5x64)\TestBA.dll" bal:BAFactoryAssembly="yes" />
7 <Payload SourceFile="!(bindpath.dnc5x64)\TestBA.runtimeconfig.json" />
8 <Payload SourceFile="!(bindpath.dnc5x64)\mbanative.dll" />
9 <Payload SourceFile="!(bindpath.dnc5x64)\WixToolset.Mba.Core.dll" />
10 <bal:WixDotNetCoreBootstrapperApplicationHost />
11 </BootstrapperApplication>
12
13 <PackageGroup Id="TestBAdnc_x64">
14 <PackageGroupRef Id="NetFx48WebAsPrereq" /> <!-- Yes, this is wrong but we don't have .NET 5 packages yet -->
15 </PackageGroup>
16 </Fragment>
17 <Fragment>
18 <BootstrapperApplication>
19 <Payload Name="WixToolset.Mba.Host.config" SourceFile="!(bindpath.net2x64)\TestBA.BootstrapperCore.config" />
20 <Payload SourceFile="!(bindpath.net2x64)\TestBA.dll" />
21 <Payload SourceFile="!(bindpath.net2x64)\mbanative.dll" />
22 <Payload SourceFile="!(bindpath.net2x64)\WixToolset.Mba.Core.dll" />
23 <bal:WixManagedBootstrapperApplicationHost />
24 </BootstrapperApplication>
25
26 <PackageGroup Id="TestBA_x64">
27 <PackageGroupRef Id="NetFx48WebAsPrereq" />
28 </PackageGroup>
29 </Fragment>
30</Wix>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestExe_x64.wxs b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestExe_x64.wxs
new file mode 100644
index 00000000..02bed038
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/TestExe_x64.wxs
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <PayloadGroup Id="TestExePayloads_x64">
5 <ExePackagePayload SourceFile="!(bindpath.net2x64)\TestExe.exe" />
6 <Payload SourceFile="!(bindpath.net2x64)\TestExe.exe.config" />
7 </PayloadGroup>
8 </Fragment>
9</Wix>
diff --git a/src/test/burn/TestData/TestBA/TestBAWixlib_x64/testbawixlib_x64.wixproj b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/testbawixlib_x64.wixproj
new file mode 100644
index 00000000..9b7d3c17
--- /dev/null
+++ b/src/test/burn/TestData/TestBA/TestBAWixlib_x64/testbawixlib_x64.wixproj
@@ -0,0 +1,20 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Library</OutputType>
5 <BindFiles>true</BindFiles>
6 <Cultures>en-us</Cultures>
7 <InstallerPlatform>x64</InstallerPlatform>
8 </PropertyGroup>
9 <ItemGroup>
10 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net35\win-x64" BindName="net2x64" />
11 <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net5.0-windows\win-x64" BindName="dnc5x64" />
12 </ItemGroup>
13 <ItemGroup>
14 <ProjectReference Include="..\..\..\TestBA\TestBA_x64.csproj" />
15 <ProjectReference Include="..\..\..\TestExe\TestExe_x64.csproj" />
16 </ItemGroup>
17 <ItemGroup>
18 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/TestData.proj b/src/test/burn/TestData/TestData.proj
new file mode 100644
index 00000000..c5682fc7
--- /dev/null
+++ b/src/test/burn/TestData/TestData.proj
@@ -0,0 +1,25 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6 <ItemGroup>
7 <TestDataProject Include="**\*.wixproj" />
8
9 <!-- https://github.com/wixtoolset/issues/issues/6387 -->
10 <TestDataProject Remove="DependencyTests\BundleC\BundleC.wixproj" />
11 <TestDataProject Remove="DependencyTests\BundleF_PatchAv1_0_1\BundleF_PatchAv1_0_1.wixproj" />
12 <TestDataProject Remove="DependencyTests\BundleF_PatchAv1_0_2\BundleF_PatchAv1_0_2.wixproj" />
13 <TestDataProject Remove="DependencyTests\BundleJ_Patch\BundleJ_Patch.wixproj" />
14 <TestDataProject Remove="DependencyTests\PatchA\PatchA.wixproj" />
15 <TestDataProject Remove="DependencyTests\PatchB\PatchB.wixproj" />
16 </ItemGroup>
17
18 <Target Name="Build">
19 <MSBuild Projects="%(TestDataProject.Identity)" />
20 </Target>
21
22 <Target Name="Restore">
23 <MSBuild Projects="%(TestDataProject.Identity)" Targets="Restore" />
24 </Target>
25</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleA.props b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..19b37770
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleA.props
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{AF745E41-CEAC-4C9F-83D8-663BAB1AF5CC}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10</Project>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..d968e8ab
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..7bf16212
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj
new file mode 100644
index 00000000..07e9581b
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs
new file mode 100644
index 00000000..5cbee5a8
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs
new file mode 100644
index 00000000..906121f4
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs
@@ -0,0 +1,42 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
9 <!-- Update should be the only thing different from the template -->
10 <Update Location="$(var.WebServerBaseUrl)BundleB/feed" />
11
12 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
13
14 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
15
16 <?ifdef SoftwareTag?>
17 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
18 <?endif?>
19
20 <?ifndef BA?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "TestBAdnc"?>
23 <!-- pulled in through the PackageGroupRef below -->
24 <?elseif $(var.BA) = "hyperlinkLicense"?>
25 <BootstrapperApplication>
26 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
27 </BootstrapperApplication>
28 <?else?>
29 <BootstrapperApplicationRef Id="$(var.BA)" />
30 <?endif?>
31
32 <Chain>
33 <?ifndef BA?>
34 <PackageGroupRef Id="TestBA" />
35 <?elseif $(var.BA) = "TestBAdnc"?>
36 <PackageGroupRef Id="TestBAdnc" />
37 <?endif?>
38
39 <PackageGroupRef Id="BundlePackages" />
40 </Chain>
41 </Bundle>
42</Wix>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleB.props b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleB.props
new file mode 100644
index 00000000..8a275612
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleB.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{BF325BA5-5012-47C7-828C-577B6979CB28}</UpgradeCode>
6 </PropertyGroup>
7</Project>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj
new file mode 100644
index 00000000..b2685e2e
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleB.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <Feeds Include="*.xml" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 </ItemGroup>
15 <Target Name="CopyFeeds" AfterTargets="AfterBuild">
16 <Copy SourceFiles="@(Feeds)" DestinationFolder="$(OutputPath)" />
17 </Target>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs
new file mode 100644
index 00000000..00d927ec
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml
new file mode 100644
index 00000000..743548be
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml
@@ -0,0 +1,32 @@
1<?xml version='1.0' ?>
2<!-- 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. -->
3
4
5<feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn">
6 <title type="text">BundleB v1.0</title>
7 <subtitle type="text">Bundle Subtitle.</subtitle>
8 <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application>
9 <updated>2014-07-14T12:39:00.000Z</updated>
10 <id>http://localhost:9999/e2e/BundleB/feed</id>
11 <link rel="self" type="application/atom+xml" href="http://localhost:9999/e2e/BundleB/feed"/>
12 <generator version="0.1">manual build</generator>
13 <entry>
14 <title>Bundle v1.0</title>
15 <id>v1.0</id>
16 <author>
17 <name>Bundle_Author</name>
18 <uri>http://mycompany.com/software</uri>
19 <email>Bundle_Author@mycompany.com</email>
20 </author>
21 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
22 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/>
23 <content type="html">
24 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
25 &lt;li&gt;Initial release.&lt;/li&gt;
26 &lt;/ul&gt;
27 </content>
28 <as:upgrade version="1.0.0.0-preview" />
29 <as:version>1.0.0.0</as:version>
30 <updated>2014-07-14T12:39:00.000Z</updated>
31 </entry>
32</feed>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml
new file mode 100644
index 00000000..c8e3f6ea
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml
@@ -0,0 +1,51 @@
1<?xml version='1.0' ?>
2<!-- 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. -->
3
4
5<feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn">
6 <title type="text">BundleB v2.0</title>
7 <subtitle type="text">Bundle Subtitle.</subtitle>
8 <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application>
9 <updated>2014-07-14T12:39:00.000Z</updated>
10 <id>http://localhost:9999/e2e/BundleB/feed</id>
11 <link rel="self" type="application/atom+xml" href="http://localhost:9999/e2e/BundleB/feed"/>
12 <generator version="0.1">manual build</generator>
13 <entry>
14 <title>Bundle v2.0</title>
15 <id>v2.0</id>
16 <author>
17 <name>Bundle_Author</name>
18 <uri>http://mycompany.com/software</uri>
19 <email>Bundle_Author@mycompany.com</email>
20 </author>
21 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
22 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/2.0/BundleB.exe" length="0" type="application/octet-stream"/>
23 <content type="html">
24 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
25 &lt;li&gt;Updated release.&lt;/li&gt;
26 &lt;/ul&gt;
27 </content>
28 <as:upgrade version="1.0" />
29 <as:version>2.0.0.0</as:version>
30 <updated>2014-11-10T12:39:00.000Z</updated>
31 </entry>
32 <entry>
33 <title>Bundle v1.0</title>
34 <id>v1.0</id>
35 <author>
36 <name>Bundle_Author</name>
37 <uri>http://mycompany.com/software</uri>
38 <email>Bundle_Author@mycompany.com</email>
39 </author>
40 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
41 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/>
42 <content type="html">
43 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
44 &lt;li&gt;Initial release.&lt;/li&gt;
45 &lt;/ul&gt;
46 </content>
47 <as:upgrade version="1.0.0.0-preview" />
48 <as:version>1.0.0.0</as:version>
49 <updated>2014-11-09T12:39:00.000Z</updated>
50 </entry>
51</feed>
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj b/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj
new file mode 100644
index 00000000..a11fc252
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleBv1\BundleB.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\BundleBv1\Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageBv2\PackageBv2.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs b/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs
new file mode 100644
index 00000000..2043b084
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageA.props b/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..bc734540
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageA.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{AB55C215-3268-4005-9657-6B0567F0A4B1}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..45d3b2c8
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj
new file mode 100644
index 00000000..b419f663
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageB.props b/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageB.props
new file mode 100644
index 00000000..e677cb7e
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageB.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{6B971C9E-2FB0-4BF7-8D77-D2DF71FD9A14}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackagePerUser.wxs" Link="PackagePerUser.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj b/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj
new file mode 100644
index 00000000..7b6f83a3
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageB.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj b/src/test/burn/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj
new file mode 100644
index 00000000..126d0f53
--- /dev/null
+++ b/src/test/burn/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageBv1\PackageB.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleA.props b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..ee20a72c
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleA.props
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{8C01FD92-87BE-419B-88EC-36754E93CA67}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10</Project>
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..d968e8ab
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..7bf16212
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wixproj
new file mode 100644
index 00000000..07e9581b
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.101" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.73" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wxs
new file mode 100644
index 00000000..5cbee5a8
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv2/BundleAv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageA.props b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..53541e10
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageA.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{E7AF5E0D-EC10-4339-9126-76A76011DA3A}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..45d3b2c8
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv2/PackageAv2.wixproj
new file mode 100644
index 00000000..b419f663
--- /dev/null
+++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv2/PackageAv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/test/burn/TestExe/NetfxTask.cs b/src/test/burn/TestExe/NetfxTask.cs
new file mode 100644
index 00000000..35b1ea95
--- /dev/null
+++ b/src/test/burn/TestExe/NetfxTask.cs
@@ -0,0 +1,295 @@
1// 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.
2
3#if NET35
4using System;
5using System.Collections.Generic;
6using System.Diagnostics;
7using System.IO;
8using System.Management;
9using Microsoft.Win32;
10
11namespace TestExe
12{
13 public class ProcessInfoTask : Task
14 {
15 public ProcessInfoTask(string Data) : base(Data) { }
16
17 public override void RunTask()
18 {
19 try
20 {
21 string processInfoXml = "";
22
23 // Get information about the process and who is running it
24 Process thisProc = Process.GetCurrentProcess();
25 string username = thisProc.StartInfo.EnvironmentVariables["username"].ToString();
26
27 int parentProcId = GetParentProcess(thisProc.Id);
28 Process parentProc = Process.GetProcessById(parentProcId);
29 string parentUsername = parentProc.StartInfo.EnvironmentVariables["username"].ToString();
30
31 int grandparentProcId = GetParentProcess(parentProc.Id);
32 Process grandparentProc = Process.GetProcessById(grandparentProcId);
33 string grandparentUsername = grandparentProc.StartInfo.EnvironmentVariables["username"].ToString();
34
35 processInfoXml += "<ProcessInfo>";
36 processInfoXml += " <ProcessName>" + thisProc.ProcessName + "</ProcessName>";
37 processInfoXml += " <Id>" + thisProc.Id.ToString() + "</Id>";
38 processInfoXml += " <SessionId>" + thisProc.SessionId.ToString() + "</SessionId>";
39 processInfoXml += " <MachineName>" + thisProc.MachineName + "</MachineName>";
40 // this stuff isn't set since we didn't start the process and tell it what to use. So don't bother
41 //processInfoXml += " <StartInfo>";
42 //processInfoXml += " <FileName>" + thisProc.StartInfo.FileName + "</FileName>";
43 //processInfoXml += " <UserName>" + thisProc.StartInfo.UserName + "</UserName>";
44 //processInfoXml += " <WorkingDirectory>" + thisProc.StartInfo.WorkingDirectory + "</WorkingDirectory>";
45 //processInfoXml += " <Arguments>" + thisProc.StartInfo.Arguments + "</Arguments>";
46 //processInfoXml += " </StartInfo>";
47 processInfoXml += " <StartTime>" + thisProc.StartTime.ToString() + "</StartTime>";
48 processInfoXml += " <Username>" + username + "</Username>";
49 processInfoXml += " <ParentProcess>";
50 processInfoXml += " <ProcessName>" + parentProc.ProcessName + "</ProcessName>";
51 processInfoXml += " <Id>" + parentProc.Id.ToString() + "</Id>";
52 processInfoXml += " <StartTime>" + parentProc.StartTime.ToString() + "</StartTime>";
53 processInfoXml += " <Username>" + parentUsername + "</Username>";
54 processInfoXml += " </ParentProcess>";
55 processInfoXml += " <GrandparentProcess>";
56 processInfoXml += " <ProcessName>" + grandparentProc.ProcessName + "</ProcessName>";
57 processInfoXml += " <Id>" + grandparentProc.Id.ToString() + "</Id>";
58 processInfoXml += " <StartTime>" + grandparentProc.StartTime.ToString() + "</StartTime>";
59 processInfoXml += " <Username>" + grandparentUsername + "</Username>";
60 processInfoXml += " </GrandparentProcess>";
61 processInfoXml += "</ProcessInfo>";
62
63 string logFile = System.Environment.ExpandEnvironmentVariables(this.data);
64 Console.WriteLine("Creating Process Info data file: " + logFile);
65 StreamWriter textFile = File.CreateText(logFile);
66 textFile.WriteLine(processInfoXml);
67 textFile.Close();
68 }
69 catch (Exception eX)
70 {
71 Console.WriteLine("Creating Process Info data file failed");
72 Console.WriteLine(eX.Message);
73 }
74
75
76 }
77
78 private static int GetParentProcess(int Id)
79 {
80 int parentPid = 0;
81 using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString() + "'"))
82 {
83 mo.Get();
84 parentPid = Convert.ToInt32(mo["ParentProcessId"]);
85 }
86 return parentPid;
87 }
88 }
89
90 /// <summary>
91 /// Task class that will create a registry key and write a name and value in it
92 /// </summary>
93 public class RegistryWriterTask : Task
94 {
95 private string hive;
96 private string keyPath;
97 private string[] keyPathArray;
98 private string name;
99 private RegistryValueKind regValueKind;
100 private object value;
101
102 public RegistryWriterTask(string Data) : base(Data) { }
103
104 public override void RunTask()
105 {
106 if (this.parseRegKeyNameTypeValue(System.Environment.ExpandEnvironmentVariables(this.data)))
107 {
108 RegistryKey rk = Registry.LocalMachine;
109
110 if (this.hive == "HKCU") { rk = Microsoft.Win32.Registry.CurrentUser; }
111 if (this.hive == "HKCC") { rk = Microsoft.Win32.Registry.CurrentConfig; }
112 if (this.hive == "HKLM") { rk = Microsoft.Win32.Registry.LocalMachine; }
113
114 foreach (string key in this.keyPathArray)
115 {
116 rk = rk.CreateSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree);
117 }
118
119 rk.SetValue(this.name, this.value, this.regValueKind);
120 Console.WriteLine("Created registry key: '{0}' name: '{1}' value: '{2}' of type: '{3}'",
121 this.hive + "\\" + this.keyPath,
122 this.name,
123 this.value.ToString(),
124 this.regValueKind.ToString());
125 }
126 else
127 {
128 Console.WriteLine("Unable to write registry key.");
129 }
130
131 }
132
133 private bool parseRegKeyNameTypeValue(string delimittedData)
134 {
135 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
136 if (splitString.Length != 4)
137 {
138 Console.WriteLine("Invalid regkey. Unable to parse key,name,type,value from: \"" + delimittedData + "\"");
139 return false;
140 }
141 else
142 {
143 this.keyPath = splitString[0];
144 this.name = splitString[1];
145 string datatype = splitString[2];
146 if (datatype == "DWord")
147 {
148 this.value = UInt32.Parse(splitString[3]);
149 }
150 else if (datatype == "QWord")
151 {
152 this.value = UInt64.Parse(splitString[3]);
153 }
154 else
155 {
156 this.value = splitString[3];
157 }
158
159 if (this.keyPath.ToUpper().StartsWith("HKLM\\"))
160 {
161 this.hive = "HKLM";
162 this.keyPath = this.keyPath.Replace("HKLM\\", "");
163 }
164 else if (this.keyPath.ToUpper().StartsWith("HKCC\\"))
165 {
166 this.hive = "HKCC";
167 this.keyPath = this.keyPath.Replace("HKCC\\", "");
168 }
169 else if (this.keyPath.ToUpper().StartsWith("HKCU\\"))
170 {
171 this.hive = "HKCU";
172 this.keyPath = this.keyPath.Replace("HKCU\\", "");
173 }
174 else
175 {
176 Console.WriteLine("Invalid regkey. Unable to determin hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
177 return false;
178 }
179 this.keyPathArray = this.keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
180
181 try
182 {
183 this.regValueKind = (RegistryValueKind)System.Enum.Parse(typeof(RegistryValueKind), datatype);
184 }
185 catch (Exception ex)
186 {
187 Console.WriteLine("Invalid datatype. It must be: String, DWord, or QWord (case sensitive)");
188 Console.WriteLine(ex.Message);
189 return false;
190 }
191 }
192 return true;
193 }
194 }
195
196 /// <summary>
197 /// Task class that will delete a registry key value or registry key and all of its children
198 /// </summary>
199 public class RegistryDeleterTask : Task
200 {
201 private string hive;
202 private string keyPath;
203 private string[] keyPathArray;
204 private string name;
205
206 public RegistryDeleterTask(string Data) : base(Data) { }
207
208 public override void RunTask()
209 {
210 if (this.parseRegKeyName(System.Environment.ExpandEnvironmentVariables(this.data)))
211 {
212 try
213 {
214 RegistryKey rk = Registry.LocalMachine;
215
216 if (this.hive == "HKCU") { rk = Microsoft.Win32.Registry.CurrentUser; }
217 if (this.hive == "HKCC") { rk = Microsoft.Win32.Registry.CurrentConfig; }
218 if (this.hive == "HKLM") { rk = Microsoft.Win32.Registry.LocalMachine; }
219
220 RegistryKey rkParent = null;
221 foreach (string key in this.keyPathArray)
222 {
223 rkParent = rk;
224 rk = rk.OpenSubKey(key, true);
225 }
226
227 if (String.IsNullOrEmpty(this.name))
228 {
229 // delete the key and all of its children
230 string subkeyToDelete = this.keyPathArray[this.keyPathArray.Length - 1];
231 rkParent.DeleteSubKeyTree(subkeyToDelete);
232 Console.WriteLine("Deleted registry key: '{0}'", this.hive + "\\" + this.keyPath);
233 }
234 else
235 {
236 // just delete this value
237 rk.DeleteValue(this.name);
238 Console.WriteLine("Deleted registry key: '{0}' name: '{1}'", this.hive + "\\" + this.keyPath, this.name);
239 }
240 }
241 catch (Exception ex)
242 {
243 Console.WriteLine("Unable to delete registry key: '{0}'", this.hive + "\\" + this.keyPath);
244 Console.WriteLine(ex.Message);
245 }
246 }
247 else
248 {
249 Console.WriteLine("Unable to delete registry key.");
250 }
251
252 }
253
254 private bool parseRegKeyName(string delimittedData)
255 {
256 string[] splitString = delimittedData.Split(new string[] { "," }, StringSplitOptions.None);
257
258 if (splitString.Length > 2)
259 {
260 Console.WriteLine("Unable to parse registry key and name.");
261 return false;
262 }
263
264 this.keyPath = splitString[0];
265 if (splitString.Length == 2)
266 {
267 this.name = splitString[1];
268 }
269
270 if (this.keyPath.ToUpper().StartsWith("HKLM\\"))
271 {
272 this.hive = "HKLM";
273 this.keyPath = this.keyPath.Replace("HKLM\\", "");
274 }
275 else if (this.keyPath.ToUpper().StartsWith("HKCC\\"))
276 {
277 this.hive = "HKCC";
278 this.keyPath = this.keyPath.Replace("HKCC\\", "");
279 }
280 else if (this.keyPath.ToUpper().StartsWith("HKCU\\"))
281 {
282 this.hive = "HKCU";
283 this.keyPath = this.keyPath.Replace("HKCU\\", "");
284 }
285 else
286 {
287 Console.WriteLine("Invalid regkey. Unable to determine hive. regkey must start with either: [HKLM], [HKCU], or [HKCC]");
288 return false;
289 }
290 this.keyPathArray = this.keyPath.Split(new string[] { "\\" }, StringSplitOptions.None);
291 return true;
292 }
293 }
294}
295#endif
diff --git a/src/test/burn/TestExe/Program.cs b/src/test/burn/TestExe/Program.cs
new file mode 100644
index 00000000..e92c413b
--- /dev/null
+++ b/src/test/burn/TestExe/Program.cs
@@ -0,0 +1,74 @@
1// 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.
2
3using System;
4using System.Collections.Generic;
5using System.Linq;
6using System.Text;
7
8namespace TestExe
9{
10 class Program
11 {
12 static List<Task> tasks;
13 static int exitCodeToReturn = 0;
14
15 static int Main(string[] args)
16 {
17 Usage();
18 tasks = TaskParser.ParseTasks(args);
19
20 foreach (Task t in tasks)
21 {
22 // special case for the ExitCodeTask
23 if (t.GetType() == typeof(ExitCodeTask))
24 {
25 exitCodeToReturn = int.Parse(t.data);
26 }
27 else
28 {
29 t.RunTask();
30 }
31 }
32
33 Console.WriteLine("Exiting with ExitCode = {0}", exitCodeToReturn);
34 return exitCodeToReturn;
35 }
36
37 static void Usage()
38 {
39 Console.WriteLine(@"TestExe.exe");
40 Console.WriteLine(@"");
41 Console.WriteLine(@"TestExe can be passed various switches to define how it will behave and what tasks it will perform.");
42 Console.WriteLine(@"All switches are optional.");
43 Console.WriteLine(@"Any # of switches can be combined in any order.");
44 Console.WriteLine(@"Switches can be specified multiple times.");
45 Console.WriteLine(@"The order of the switches listed is the order they will be processed.");
46 Console.WriteLine(@"Info is written to stdout to describe what tasks are being performed as they are executed.");
47 Console.WriteLine(@"");
48 Console.WriteLine(@"Usage: TestExe.exe [tasks...]");
49 Console.WriteLine(@"");
50 Console.WriteLine(@"");
51 Console.WriteLine(@"/ec # Exit code to return. Can only be specified once. If not specified, 0 will be returned. Example: “/ec 3010” would return 3010");
52 Console.WriteLine(@"/s # Milliseconds to sleep before continuing. Example: “/s 5000” would sleep 5 seconds.");
53 Console.WriteLine(@"/sr #-# Random range of Milliseconds to sleep before continuing. Example: “/sr 5000-10000” would sleep between 5-10 seconds.");
54 Console.WriteLine(@"/log filename Create a log file called filename. Contents of the log are static text. Example: “/log %temp%\test.log” would create a %temp%\test.log file.");
55 Console.WriteLine(@"/Pinfo filename Create an xml file containing information about the process: PID, start time, user running the process, etc.");
56 Console.WriteLine(@"/fe filename Wait for a file to exist before continuing. Example: “/fe %temp%\cache\file.msi” would wait until %temp%\cache\file.msi exists.");
57 Console.WriteLine(@"/regw regkey,name,type,value (Re)writes a registry key with the specified value");
58 Console.WriteLine(@"/regd regkey,[name] Deletes registry key name or key and all of its children (subkeys and values)");
59 Console.WriteLine(@"");
60 Console.WriteLine(@"Example: ");
61 Console.WriteLine(@"");
62 Console.WriteLine(@"TestExe.exe /ec 1603 /Pinfo %temp%\Pinfo1.xml /s 1000 /log %temp%\log1.log /sr 5000-10000 /log %temp%\log2.log");
63 Console.WriteLine(@"");
64 Console.WriteLine(@"This would result in the following execution:");
65 Console.WriteLine(@" - Create an xml file with the current process info in it.");
66 Console.WriteLine(@" - Sleep 1 seconds");
67 Console.WriteLine(@" - Create log1.log");
68 Console.WriteLine(@" - Sleep between 5-10 seconds");
69 Console.WriteLine(@" - Create log2.log");
70 Console.WriteLine(@" - Exit with 1603");
71 Console.WriteLine(@"");
72 }
73 }
74}
diff --git a/src/test/burn/TestExe/Task.cs b/src/test/burn/TestExe/Task.cs
new file mode 100644
index 00000000..7d39bfd9
--- /dev/null
+++ b/src/test/burn/TestExe/Task.cs
@@ -0,0 +1,209 @@
1// 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.
2
3using System;
4using System.Collections.Generic;
5using System.Diagnostics;
6using System.IO;
7using Microsoft.Win32;
8
9namespace TestExe
10{
11 public abstract class Task
12 {
13 public string data;
14
15 public Task(string Data)
16 {
17 this.data = Data;
18 }
19
20 public abstract void RunTask();
21
22 }
23
24 public class ExitCodeTask : Task
25 {
26 public ExitCodeTask(string Data) : base(Data) { }
27
28 public override void RunTask()
29 {
30 // this task does nothing. Just stores data about what exit code to return.
31 }
32 }
33
34 public class SleepTask : Task
35 {
36 public SleepTask(string Data) : base(Data) { }
37
38 public override void RunTask()
39 {
40 int milliseconds = int.Parse(this.data);
41 Console.WriteLine("Starting to sleep for {0} milliseconds", milliseconds);
42 System.Threading.Thread.Sleep(milliseconds);
43 }
44 }
45
46 public class SleepRandomTask : Task
47 {
48 public SleepRandomTask(string Data) : base(Data) { }
49
50 public override void RunTask()
51 {
52 int low = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[0]);
53 int high = int.Parse(this.data.Split(new string[] { ":" }, 2, StringSplitOptions.None)[1]);
54
55 Random r = new Random();
56 int milliseconds = r.Next(high - low) + low;
57 Console.WriteLine("Starting to sleep for {0} milliseconds", milliseconds);
58 System.Threading.Thread.Sleep(milliseconds);
59 }
60 }
61
62 public class LargeFileTask : Task
63 {
64 public LargeFileTask(string Data) : base(Data) { }
65
66 public override void RunTask()
67 {
68 string[] tokens = this.data.Split(new char[] { '|' }, 2);
69 string filePath = System.Environment.ExpandEnvironmentVariables(tokens[0]);
70 long size = long.Parse(tokens[1]);
71 using (var stream = File.Create(filePath))
72 {
73 stream.Seek(size - 1, SeekOrigin.Begin);
74 stream.WriteByte(1);
75 }
76 }
77 }
78
79 public class LogTask : Task
80 {
81 string[] argsUsed;
82 public LogTask(string Data, string[] args)
83 : base(Data)
84 {
85 this.argsUsed = args;
86 }
87
88 public override void RunTask()
89 {
90 string logFile = "";
91 string argsUsedString = "";
92
93 foreach (string a in this.argsUsed)
94 {
95 argsUsedString += a + " ";
96 }
97
98 try
99 {
100 logFile = System.Environment.ExpandEnvironmentVariables(this.data);
101 Console.WriteLine("creating log file: " + logFile);
102 StreamWriter textFile = File.CreateText(logFile);
103 textFile.WriteLine("This is a log file created by TestExe.exe");
104 textFile.WriteLine("Args used: " + argsUsedString);
105 textFile.Close();
106 }
107 catch
108 {
109 Console.WriteLine("creating a log file failed for: {0}", logFile);
110 }
111
112 }
113 }
114
115 public class FileExistsTask : Task
116 {
117 public FileExistsTask(string Data) : base(Data) { }
118
119 public override void RunTask()
120 {
121 string fileToExist = System.Environment.ExpandEnvironmentVariables(this.data);
122
123 if (!String.IsNullOrEmpty(fileToExist))
124 {
125 Console.WriteLine("Waiting for this file to exist: \"" + fileToExist + "\"");
126 while (!System.IO.File.Exists(fileToExist))
127 {
128 System.Threading.Thread.Sleep(250);
129 }
130 Console.WriteLine("Found: \"" + fileToExist + "\"");
131 }
132
133 }
134 }
135
136 public class TaskParser
137 {
138
139 public static List<Task> ParseTasks(string[] args)
140 {
141 List<Task> tasks = new List<Task>();
142
143 try
144 {
145 // for invalid args. return empty list
146 if (args.Length % 2 == 0)
147 {
148 Task t;
149
150 for (int i = 0; i < args.Length; i += 2)
151 {
152 switch (args[i].ToLower())
153 {
154 case "/ec":
155 t = new ExitCodeTask(args[i + 1]);
156 tasks.Add(t);
157 break;
158 case "/s":
159 t = new SleepTask(args[i + 1]);
160 tasks.Add(t);
161 break;
162 case "/sr":
163 t = new SleepRandomTask(args[i + 1]);
164 tasks.Add(t);
165 break;
166 case "/lf":
167 t = new LargeFileTask(args[i + 1]);
168 tasks.Add(t);
169 break;
170 case "/log":
171 t = new LogTask(args[i + 1], args);
172 tasks.Add(t);
173 break;
174 case "/fe":
175 t = new FileExistsTask(args[i + 1]);
176 tasks.Add(t);
177 break;
178#if NET35
179 case "/pinfo":
180 t = new ProcessInfoTask(args[i + 1]);
181 tasks.Add(t);
182 break;
183 case "/regw":
184 t = new RegistryWriterTask(args[i + 1]);
185 tasks.Add(t);
186 break;
187 case "/regd":
188 t = new RegistryDeleterTask(args[i + 1]);
189 tasks.Add(t);
190 break;
191#endif
192
193 default:
194 Console.WriteLine("Error: Invalid switch specified.");
195 return new List<Task>();
196 }
197 }
198 }
199 }
200 catch
201 {
202 Console.WriteLine("Error: Invalid switch data specified. Couldn't parse the data.");
203 return new List<Task>();
204 }
205
206 return tasks;
207 }
208 }
209}
diff --git a/src/test/burn/TestExe/TestExe.csproj b/src/test/burn/TestExe/TestExe.csproj
new file mode 100644
index 00000000..5a130422
--- /dev/null
+++ b/src/test/burn/TestExe/TestExe.csproj
@@ -0,0 +1,20 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFrameworks>net35;netcoreapp3.1</TargetFrameworks>
7 <AssemblyName>TestExe</AssemblyName>
8 <RootNamespace>TestExe</RootNamespace>
9 <OutputType>Exe</OutputType>
10 <DebugType>embedded</DebugType>
11 <RuntimeIdentifier>win-x86</RuntimeIdentifier>
12 <SelfContained>false</SelfContained>
13 <UseAppHost>true</UseAppHost>
14 <RollForward>Major</RollForward>
15 </PropertyGroup>
16
17 <ItemGroup Condition="'$(TargetFramework)'=='net35'">
18 <Reference Include="System.Management" />
19 </ItemGroup>
20</Project> \ No newline at end of file
diff --git a/src/test/burn/TestExe/TestExe_x64.csproj b/src/test/burn/TestExe/TestExe_x64.csproj
new file mode 100644
index 00000000..1dd2d8e6
--- /dev/null
+++ b/src/test/burn/TestExe/TestExe_x64.csproj
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFrameworks>net35</TargetFrameworks>
7 <AssemblyName>TestExe</AssemblyName>
8 <RootNamespace>TestExe</RootNamespace>
9 <OutputType>Exe</OutputType>
10 <DebugType>embedded</DebugType>
11 <RuntimeIdentifier>win-x64</RuntimeIdentifier>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Reference Include="System.Management" />
16 </ItemGroup>
17</Project> \ No newline at end of file
diff --git a/src/test/burn/TestExe/app.config b/src/test/burn/TestExe/app.config
new file mode 100644
index 00000000..f9811b74
--- /dev/null
+++ b/src/test/burn/TestExe/app.config
@@ -0,0 +1,10 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4
5<configuration>
6 <startup>
7 <supportedRuntime version="v4.0" />
8 <supportedRuntime version="v2.0.50727" />
9 </startup>
10</configuration>
diff --git a/src/test/burn/Wix.Build.props b/src/test/burn/Wix.Build.props
new file mode 100644
index 00000000..06cf5b1d
--- /dev/null
+++ b/src/test/burn/Wix.Build.props
@@ -0,0 +1,11 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <TestGroupName Condition=" '$(TestGroupName)'=='' ">$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))))</TestGroupName>
5 <BaseIntermediateOutputPath>$(BaseOutputPath)obj\$(TestGroupName)\$(ProjectName)\</BaseIntermediateOutputPath>
6 <OutputPath>$(OutputPath)netcoreapp3.1\TestData\$(TestGroupName)\</OutputPath>
7 <DefaultCompressionLevel>None</DefaultCompressionLevel>
8 <CompilerAdditionalOptions>-wx</CompilerAdditionalOptions>
9 <SuppressSpecificWarnings>1154;$(SuppressSpecificWarnings)</SuppressSpecificWarnings>
10 </PropertyGroup>
11</Project>
diff --git a/src/test/burn/Wix.Build.targets b/src/test/burn/Wix.Build.targets
new file mode 100644
index 00000000..17a46e2a
--- /dev/null
+++ b/src/test/burn/Wix.Build.targets
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3<Project>
4 <PropertyGroup>
5 <BundleName Condition=" '$(BundleName)' == '' ">$(MSBuildProjectName)</BundleName>
6 <PackageName Condition=" '$(PackageName)' == '' ">$(MSBuildProjectName)</PackageName>
7 <WebServerBaseUrl Condition=" '$(WebServerBaseUrl)' == '' ">http://localhost:9999/e2e/</WebServerBaseUrl>
8 <DefineConstants>TestGroupName=$(TestGroupName);PackageName=$(PackageName);BundleName=$(BundleName);WebServerBaseUrl=$(WebServerBaseUrl);$(DefineConstants)</DefineConstants>
9 <DefineConstants Condition=" '$(BA)' != '' ">BA=$(BA);$(DefineConstants)</DefineConstants>
10 <DefineConstants Condition=" '$(CabPrefix)' != '' ">CabPrefix=$(CabPrefix);$(DefineConstants)</DefineConstants>
11 <DefineConstants Condition=" '$(IncludeSoftwareTag)' == 'true' ">SoftwareTag=1;$(DefineConstants)</DefineConstants>
12 <DefineConstants Condition=" '$(ProductCode)' != '' ">ProductCode=$(ProductCode);$(DefineConstants)</DefineConstants>
13 <DefineConstants Condition=" '$(ProductComponentsRef)' == 'true' ">ProductComponents=1;$(DefineConstants)</DefineConstants>
14 <DefineConstants Condition=" '$(UpgradeCode)' != '' ">UpgradeCode=$(UpgradeCode);$(DefineConstants)</DefineConstants>
15 <DefineConstants Condition=" '$(Version)' != '' ">Version=$(Version);$(DefineConstants)</DefineConstants>
16 </PropertyGroup>
17</Project>
diff --git a/src/test/burn/WixTestTools/BundleInstaller.cs b/src/test/burn/WixTestTools/BundleInstaller.cs
new file mode 100644
index 00000000..a49c4024
--- /dev/null
+++ b/src/test/burn/WixTestTools/BundleInstaller.cs
@@ -0,0 +1,197 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Text;
8
9 public partial class BundleInstaller : IDisposable
10 {
11 public BundleInstaller(WixTestContext testContext, string name)
12 {
13 this.Bundle = Path.Combine(testContext.TestDataFolder, $"{name}.exe");
14 this.BundlePdb = Path.Combine(testContext.TestDataFolder, $"{name}.wixpdb");
15 this.TestContext = testContext;
16 this.TestGroupName = testContext.TestGroupName;
17 this.TestName = testContext.TestName;
18 }
19
20 public string Bundle { get; }
21
22 private WixTestContext TestContext { get; }
23
24 public string TestGroupName { get; }
25
26 public string TestName { get; }
27
28 /// <summary>
29 /// Installs the bundle with optional arguments.
30 /// </summary>
31 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
32 /// <param name="arguments">Optional arguments to pass to the tool.</param>
33 /// <returns>Path to the generated log file.</returns>
34 public string Install(int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
35 {
36 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Install, arguments);
37 }
38
39 /// <summary>
40 /// Installs the bundle with optional arguments.
41 /// </summary>
42 /// <param name="bundlePath">This should be the bundle in the package cache.</param>
43 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
44 /// <param name="arguments">Optional arguments to pass to the tool.</param>
45 /// <returns>Path to the generated log file.</returns>
46 public string Install(string bundlePath, int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
47 {
48 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Install, arguments, bundlePath: bundlePath);
49 }
50
51 /// <summary>
52 /// Calls Layout for the bundle with optional arguments.
53 /// </summary>
54 /// <param name="layoutDirectory">The destination directory.</param>
55 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
56 /// <param name="arguments">Optional arguments to pass to the tool.</param>
57 /// <returns>Path to the generated log file.</returns>
58 public string Layout(string layoutDirectory, int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
59 {
60 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.AdministrativeInstall, arguments, layoutDirectory: layoutDirectory);
61 }
62
63 /// <summary>
64 /// Calls Layout for the bundle with optional arguments.
65 /// </summary>
66 /// <param name="bundlePath">Path to the bundle to run.</param>
67 /// <param name="layoutDirectory">The destination directory.</param>
68 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
69 /// <param name="arguments">Optional arguments to pass to the tool.</param>
70 /// <returns>Path to the generated log file.</returns>
71 public string Layout(string bundlePath, string layoutDirectory, int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
72 {
73 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.AdministrativeInstall, arguments, bundlePath: bundlePath, layoutDirectory: layoutDirectory);
74 }
75
76 /// <summary>
77 /// Modify the bundle with optional arguments.
78 /// </summary>
79 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
80 /// <param name="arguments">Optional arguments to pass to the tool.</param>
81 /// <returns>Path to the generated log file.</returns>
82 public string Modify(int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
83 {
84 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Modify, arguments);
85 }
86
87 /// <summary>
88 /// Modify the bundle with optional arguments.
89 /// </summary>
90 /// <param name="bundlePath">This should be the bundle in the package cache.</param>
91 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
92 /// <param name="arguments">Optional arguments to pass to the tool.</param>
93 /// <returns>Path to the generated log file.</returns>
94 public string Modify(string bundlePath, int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
95 {
96 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Modify, arguments, bundlePath: bundlePath);
97 }
98
99 /// <summary>
100 /// Repairs the bundle with optional arguments.
101 /// </summary>
102 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
103 /// <param name="arguments">Optional arguments to pass to the tool.</param>
104 /// <returns>Path to the generated log file.</returns>
105 public string Repair(int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
106 {
107 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Repair, arguments);
108 }
109
110 /// <summary>
111 /// Uninstalls the bundle with optional arguments.
112 /// </summary>
113 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
114 /// <param name="arguments">Optional arguments to pass to the tool.</param>
115 /// <returns>Path to the generated log file.</returns>
116 public string Uninstall(int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
117 {
118 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Uninstall, arguments);
119 }
120
121 /// <summary>
122 /// Uninstalls the bundle at the given path with optional arguments.
123 /// </summary>
124 /// <param name="bundlePath">This should be the bundle in the package cache.</param>
125 /// <param name="expectedExitCode">Expected exit code, defaults to success.</param>
126 /// <param name="arguments">Optional arguments to pass to the tool.</param>
127 /// <returns>Path to the generated log file.</returns>
128 public string Uninstall(string bundlePath, int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments)
129 {
130 return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Uninstall, arguments, bundlePath: bundlePath);
131 }
132
133 /// <summary>
134 /// Executes the bundle with optional arguments.
135 /// </summary>
136 /// <param name="expectedExitCode">Expected exit code.</param>
137 /// <param name="mode">Install mode.</param>
138 /// <param name="arguments">Optional arguments to pass to the tool.</param>
139 /// <returns>Path to the generated log file.</returns>
140 private string RunBundleWithArguments(int expectedExitCode, MSIExec.MSIExecMode mode, string[] arguments, bool assertOnError = true, string bundlePath = null, string layoutDirectory = null)
141 {
142 TestTool bundle = new TestTool(bundlePath ?? this.Bundle);
143 var sb = new StringBuilder();
144
145 // Be sure to run silent.
146 sb.Append(" -quiet");
147
148 // Generate the log file name.
149 string logFile = Path.Combine(Path.GetTempPath(), String.Format("{0}_{1}_{2:yyyyMMddhhmmss}_{4}_{3}.log", this.TestGroupName, this.TestName, DateTime.UtcNow, Path.GetFileNameWithoutExtension(this.Bundle), mode));
150 sb.AppendFormat(" -log \"{0}\"", logFile);
151
152 // Set operation.
153 switch (mode)
154 {
155 case MSIExec.MSIExecMode.AdministrativeInstall:
156 sb.Append($" -layout \"{layoutDirectory}\"");
157 break;
158
159 case MSIExec.MSIExecMode.Modify:
160 sb.Append(" -modify");
161 break;
162
163 case MSIExec.MSIExecMode.Repair:
164 sb.Append(" -repair");
165 break;
166
167 case MSIExec.MSIExecMode.Cleanup:
168 case MSIExec.MSIExecMode.Uninstall:
169 sb.Append(" -uninstall");
170 break;
171 }
172
173 // Add additional arguments.
174 if (null != arguments)
175 {
176 sb.Append(" ");
177 sb.Append(String.Join(" ", arguments));
178 }
179
180 // Set the arguments.
181 bundle.Arguments = sb.ToString();
182
183 // Run the tool and assert the expected code.
184 bundle.ExpectedExitCode = expectedExitCode;
185 bundle.Run(assertOnError);
186
187 // Return the log file name.
188 return logFile;
189 }
190
191 public void Dispose()
192 {
193 string[] args = { "-burn.ignoredependencies=ALL" };
194 this.RunBundleWithArguments((int)MSIExec.MSIExecReturnCode.SUCCESS, MSIExec.MSIExecMode.Cleanup, args, assertOnError: false);
195 }
196 }
197}
diff --git a/src/test/burn/WixTestTools/BundleRegistration.cs b/src/test/burn/WixTestTools/BundleRegistration.cs
new file mode 100644
index 00000000..75660838
--- /dev/null
+++ b/src/test/burn/WixTestTools/BundleRegistration.cs
@@ -0,0 +1,182 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using Microsoft.Win32;
7
8 public class BundleRegistration
9 {
10 public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
11 public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY_WOW6432NODE = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
12 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH = "BundleCachePath";
13 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE = "BundleAddonCode";
14 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE = "BundleDetectCode";
15 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE = "BundlePatchCode";
16 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = "BundleUpgradeCode";
17 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME = "DisplayName";
18 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION = "BundleVersion";
19 public const string BURN_REGISTRATION_REGISTRY_ENGINE_VERSION = "EngineVersion";
20 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = "BundleProviderKey";
21 public const string BURN_REGISTRATION_REGISTRY_BUNDLE_TAG = "BundleTag";
22 public const string REGISTRY_REBOOT_PENDING_FORMAT = "{0}.RebootRequired";
23 public const string REGISTRY_BUNDLE_INSTALLED = "Installed";
24 public const string REGISTRY_BUNDLE_DISPLAY_ICON = "DisplayIcon";
25 public const string REGISTRY_BUNDLE_DISPLAY_VERSION = "DisplayVersion";
26 public const string REGISTRY_BUNDLE_ESTIMATED_SIZE = "EstimatedSize";
27 public const string REGISTRY_BUNDLE_PUBLISHER = "Publisher";
28 public const string REGISTRY_BUNDLE_HELP_LINK = "HelpLink";
29 public const string REGISTRY_BUNDLE_HELP_TELEPHONE = "HelpTelephone";
30 public const string REGISTRY_BUNDLE_URL_INFO_ABOUT = "URLInfoAbout";
31 public const string REGISTRY_BUNDLE_URL_UPDATE_INFO = "URLUpdateInfo";
32 public const string REGISTRY_BUNDLE_PARENT_DISPLAY_NAME = "ParentDisplayName";
33 public const string REGISTRY_BUNDLE_PARENT_KEY_NAME = "ParentKeyName";
34 public const string REGISTRY_BUNDLE_COMMENTS = "Comments";
35 public const string REGISTRY_BUNDLE_CONTACT = "Contact";
36 public const string REGISTRY_BUNDLE_NO_MODIFY = "NoModify";
37 public const string REGISTRY_BUNDLE_MODIFY_PATH = "ModifyPath";
38 public const string REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY = "NoElevateOnModify";
39 public const string REGISTRY_BUNDLE_NO_REMOVE = "NoRemove";
40 public const string REGISTRY_BUNDLE_SYSTEM_COMPONENT = "SystemComponent";
41 public const string REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING = "QuietUninstallString";
42 public const string REGISTRY_BUNDLE_UNINSTALL_STRING = "UninstallString";
43 public const string REGISTRY_BUNDLE_RESUME_COMMAND_LINE = "BundleResumeCommandLine";
44 public const string REGISTRY_BUNDLE_VERSION_MAJOR = "VersionMajor";
45 public const string REGISTRY_BUNDLE_VERSION_MINOR = "VersionMinor";
46
47 public string[] AddonCodes { get; set; }
48
49 public string CachePath { get; set; }
50
51 public string DisplayName { get; set; }
52
53 public string[] DetectCodes { get; set; }
54
55 public string EngineVersion { get; set; }
56
57 public int? EstimatedSize { get; set; }
58
59 public int? Installed { get; set; }
60
61 public string ModifyPath { get; set; }
62
63 public string[] PatchCodes { get; set; }
64
65 public string ProviderKey { get; set; }
66
67 public string Publisher { get; set; }
68
69 public string QuietUninstallString { get; set; }
70
71 public string QuietUninstallCommand { get; set; }
72
73 public string QuietUninstallCommandArguments { get; set; }
74
75 public string Tag { get; set; }
76
77 public string UninstallCommand { get; set; }
78
79 public string UninstallCommandArguments { get; set; }
80
81 public string UninstallString { get; set; }
82
83 public string[] UpgradeCodes { get; set; }
84
85 public string UrlInfoAbout { get; set; }
86
87 public string UrlUpdateInfo { get; set; }
88
89 public string Version { get; set; }
90
91 public static bool TryGetPerMachineBundleRegistrationById(string bundleId, bool x64, out BundleRegistration registration)
92 {
93 var baseKeyPath = x64 ? BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY : BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY_WOW6432NODE;
94 var registrationKeyPath = $"{baseKeyPath}\\{bundleId}";
95 using var registrationKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath);
96 var success = registrationKey != null;
97 registration = success ? GetBundleRegistration(registrationKey) : null;
98 return success;
99 }
100
101 public static bool TryGetPerUserBundleRegistrationById(string bundleId, out BundleRegistration registration)
102 {
103 var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}";
104 using var registrationKey = Registry.CurrentUser.OpenSubKey(registrationKeyPath);
105 var success = registrationKey != null;
106 registration = success ? GetBundleRegistration(registrationKey) : null;
107 return success;
108 }
109
110 private static BundleRegistration GetBundleRegistration(RegistryKey idKey)
111 {
112 var registration = new BundleRegistration();
113
114 registration.AddonCodes = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE) as string[];
115 registration.CachePath = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH) as string;
116 registration.DetectCodes = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE) as string[];
117 registration.PatchCodes = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE) as string[];
118 registration.ProviderKey = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY) as string;
119 registration.Tag = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_TAG) as string;
120 registration.UpgradeCodes = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE) as string[];
121 registration.Version = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION) as string;
122 registration.DisplayName = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME) as string;
123 registration.EngineVersion = idKey.GetValue(BURN_REGISTRATION_REGISTRY_ENGINE_VERSION) as string;
124 registration.EstimatedSize = idKey.GetValue(REGISTRY_BUNDLE_ESTIMATED_SIZE) as int?;
125 registration.Installed = idKey.GetValue(REGISTRY_BUNDLE_INSTALLED) as int?;
126 registration.ModifyPath = idKey.GetValue(REGISTRY_BUNDLE_MODIFY_PATH) as string;
127 registration.Publisher = idKey.GetValue(REGISTRY_BUNDLE_PUBLISHER) as string;
128 registration.UrlInfoAbout = idKey.GetValue(REGISTRY_BUNDLE_URL_INFO_ABOUT) as string;
129 registration.UrlUpdateInfo = idKey.GetValue(REGISTRY_BUNDLE_URL_UPDATE_INFO) as string;
130
131 registration.QuietUninstallString = idKey.GetValue(REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING) as string;
132 if (!String.IsNullOrEmpty(registration.QuietUninstallString))
133 {
134 var closeQuote = registration.QuietUninstallString.IndexOf("\"", 1);
135 if (closeQuote > 0)
136 {
137 registration.QuietUninstallCommand = registration.QuietUninstallString.Substring(1, closeQuote - 1).Trim();
138 registration.QuietUninstallCommandArguments = registration.QuietUninstallString.Substring(closeQuote + 1).Trim();
139 }
140 }
141
142 registration.UninstallString = idKey.GetValue(REGISTRY_BUNDLE_UNINSTALL_STRING) as string;
143 if (!String.IsNullOrEmpty(registration.UninstallString))
144 {
145 var closeQuote = registration.UninstallString.IndexOf("\"", 1);
146 if (closeQuote > 0)
147 {
148 registration.UninstallCommand = registration.UninstallString.Substring(1, closeQuote - 1).Trim();
149 registration.UninstallCommandArguments = registration.UninstallString.Substring(closeQuote + 1).Trim();
150 }
151 }
152
153 return registration;
154 }
155
156 public static bool TryGetDependencyProviderValue(string providerId, string name, out string value)
157 {
158 value = null;
159
160 string key = String.Format(@"Installer\Dependencies\{0}", providerId);
161 using (RegistryKey providerKey = Registry.ClassesRoot.OpenSubKey(key))
162 {
163 if (null == providerKey)
164 {
165 return false;
166 }
167
168 value = providerKey.GetValue(name) as string;
169 return value != null;
170 }
171 }
172
173 public static bool DependencyDependentExists(string providerId, string dependentId)
174 {
175 string key = String.Format(@"Installer\Dependencies\{0}\Dependents\{1}", providerId, dependentId);
176 using (RegistryKey dependentKey = Registry.ClassesRoot.OpenSubKey(key))
177 {
178 return null != dependentKey;
179 }
180 }
181 }
182}
diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs
new file mode 100644
index 00000000..984df169
--- /dev/null
+++ b/src/test/burn/WixTestTools/BundleVerifier.cs
@@ -0,0 +1,156 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Linq;
8 using System.Text;
9 using Microsoft.Win32;
10 using WixToolset.Data;
11 using WixToolset.Data.Symbols;
12 using Xunit;
13
14 public partial class BundleInstaller
15 {
16 public const string FULL_BURN_POLICY_REGISTRY_PATH = "SOFTWARE\\WOW6432Node\\Policies\\WiX\\Burn";
17 public const string PACKAGE_CACHE_FOLDER_NAME = "Package Cache";
18
19 public string BundlePdb { get; }
20
21 private WixBundleSymbol BundleSymbol { get; set; }
22
23 private WixBundleSymbol GetBundleSymbol()
24 {
25 if (this.BundleSymbol == null)
26 {
27 using var wixOutput = WixOutput.Read(this.BundlePdb);
28 var intermediate = Intermediate.Load(wixOutput);
29 var section = intermediate.Sections.Single();
30 this.BundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
31 }
32
33 return this.BundleSymbol;
34 }
35
36 public string GetPackageCachePathForCacheId(string cacheId, bool perMachine)
37 {
38 string cachePath;
39 if (perMachine)
40 {
41 using var policyKey = Registry.LocalMachine.OpenSubKey(FULL_BURN_POLICY_REGISTRY_PATH);
42 var redirectedCachePath = policyKey?.GetValue("PackageCache") as string;
43 cachePath = redirectedCachePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), PACKAGE_CACHE_FOLDER_NAME);
44 }
45 else
46 {
47 cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PACKAGE_CACHE_FOLDER_NAME);
48 }
49 return Path.Combine(cachePath, cacheId);
50 }
51
52 public string GetExpectedCachedBundlePath()
53 {
54 var bundleSymbol = this.GetBundleSymbol();
55 var cachePath = this.GetPackageCachePathForCacheId(bundleSymbol.BundleId, bundleSymbol.PerMachine);
56 return Path.Combine(cachePath, Path.GetFileName(this.Bundle));
57 }
58
59 public string ManuallyCache()
60 {
61 var expectedCachePath = this.GetExpectedCachedBundlePath();
62 Directory.CreateDirectory(Path.GetDirectoryName(expectedCachePath));
63 File.Copy(this.Bundle, expectedCachePath);
64 return expectedCachePath;
65 }
66
67 public void ManuallyUncache()
68 {
69 var expectedCachePath = this.GetExpectedCachedBundlePath();
70 File.Delete(expectedCachePath);
71 }
72
73 public bool TryGetRegistration(out BundleRegistration registration)
74 {
75 var bundleSymbol = this.GetBundleSymbol();
76 var x64 = bundleSymbol.Platform != Platform.X86;
77 var bundleId = bundleSymbol.BundleId;
78 if (bundleSymbol.PerMachine)
79 {
80 return BundleRegistration.TryGetPerMachineBundleRegistrationById(bundleId, x64, out registration);
81 }
82 else
83 {
84 return BundleRegistration.TryGetPerUserBundleRegistrationById(bundleId, out registration);
85 }
86 }
87
88 public string VerifyRegisteredAndInPackageCache()
89 {
90 Assert.True(this.TryGetRegistration(out var registration));
91
92 Assert.NotNull(registration.CachePath);
93 Assert.True(File.Exists(registration.CachePath));
94
95 var expectedCachePath = this.GetExpectedCachedBundlePath();
96 Assert.Equal(expectedCachePath, registration.CachePath, StringComparer.OrdinalIgnoreCase);
97
98 return registration.CachePath;
99 }
100
101 public void VerifyUnregisteredAndRemovedFromPackageCache()
102 {
103 var cachedBundlePath = this.GetExpectedCachedBundlePath();
104 this.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
105 }
106
107 public void VerifyUnregisteredAndRemovedFromPackageCache(string cachedBundlePath)
108 {
109 Assert.False(this.TryGetRegistration(out _));
110 Assert.False(File.Exists(cachedBundlePath));
111 }
112
113 public void RemovePackageFromCache(string packageId)
114 {
115 using var wixOutput = WixOutput.Read(this.BundlePdb);
116 var intermediate = Intermediate.Load(wixOutput);
117 var section = intermediate.Sections.Single();
118 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
119 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes);
120 if (Directory.Exists(cachePath))
121 {
122 Directory.Delete(cachePath, true);
123 }
124 }
125
126 public void VerifyPackageIsCached(string packageId)
127 {
128 using var wixOutput = WixOutput.Read(this.BundlePdb);
129 var intermediate = Intermediate.Load(wixOutput);
130 var section = intermediate.Sections.Single();
131 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
132 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes);
133 Assert.True(Directory.Exists(cachePath));
134 }
135
136 public void VerifyExeTestRegistryRootDeleted(string name, bool x64 = false)
137 {
138 using var testRegistryRoot = this.TestContext.GetTestRegistryRoot(x64, name);
139 if (testRegistryRoot != null)
140 {
141 var actualValue = testRegistryRoot.GetValue("Version") as string;
142 Assert.Null(actualValue);
143 }
144 }
145
146 public void VerifyExeTestRegistryValue(string name, string expectedValue, bool x64 = false)
147 {
148 using (var root = this.TestContext.GetTestRegistryRoot(x64, name))
149 {
150 Assert.NotNull(root);
151 var actualValue = root.GetValue("Version") as string;
152 Assert.Equal(expectedValue, actualValue);
153 }
154 }
155 }
156}
diff --git a/src/test/burn/WixTestTools/LogVerifier.cs b/src/test/burn/WixTestTools/LogVerifier.cs
new file mode 100644
index 00000000..0252a9f9
--- /dev/null
+++ b/src/test/burn/WixTestTools/LogVerifier.cs
@@ -0,0 +1,252 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using System.Text.RegularExpressions;
9 using Xunit;
10
11 /// <summary>
12 /// The LogVerifier can verify a log file for given regular expressions.
13 /// </summary>
14 public class LogVerifier
15 {
16 // Member Variables
17 private string logFile;
18
19 /// <summary>
20 /// Prevent creation of LogVerifier without log file
21 /// </summary>
22 private LogVerifier()
23 { }
24
25 /// <summary>
26 /// Constructor for log files where the exact file name is known.
27 /// </summary>
28 /// <param name="fileName">The full path to the log file</param>
29 public LogVerifier(string fileName)
30 {
31 if (null == fileName)
32 throw new ArgumentNullException("fileName");
33
34 if (!File.Exists(fileName))
35 throw new ArgumentException(String.Format(@"File doesn't exist:{0}", fileName), "fileName");
36
37 logFile = fileName;
38 }
39
40 /// <summary>
41 /// Constructor for log files where the exact file name is known.
42 /// </summary>
43 /// <param name="directory">The directory in which the log file is located.</param>
44 /// <param name="fileName">The name of the log file.</param>
45 public LogVerifier(string directory, string fileName)
46 : this(Path.Combine(directory, fileName))
47 { }
48
49 /// <summary>
50 /// Scans a log file line by line until the regex pattern is matched or eof is reached.
51 /// This method would be used in the case where the log file is very large, the regex doesn't
52 /// span multiple lines, and only one match is required.
53 /// </summary>
54 /// <param name="regex">A regular expression</param>
55 /// <returns>True if a match is found, False otherwise.</returns>
56 public bool LineByLine(Regex regex)
57 {
58 string line = string.Empty;
59 StreamReader sr = new StreamReader(logFile);
60
61 // Read from a file stream line by line.
62 while ((line = sr.ReadLine()) != null)
63 {
64 if (regex.Match(line).Success)
65 {
66 sr.Close();
67 sr.Dispose();
68 return true;
69 }
70 }
71 return false;
72 }
73
74
75 /// <summary>
76 /// Scans a log file line by line until the regex pattern is matched or eof is reached.
77 /// This method would be used in the case where the log file is very large, the regex doesn't
78 /// span multiple lines, and only one match is required.
79 /// No RegexOptions are used and matches are case sensitive.
80 /// </summary>
81 /// <param name="regex">A regular expression string.</param>
82 /// <returns>True if a match is found, False otherwise.</returns>
83 public bool LineByLine(string regex)
84 {
85 return LineByLine(new Regex(regex));
86 }
87
88
89 /// <summary>
90 /// Scans a log file for matches to the regex.
91 /// </summary>
92 /// <param name="regex">A regular expression</param>
93 /// <returns>The number of matches</returns>
94 public int EntireFileAtOnce(Regex regex)
95 {
96 string logFileText = this.ReadLogFile();
97 return regex.Matches(logFileText).Count;
98 }
99
100 /// <summary>
101 /// Scans a log file for matches to the regex.
102 /// </summary>
103 /// <param name="regex">A regular expression</param>
104 /// <returns>The number of matches</returns>
105 public bool EntireFileAtOncestr(string regex)
106 {
107 string logFileText = this.ReadLogFile();
108 return logFileText.Contains(regex);
109 }
110 /// <summary>
111 /// Scans a log file for matches to the regex string.
112 /// Only the Multiline RegexOption is used and matches are case sensitive.
113 /// </summary>
114 /// <param name="regex">A regular expression</param>
115 /// <returns>The number of matches</returns>
116 public int EntireFileAtOnce(string regex)
117 {
118 return EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline));
119 }
120
121 /// <summary>
122 /// Scans a log file for matches to the regex string.
123 /// </summary>
124 /// <param name="regex">A regular expression</param>
125 /// <param name="ignoreCase">Specify whether to perform case sensitive matches</param>
126 /// <returns>The number of matches</returns>
127 public int EntireFileAtOnce(string regex, bool ignoreCase)
128 {
129 if (!ignoreCase)
130 return EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline));
131 else
132 return EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline | RegexOptions.IgnoreCase));
133 }
134
135 /// <summary>
136 /// Search through the log and Assert.Fail() if a specified string is not found.
137 /// </summary>
138 /// <param name="regex">Search expression</param>
139 /// <param name="ignoreCase">Perform case insensitive match</param>
140 public void AssertTextInLog(string regex, bool ignoreCase)
141 {
142 Assert.True(EntireFileAtOncestr(regex),
143 String.Format("The log does not contain a match to the regular expression \"{0}\" ", regex));
144 }
145
146 /// <summary>
147 /// Search through the log and Assert.Fail() if a specified string is not found.
148 /// </summary>
149 /// <param name="regex">Search expression</param>
150 /// <param name="ignoreCase">Perform case insensitive match</param>
151 public void AssertTextInLog(Regex regex, bool ignoreCase)
152 {
153 Assert.True(EntireFileAtOnce(regex) >= 1,
154 String.Format("The log does not contain a match to the regular expression \"{0}\" ", regex.ToString()));
155 }
156
157 /// <summary>
158 /// Search through the log and Assert.Fail() if a specified string is not found.
159 /// </summary>
160 /// <param name="regex">Search expression</param>
161 /// <param name="ignoreCase">Perform case insensitive match</param>
162 public void AssertTextInLog(string regex)
163 {
164 AssertTextInLog(regex, true);
165 }
166
167 /// <summary>
168 /// Search through the log and Assert.Fail() if a specified string is not found.
169 /// </summary>
170 /// <param name="regex">Search expression</param>
171 /// <param name="ignoreCase">Perform case insensitive match</param>
172 public void AssertTextInLog(Regex regex)
173 {
174 AssertTextInLog(regex, true);
175 }
176
177
178 /// <summary>
179 /// Search through the log and Assert.Fail() if a specified string is found.
180 /// </summary>
181 /// <param name="regex">Search expression</param>
182 /// <param name="ignoreCase">Perform case insensitive match</param>
183 public void AssertTextNotInLog(Regex regex, bool ignoreCase)
184 {
185 Assert.True(EntireFileAtOnce(regex) < 1,
186 String.Format("The log contain a match to the regular expression \"{0}\" ", regex.ToString()));
187 }
188
189 /// <summary>
190 /// Search through the log and Assert.Fail() if a specified string is not found.
191 /// </summary>
192 /// <param name="regex">Search expression</param>
193 /// <param name="ignoreCase">Perform case insensitive match</param>
194 public void AssertTextNotInLog(string regex, bool ignoreCase)
195 {
196 Assert.False(EntireFileAtOncestr(regex),
197 String.Format("The log does not contain a match to the regular expression \"{0}\" ", regex));
198 }
199
200 /// <summary>
201 /// Checks if a meesage is in a file
202 /// </summary>
203 /// <param name="logFileName">The full path to the log file</param>
204 /// <param name="message">Search expression</param>
205 /// <returns>True if the message was found, false otherwise</returns>
206 public static bool MessageInLogFile(string logFileName, string message)
207 {
208 LogVerifier logVerifier = new LogVerifier(logFileName);
209 return logVerifier.EntireFileAtOncestr(message);
210 }
211
212 /// <summary>
213 /// Checks if a meesage is in a file
214 /// </summary>
215 /// <param name="logFileName">The full path to the log file</param>
216 /// <param name="message">Search expression (regex)</param>
217 /// <returns>True if the message was found, false otherwise</returns>
218 public static bool MessageInLogFileRegex(string logFileName, string regexMessage)
219 {
220 LogVerifier logVerifier = new LogVerifier(logFileName);
221 return logVerifier.EntireFileAtOnce(regexMessage) > 0;
222 }
223
224 /// <summary>
225 /// Read in the entire log file at once.
226 /// </summary>
227 /// <returns>Contents of log file.</returns>
228 private string ReadLogFile()
229 {
230 // Retry a few times.
231 for (int retry = 0; ; ++retry)
232 {
233 try
234 {
235 using (StreamReader sr = new StreamReader(this.logFile))
236 {
237 return sr.ReadToEnd();
238 }
239 }
240 catch // we'll catch everything a few times until we give up.
241 {
242 if (retry > 4)
243 {
244 throw;
245 }
246
247 System.Threading.Thread.Sleep(1000);
248 }
249 }
250 }
251 }
252}
diff --git a/src/test/burn/WixTestTools/MSIExec.cs b/src/test/burn/WixTestTools/MSIExec.cs
new file mode 100644
index 00000000..8dce96cf
--- /dev/null
+++ b/src/test/burn/WixTestTools/MSIExec.cs
@@ -0,0 +1,753 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using WixBuildTools.TestSupport;
9
10 public class MSIExec : TestTool
11 {
12 /// <summary>
13 /// The expected exit code of the tool
14 /// </summary>
15 public new MSIExecReturnCode ExpectedExitCode
16 {
17 get { return (MSIExecReturnCode)base.ExpectedExitCode; }
18 set { base.ExpectedExitCode = (int?)value; }
19 }
20
21 /// <summary>
22 /// Mode of execution (install, uninstall, or repair)
23 /// </summary>
24 public MSIExecMode ExecutionMode { get; set; }
25
26 /// <summary>
27 /// Path to msi or ProductCode
28 /// </summary>
29 public string Product { get; set; }
30
31 /// <summary>
32 /// Logging Options
33 /// </summary>
34 public MSIExecLoggingOptions LoggingOptions { get; set; }
35
36 /// <summary>
37 /// Path to the log file
38 /// </summary>
39 public string LogFile { get; set; }
40
41 /// <summary>
42 /// Unattended mode - progress bar only
43 /// </summary>
44 public bool Passive { get; set; }
45
46 /// <summary>
47 /// Quiet mode, no user interaction
48 /// </summary>
49 public bool Quiet { get; set; }
50
51 /// <summary>
52 /// Sets user interface level
53 /// </summary>
54 public MSIExecUserInterfaceLevel UserInterfaceLevel { get; set; }
55
56 /// <summary>
57 /// Do not restart after the installation is complete
58 /// </summary>
59 public bool NoRestart { get; set; }
60
61 /// <summary>
62 /// Prompts the user for restart if necessary
63 /// </summary>
64 public bool PromptRestart { get; set; }
65
66 /// <summary>
67 /// Always restart the computer after installation
68 /// </summary>
69 public bool ForceRestart { get; set; }
70
71 /// <summary>
72 /// Other arguments.
73 /// </summary>
74 public string OtherArguments { get; set; }
75
76 /// <summary>
77 /// Constructor that uses the default location for MSIExec.
78 /// </summary>
79 public MSIExec()
80 : this(Environment.SystemDirectory)
81 {
82 }
83
84 /// <summary>
85 /// Constructor that accepts a path to the MSIExec location.
86 /// </summary>
87 /// <param name="toolDirectory">The directory of MSIExec.exe.</param>
88 public MSIExec(string toolDirectory)
89 : base(Path.Combine(toolDirectory, "MSIExec.exe"))
90 {
91 this.SetDefaultArguments();
92 }
93
94 public override ExternalExecutableResult Run(bool assertOnError)
95 {
96 this.Arguments = this.GetArguments();
97 return base.Run(assertOnError);
98 }
99
100 /// <summary>
101 /// Clears all of the assigned arguments and resets them to the default values.
102 /// </summary>
103 public void SetDefaultArguments()
104 {
105 this.ExecutionMode = MSIExecMode.Install;
106 this.Product = String.Empty;
107 this.Quiet = true;
108 this.Passive = false;
109 this.UserInterfaceLevel = MSIExecUserInterfaceLevel.None;
110 this.NoRestart = true;
111 this.ForceRestart = false;
112 this.PromptRestart = false;
113 this.LogFile = string.Empty;
114 this.LoggingOptions = MSIExecLoggingOptions.VOICEWARMUP;
115 this.OtherArguments = String.Empty;
116 }
117
118 public string GetArguments()
119 {
120 var arguments = new StringBuilder();
121
122 // quiet
123 if (this.Quiet)
124 {
125 arguments.Append(" /quiet ");
126 }
127
128 // passive
129 if (this.Passive)
130 {
131 arguments.Append(" /passive ");
132 }
133
134 // UserInterfaceLevel
135 switch (this.UserInterfaceLevel)
136 {
137 case MSIExecUserInterfaceLevel.None:
138 arguments.Append(" /qn ");
139 break;
140 case MSIExecUserInterfaceLevel.Basic:
141 arguments.Append(" /qb ");
142 break;
143 case MSIExecUserInterfaceLevel.Reduced:
144 arguments.Append(" /qr ");
145 break;
146 case MSIExecUserInterfaceLevel.Full:
147 arguments.Append(" /qf ");
148 break;
149 }
150
151 // NoRestart
152 if (this.NoRestart)
153 {
154 arguments.Append(" /norestart ");
155 }
156
157 // PromptRestart
158 if (this.PromptRestart)
159 {
160 arguments.Append(" /promptrestart ");
161 }
162
163 // ForceRestart
164 if (this.ForceRestart)
165 {
166 arguments.Append(" /forcerestart ");
167 }
168
169 // Logging options
170 var loggingOptionsString = new StringBuilder();
171 if ((this.LoggingOptions & MSIExecLoggingOptions.Status_Messages) == MSIExecLoggingOptions.Status_Messages)
172 {
173 loggingOptionsString.Append("i");
174 }
175 if ((this.LoggingOptions & MSIExecLoggingOptions.Nonfatal_Warnings) == MSIExecLoggingOptions.Nonfatal_Warnings)
176 {
177 loggingOptionsString.Append("w");
178 }
179 if ((this.LoggingOptions & MSIExecLoggingOptions.All_Error_Messages) == MSIExecLoggingOptions.All_Error_Messages)
180 {
181 loggingOptionsString.Append("e");
182 }
183 if ((this.LoggingOptions & MSIExecLoggingOptions.Start_Up_Of_Actions) == MSIExecLoggingOptions.Start_Up_Of_Actions)
184 {
185 loggingOptionsString.Append("a");
186 }
187 if ((this.LoggingOptions & MSIExecLoggingOptions.Action_Specific_Records) == MSIExecLoggingOptions.Action_Specific_Records)
188 {
189 loggingOptionsString.Append("r");
190 }
191 if ((this.LoggingOptions & MSIExecLoggingOptions.User_Requests) == MSIExecLoggingOptions.User_Requests)
192 {
193 loggingOptionsString.Append("u");
194 }
195 if ((this.LoggingOptions & MSIExecLoggingOptions.Initial_UI_Parameters) == MSIExecLoggingOptions.Initial_UI_Parameters)
196 {
197 loggingOptionsString.Append("c");
198 }
199 if ((this.LoggingOptions & MSIExecLoggingOptions.OutOfMemory_Or_Fatal_Exit_Information) == MSIExecLoggingOptions.OutOfMemory_Or_Fatal_Exit_Information)
200 {
201 loggingOptionsString.Append("m");
202 }
203 if ((this.LoggingOptions & MSIExecLoggingOptions.OutOfDiskSpace_Messages) == MSIExecLoggingOptions.OutOfDiskSpace_Messages)
204 {
205 loggingOptionsString.Append("o");
206 }
207 if ((this.LoggingOptions & MSIExecLoggingOptions.Terminal_Properties) == MSIExecLoggingOptions.Terminal_Properties)
208 {
209 loggingOptionsString.Append("p");
210 }
211 if ((this.LoggingOptions & MSIExecLoggingOptions.Verbose_Output) == MSIExecLoggingOptions.Verbose_Output)
212 {
213 loggingOptionsString.Append("v");
214 }
215 if ((this.LoggingOptions & MSIExecLoggingOptions.Extra_Debugging_Information) == MSIExecLoggingOptions.Extra_Debugging_Information)
216 {
217 loggingOptionsString.Append("x");
218 }
219 if ((this.LoggingOptions & MSIExecLoggingOptions.Append_To_Existing_Log_File) == MSIExecLoggingOptions.Append_To_Existing_Log_File)
220 {
221 loggingOptionsString.Append("+");
222 }
223 if ((this.LoggingOptions & MSIExecLoggingOptions.Flush_Each_line) == MSIExecLoggingOptions.Flush_Each_line)
224 {
225 loggingOptionsString.Append("!");
226 }
227 if ((this.LoggingOptions & MSIExecLoggingOptions.Log_All_Information) == MSIExecLoggingOptions.Log_All_Information)
228 {
229 loggingOptionsString.Append("*");
230 }
231
232 // logfile and logging options
233 if (0 != loggingOptionsString.Length || !string.IsNullOrEmpty(this.LogFile))
234 {
235 arguments.Append(" /l");
236 if (0 != loggingOptionsString.Length)
237 {
238 arguments.AppendFormat("{0} ", loggingOptionsString);
239 }
240 if (!string.IsNullOrEmpty(this.LogFile))
241 {
242 arguments.AppendFormat(" \"{0}\" ", this.LogFile);
243 }
244 }
245
246 // OtherArguments
247 if (!String.IsNullOrEmpty(this.OtherArguments))
248 {
249 arguments.AppendFormat(" {0} ", this.OtherArguments);
250 }
251
252 // execution mode
253 switch (this.ExecutionMode)
254 {
255 case MSIExecMode.Install:
256 arguments.Append(" /package ");
257 break;
258 case MSIExecMode.AdministrativeInstall:
259 arguments.Append(" /a ");
260 break;
261 case MSIExecMode.Repair:
262 arguments.Append(" /f ");
263 break;
264 case MSIExecMode.Cleanup:
265 case MSIExecMode.Uninstall:
266 arguments.Append(" /uninstall ");
267 break;
268 };
269
270 // product
271 if (!string.IsNullOrEmpty(this.Product))
272 {
273 arguments.AppendFormat(" \"{0}\" ", this.Product);
274 }
275
276 return arguments.ToString();
277 }
278
279 /// <summary>
280 /// Return codes from an MSI install or uninstall
281 /// </summary>
282 /// <remarks>
283 /// Error codes indicative of success are:
284 /// ERROR_SUCCESS, ERROR_SUCCESS_REBOOT_INITIATED, and ERROR_SUCCESS_REBOOT_REQUIRED
285 /// </remarks>
286 public enum MSIExecReturnCode
287 {
288 /// <summary>
289 /// ERROR_SUCCESS 0
290 /// Action completed successfully.
291 /// </summary>
292 SUCCESS = 0,
293
294 /// <summary>
295 /// ERROR_INVALID_DATA 13
296 /// The data is invalid.
297 /// </summary>
298 ERROR_INVALID_DATA = 13,
299
300 /// <summary>
301 /// ERROR_INVALID_PARAMETER 87
302 /// One of the parameters was invalid.
303 /// </summary>
304 ERROR_INVALID_PARAMETER = 87,
305
306 /// <summary>
307 /// ERROR_CALL_NOT_IMPLEMENTED 120
308 /// This value is returned when a custom action attempts to call a function that cannot be called from custom actions.
309 /// The function returns the value ERROR_CALL_NOT_IMPLEMENTED. Available beginning with Windows Installer version 3.0.
310 /// </summary>
311 ERROR_CALL_NOT_IMPLEMENTED = 120,
312
313 /// <summary>
314 /// ERROR_APPHELP_BLOCK 1259
315 /// If Windows Installer determines a product may be incompatible with the current operating system,
316 /// it displays a dialog box informing the user and asking whether to try to install anyway.
317 /// This error code is returned if the user chooses not to try the installation.
318 /// </summary>
319 ERROR_APPHELP_BLOCK = 1259,
320
321 /// <summary>
322 /// ERROR_INSTALL_SERVICE_FAILURE 1601
323 /// The Windows Installer service could not be accessed.
324 /// Contact your support personnel to verify that the Windows Installer service is properly registered.
325 /// </summary>
326 ERROR_INSTALL_SERVICE_FAILURE = 1601,
327
328
329 /// <summary>
330 /// ERROR_INSTALL_USEREXIT 1602
331 /// The user cancels installation.
332 /// </summary>
333 ERROR_INSTALL_USEREXIT = 1602,
334
335 /// <summary>
336 /// ERROR_INSTALL_FAILURE 1603
337 /// A fatal error occurred during installation.
338 /// </summary>
339 ERROR_INSTALL_FAILURE = 1603,
340
341 /// <summary>
342 /// ERROR_INSTALL_SUSPEND 1604
343 /// Installation suspended, incomplete.
344 /// </summary>
345 ERROR_INSTALL_SUSPEND = 1604,
346
347 /// <summary>
348 /// ERROR_UNKNOWN_PRODUCT 1605
349 /// This action is only valid for products that are currently installed.
350 /// </summary>
351 ERROR_UNKNOWN_PRODUCT = 1605,
352
353 /// <summary>
354 /// ERROR_UNKNOWN_FEATURE 1606
355 /// The feature identifier is not registered.
356 /// </summary>
357 ERROR_UNKNOWN_FEATURE = 1606,
358
359 /// <summary>
360 /// ERROR_UNKNOWN_COMPONENT 1607
361 /// The component identifier is not registered.
362 /// </summary>
363 ERROR_UNKNOWN_COMPONENT = 1607,
364
365 /// <summary>
366 /// ERROR_UNKNOWN_PROPERTY 1608
367 /// This is an unknown property.
368 /// </summary>
369 ERROR_UNKNOWN_PROPERTY = 1608,
370
371 /// <summary>
372 /// ERROR_INVALID_HANDLE_STATE 1609
373 /// The handle is in an invalid state.
374 /// </summary>
375 ERROR_INVALID_HANDLE_STATE = 1609,
376
377 /// <summary>
378 /// ERROR_BAD_CONFIGURATION 1610
379 /// The configuration data for this product is corrupt. Contact your support personnel.
380 /// </summary>
381 ERROR_BAD_CONFIGURATION = 1610,
382
383 /// <summary>
384 /// ERROR_INDEX_ABSENT 1611
385 /// The component qualifier not present.
386 /// </summary>
387 ERROR_INDEX_ABSENT = 1611,
388
389 /// <summary>ERROR_INSTALL_SOURCE_ABSENT 1612
390 /// The installation source for this product is not available.
391 /// Verify that the source exists and that you can access it.
392 /// </summary>
393 ERROR_INSTALL_SOURCE_ABSENT = 1612,
394
395 /// <summary>
396 /// ERROR_INSTALL_PACKAGE_VERSION 1613
397 /// This installation package cannot be installed by the Windows Installer service.
398 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.
399 /// </summary>
400 ERROR_INSTALL_PACKAGE_VERSION = 1613,
401
402 /// <summary>
403 /// ERROR_PRODUCT_UNINSTALLED 1614
404 /// The product is uninstalled.
405 /// </summary>
406 ERROR_PRODUCT_UNINSTALLED = 1614,
407
408 /// <summary>
409 /// ERROR_BAD_QUERY_SYNTAX 1615
410 /// The SQL query syntax is invalid or unsupported.
411 /// </summary>
412 ERROR_BAD_QUERY_SYNTAX = 1615,
413
414 /// <summary>
415 /// ERROR_INVALID_FIELD 1616
416 /// The record field does not exist.
417 /// </summary>
418 ERROR_INVALID_FIELD = 1616,
419
420 /// <summary>
421 /// ERROR_INSTALL_ALREADY_RUNNING 1618
422 /// Another installation is already in progress. Complete that installation before proceeding with this install.
423 /// For information about the mutex, see _MSIExecute Mutex.
424 /// </summary>
425 ERROR_INSTALL_ALREADY_RUNNING = 1618,
426
427 /// <summary>
428 /// ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619
429 /// This installation package could not be opened. Verify that the package exists and is accessible, or contact the
430 /// application vendor to verify that this is a valid Windows Installer package.
431 /// </summary>
432 ERROR_INSTALL_PACKAGE_OPEN_FAILED = 1619,
433
434
435 /// <summary>
436 /// ERROR_INSTALL_PACKAGE_INVALID 1620
437 /// This installation package could not be opened.
438 /// Contact the application vendor to verify that this is a valid Windows Installer package.
439 /// </summary>
440 ERROR_INSTALL_PACKAGE_INVALID = 1620,
441
442 /// <summary>
443 /// ERROR_INSTALL_UI_FAILURE 1621
444 /// There was an error starting the Windows Installer service user interface.
445 /// Contact your support personnel.
446 /// </summary>
447 ERROR_INSTALL_UI_FAILURE = 1621,
448
449 /// <summary>
450 /// ERROR_INSTALL_LOG_FAILURE 1622
451 /// There was an error opening installation log file.
452 /// Verify that the specified log file location exists and is writable.
453 /// </summary>
454 ERROR_INSTALL_LOG_FAILURE = 1622,
455
456 /// <summary>
457 /// ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623
458 /// This language of this installation package is not supported by your system.
459 /// </summary>
460 ERROR_INSTALL_LANGUAGE_UNSUPPORTED = 1623,
461
462 /// <summary>
463 /// ERROR_INSTALL_TRANSFORM_FAILURE 1624
464 /// There was an error applying transforms.
465 /// Verify that the specified transform paths are valid.
466 /// </summary>
467 ERROR_INSTALL_TRANSFORM_FAILURE = 1624,
468
469
470 /// <summary>
471 /// ERROR_INSTALL_PACKAGE_REJECTED 1625
472 /// This installation is forbidden by system policy.
473 /// Contact your system administrator.
474 /// </summary>
475 ERROR_INSTALL_PACKAGE_REJECTED = 1625,
476
477 /// <summary>
478 /// ERROR_FUNCTION_NOT_CALLED 1626
479 /// The function could not be executed.
480 /// </summary>
481 ERROR_FUNCTION_NOT_CALLED = 1626,
482
483 /// <summary>
484 /// ERROR_FUNCTION_FAILED 1627
485 /// The function failed during execution.
486 /// </summary>
487 ERROR_FUNCTION_FAILED = 1627,
488
489 /// <summary>
490 /// ERROR_INVALID_TABLE 1628
491 /// An invalid or unknown table was specified.
492 /// </summary>
493 ERROR_INVALID_TABLE = 1628,
494
495 /// <summary>
496 /// ERROR_DATATYPE_MISMATCH 1629
497 /// The data supplied is the wrong type.
498 /// </summary>
499 ERROR_DATATYPE_MISMATCH = 1629,
500
501 /// <summary>
502 /// ERROR_UNSUPPORTED_TYPE 1630
503 /// Data of this type is not supported.
504 /// </summary>
505 ERROR_UNSUPPORTED_TYPE = 1630,
506
507 /// <summary>
508 /// ERROR_CREATE_FAILED 1631
509 /// The Windows Installer service failed to start.
510 /// Contact your support personnel.
511 /// </summary>
512 ERROR_CREATE_FAILED = 1631,
513
514 /// <summary>
515 /// ERROR_INSTALL_TEMP_UNWRITABLE 1632
516 /// The Temp folder is either full or inaccessible.
517 /// Verify that the Temp folder exists and that you can write to it.
518 /// </summary>
519 ERROR_INSTALL_TEMP_UNWRITABLE = 1632,
520
521 /// <summary>
522 /// ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633
523 /// This installation package is not supported on this platform. Contact your application vendor. </summary>
524 ERROR_INSTALL_PLATFORM_UNSUPPORTED = 1633,
525
526 /// <summary>
527 /// ERROR_INSTALL_NOTUSED 1634
528 /// Component is not used on this machine.
529 /// </summary>
530 ERROR_INSTALL_NOTUSED = 1634,
531
532 /// <summary>
533 /// ERROR_PATCH_PACKAGE_OPEN_FAILED 1635
534 /// This patch package could not be opened. Verify that the patch package exists and is accessible,
535 /// or contact the application vendor to verify that this is a valid Windows Installer patch package.
536 /// </summary>
537 ERROR_PATCH_PACKAGE_OPEN_FAILED = 1635,
538
539 /// <summary>
540 /// ERROR_PATCH_PACKAGE_INVALID 1636
541 /// This patch package could not be opened.
542 /// Contact the application vendor to verify that this is a valid Windows Installer patch package.
543 /// </summary>
544 ERROR_PATCH_PACKAGE_INVALID = 1636,
545
546 /// <summary>
547 /// ERROR_PATCH_PACKAGE_UNSUPPORTED 1637
548 /// This patch package cannot be processed by the Windows Installer service.
549 /// You must install a Windows service pack that contains a newer version of the Windows Installer service.
550 /// </summary>
551 ERROR_PATCH_PACKAGE_UNSUPPORTED = 1637,
552
553 /// <summary>
554 /// ERROR_PRODUCT_VERSION 1638
555 /// Another version of this product is already installed.
556 /// Installation of this version cannot continue. To configure or remove the existing version of this product,
557 /// use Add/Remove Programs in Control Panel.
558 /// </summary>
559 ERROR_PRODUCT_VERSION = 1638,
560
561 /// <summary>
562 /// ERROR_INVALID_COMMAND_LINE 1639
563 /// Invalid command line argument.
564 /// Consult the Windows Installer SDK for detailed command-line help.
565 /// </summary>
566 ERROR_INVALID_COMMAND_LINE = 1639,
567
568 /// <summary>
569 /// ERROR_INSTALL_REMOTE_DISALLOWED 1640
570 /// The current user is not permitted to perform installations from a client session of a server running the
571 /// Terminal Server role service.
572 /// </summary>
573 ERROR_INSTALL_REMOTE_DISALLOWED = 1640,
574
575 /// <summary>
576 /// ERROR_SUCCESS_REBOOT_INITIATED 1641
577 /// The installer has initiated a restart.
578 /// This message is indicative of a success.
579 /// </summary>
580 ERROR_SUCCESS_REBOOT_INITIATED = 1641,
581
582 /// <summary>
583 /// ERROR_PATCH_TARGET_NOT_FOUND 1642
584 /// The installer cannot install the upgrade patch because the program being upgraded may be missing or the
585 /// upgrade patch updates a different version of the program.
586 /// Verify that the program to be upgraded exists on your computer and that you have the correct upgrade patch.
587 /// </summary>
588 ERROR_PATCH_TARGET_NOT_FOUND = 1642,
589
590 /// <summary>
591 /// ERROR_PATCH_PACKAGE_REJECTED 1643
592 /// The patch package is not permitted by system policy.
593 /// </summary>
594 ERROR_PATCH_PACKAGE_REJECTED = 1643,
595
596 /// <summary>
597 /// ERROR_INSTALL_TRANSFORM_REJECTED 1644
598 /// One or more customizations are not permitted by system policy.
599 /// </summary>
600 ERROR_INSTALL_TRANSFORM_REJECTED = 1644,
601
602 /// <summary>
603 /// ERROR_INSTALL_REMOTE_PROHIBITED 1645
604 /// Windows Installer does not permit installation from a Remote Desktop Connection.
605 /// </summary>
606 ERROR_INSTALL_REMOTE_PROHIBITED = 1645,
607
608 /// <summary>
609 /// ERROR_PATCH_REMOVAL_UNSUPPORTED 1646
610 /// The patch package is not a removable patch package. Available beginning with Windows Installer version 3.0.
611 /// </summary>
612 ERROR_PATCH_REMOVAL_UNSUPPORTED = 1646,
613
614 /// <summary>
615 /// ERROR_UNKNOWN_PATCH 1647
616 /// The patch is not applied to this product. Available beginning with Windows Installer version 3.0.
617 /// </summary>
618 ERROR_UNKNOWN_PATCH = 1647,
619
620 /// <summary>
621 /// ERROR_PATCH_NO_SEQUENCE 1648
622 /// No valid sequence could be found for the set of patches. Available beginning with Windows Installer version 3.0.
623 /// </summary>
624 ERROR_PATCH_NO_SEQUENCE = 1648,
625
626 /// <summary>
627 /// ERROR_PATCH_REMOVAL_DISALLOWED 1649
628 /// Patch removal was disallowed by policy. Available beginning with Windows Installer version 3.0. </summary>
629 ERROR_PATCH_REMOVAL_DISALLOWED = 1649,
630
631 /// <summary>
632 /// ERROR_INVALID_PATCH_XML = 1650
633 /// The XML patch data is invalid. Available beginning with Windows Installer version 3.0.
634 /// </summary>
635 ERROR_INVALID_PATCH_XML = 1650,
636
637 /// <summary>
638 /// ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT 1651
639 /// Administrative user failed to apply patch for a per-user managed or a per-machine application that is in advertise state.
640 /// Available beginning with Windows Installer version 3.0. </summary>
641 ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT = 1651,
642
643 /// <summary>
644 /// ERROR_INSTALL_SERVICE_SAFEBOOT 1652
645 /// Windows Installer is not accessible when the computer is in Safe Mode.
646 /// Exit Safe Mode and try again or try using System Restore to return your computer to a previous state.
647 /// Available beginning with Windows Installer version 4.0.
648 /// </summary>
649 ERROR_INSTALL_SERVICE_SAFEBOOT = 1652,
650
651 /// <summary>
652 /// ERROR_ROLLBACK_DISABLED 1653
653 /// Could not perform a multiple-package transaction because rollback has been disabled.
654 /// Multiple-Package Installations cannot run if rollback is disabled. Available beginning with Windows Installer version 4.5.
655 /// </summary>
656 ERROR_ROLLBACK_DISABLED = 1653,
657
658 /// <summary>
659 /// ERROR_SUCCESS_REBOOT_REQUIRED 3010
660 /// A restart is required to complete the install. This message is indicative of a success.
661 /// This does not include installs where the ForceReboot action is run.
662 /// </summary>
663 ERROR_SUCCESS_REBOOT_REQUIRED = 3010
664 }
665
666 /// <summary>
667 /// Modes of operations for MSIExec; install, administrator install, uninstall .. etc
668 /// </summary>
669 public enum MSIExecMode
670 {
671 /// <summary>
672 /// Installs or configures a product
673 /// </summary>
674 Install = 0,
675
676 /// <summary>
677 /// Administrative install - Installs a product on the network
678 /// </summary>
679 AdministrativeInstall,
680
681 /// <summary>
682 /// Uninstalls the product
683 /// </summary>
684 Uninstall,
685
686 /// <summary>
687 /// Repairs a product
688 /// </summary>
689 Repair,
690
691 /// <summary>
692 /// Modifies a product
693 /// </summary>
694 Modify,
695
696 /// <summary>
697 /// Uninstalls the product as part of cleanup
698 /// </summary>
699 Cleanup,
700 }
701
702 /// <summary>
703 /// User interfave levels
704 /// </summary>
705 public enum MSIExecUserInterfaceLevel
706 {
707 /// <summary>
708 /// No UI
709 /// </summary>
710 None = 0,
711
712 /// <summary>
713 /// Basic UI
714 /// </summary>
715 Basic,
716
717 /// <summary>
718 /// Reduced UI
719 /// </summary>
720 Reduced,
721
722 /// <summary>
723 /// Full UI (default)
724 /// </summary>
725 Full
726 }
727
728 /// <summary>
729 /// Logging options
730 /// </summary>
731 [Flags]
732 public enum MSIExecLoggingOptions
733 {
734 Status_Messages = 0x0001,
735 Nonfatal_Warnings = 0x0002,
736 All_Error_Messages = 0x0004,
737 Start_Up_Of_Actions = 0x0008,
738 Action_Specific_Records = 0x0010,
739 User_Requests = 0x0020,
740 Initial_UI_Parameters = 0x0040,
741 OutOfMemory_Or_Fatal_Exit_Information = 0x0080,
742 OutOfDiskSpace_Messages = 0x0100,
743 Terminal_Properties = 0x0200,
744 Verbose_Output = 0x0400,
745 Append_To_Existing_Log_File = 0x0800,
746
747 Flush_Each_line = 0x1000,
748 Extra_Debugging_Information = 0x2000,
749 Log_All_Information = 0x4000,
750 VOICEWARMUP = 0x0FFF
751 }
752 }
753}
diff --git a/src/test/burn/WixTestTools/MsiUtilities.cs b/src/test/burn/WixTestTools/MsiUtilities.cs
new file mode 100644
index 00000000..4c7d1601
--- /dev/null
+++ b/src/test/burn/WixTestTools/MsiUtilities.cs
@@ -0,0 +1,47 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using WixToolset.Dtf.WindowsInstaller;
7
8 public class MsiUtilities
9 {
10 /// <summary>
11 /// Return true if it finds the given productcode in system otherwise it returns false
12 /// </summary>
13 /// <param name="prodCode"></param>
14 /// <returns></returns>
15 public static bool IsProductInstalled(string prodCode)
16 {
17 //look in all user's products (both per-machine and per-user)
18 foreach (ProductInstallation product in ProductInstallation.GetProducts(null, "s-1-1-0", UserContexts.All))
19 {
20 if (product.ProductCode == prodCode)
21 {
22 return true;
23 }
24 }
25 return false;
26 }
27
28 /// <summary>
29 /// Return true if it finds the given productcode in system with the specified version otherwise it returns false
30 /// </summary>
31 /// <param name="prodCode"></param>
32 /// <param name="prodVersion"></param>
33 /// <returns></returns>
34 public static bool IsProductInstalledWithVersion(string prodCode, Version prodVersion)
35 {
36 //look in all user's products (both per-machine and per-user)
37 foreach (ProductInstallation product in ProductInstallation.GetProducts(null, "s-1-1-0", UserContexts.All))
38 {
39 if (product.ProductCode == prodCode && product.ProductVersion == prodVersion)
40 {
41 return true;
42 }
43 }
44 return false;
45 }
46 }
47}
diff --git a/src/test/burn/WixTestTools/PackageInstaller.cs b/src/test/burn/WixTestTools/PackageInstaller.cs
new file mode 100644
index 00000000..d32f499b
--- /dev/null
+++ b/src/test/burn/WixTestTools/PackageInstaller.cs
@@ -0,0 +1,104 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Data.WindowsInstaller;
11 using static WixTestTools.MSIExec;
12
13 public partial class PackageInstaller : IDisposable
14 {
15 public PackageInstaller(WixTestContext testContext, string filename)
16 {
17 this.Package = Path.Combine(testContext.TestDataFolder, $"{filename}.msi");
18 this.PackagePdb = Path.Combine(testContext.TestDataFolder, $"{filename}.wixpdb");
19 this.TestContext = testContext;
20
21 using var wixOutput = WixOutput.Read(this.PackagePdb);
22
23 var intermediate = Intermediate.Load(wixOutput);
24 var section = intermediate.Sections.Single();
25 var platformSummary = section.Symbols.OfType<SummaryInformationSymbol>().Single(s => s.PropertyId == SummaryInformationType.PlatformAndLanguage);
26 var platformString = platformSummary.Value.Split(new char[] { ';' }, 2)[0];
27 this.IsX64 = platformString != "Intel";
28
29 this.WiData = WindowsInstallerData.Load(wixOutput);
30 }
31
32 public string Package { get; }
33
34 private WixTestContext TestContext { get; }
35
36 public string TestGroupName => this.TestContext.TestGroupName;
37
38 public string TestName => this.TestContext.TestName;
39
40 /// <summary>
41 /// Installs a .msi file
42 /// </summary>
43 /// <param name="expectedExitCode">Expected exit code</param>
44 /// <param name="otherArguments">Other arguments to pass to MSIExec.</param>
45 /// <returns>MSIExec log File</returns>
46 public string InstallProduct(MSIExecReturnCode expectedExitCode = MSIExecReturnCode.SUCCESS, params string[] otherArguments)
47 {
48 return this.RunMSIExec(MSIExecMode.Install, otherArguments, expectedExitCode);
49 }
50
51 /// <summary>
52 /// Uninstalls a .msi file
53 /// </summary>
54 /// <param name="expectedExitCode">Expected exit code</param>
55 /// <param name="otherArguments">Other arguments to pass to MSIExec.</param>
56 /// <returns>MSIExec log File</returns>
57 public string UninstallProduct(MSIExecReturnCode expectedExitCode = MSIExecReturnCode.SUCCESS, params string[] otherArguments)
58 {
59 return this.RunMSIExec(MSIExecMode.Uninstall, otherArguments, expectedExitCode);
60 }
61
62 /// <summary>
63 /// Repairs a .msi file
64 /// </summary>
65 /// <param name="expectedExitCode">Expected exit code</param>
66 /// <param name="otherArguments">Other arguments to pass to msiexe.exe.</param>
67 /// <returns>MSIExec log File</returns>
68 public string RepairProduct(MSIExecReturnCode expectedExitCode = MSIExecReturnCode.SUCCESS, params string[] otherArguments)
69 {
70 return this.RunMSIExec(MSIExecMode.Repair, otherArguments, expectedExitCode);
71 }
72
73 /// <summary>
74 /// Executes MSIExec on a .msi file
75 /// </summary>
76 /// <param name="mode">Mode of execution for MSIExec</param>
77 /// <param name="otherArguments">Other arguments to pass to MSIExec.</param>
78 /// <param name="expectedExitCode">Expected exit code</param>
79 /// <returns>MSIExec exit code</returns>
80 private string RunMSIExec(MSIExecMode mode, string[] otherArguments, MSIExecReturnCode expectedExitCode, bool assertOnError = true)
81 {
82 // Generate the log file name.
83 var logFile = Path.Combine(Path.GetTempPath(), String.Format("{0}_{1}_{2:yyyyMMddhhmmss}_{4}_{3}.log", this.TestGroupName, this.TestName, DateTime.UtcNow, Path.GetFileNameWithoutExtension(this.Package), mode));
84
85 var msiexec = new MSIExec
86 {
87 Product = this.Package,
88 ExecutionMode = mode,
89 OtherArguments = null != otherArguments ? String.Join(" ", otherArguments) : null,
90 ExpectedExitCode = expectedExitCode,
91 LogFile = logFile,
92 };
93
94 msiexec.Run(assertOnError);
95 return msiexec.LogFile;
96 }
97
98 public void Dispose()
99 {
100 string[] args = { "IGNOREDEPENDENCIES=ALL", "WIXFAILWHENDEFERRED=0" };
101 this.RunMSIExec(MSIExecMode.Cleanup, args, MSIExecReturnCode.SUCCESS, assertOnError: false);
102 }
103 }
104}
diff --git a/src/test/burn/WixTestTools/PackageVerifier.cs b/src/test/burn/WixTestTools/PackageVerifier.cs
new file mode 100644
index 00000000..2f42dd21
--- /dev/null
+++ b/src/test/burn/WixTestTools/PackageVerifier.cs
@@ -0,0 +1,81 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Linq;
8 using WixToolset.Data.WindowsInstaller;
9 using WixToolset.Data.WindowsInstaller.Rows;
10 using Xunit;
11
12 public partial class PackageInstaller
13 {
14 public string PackagePdb { get; }
15
16 private bool IsX64 { get; }
17
18 private WindowsInstallerData WiData { get; }
19
20 public string GetInstalledFilePath(string filename)
21 {
22 return this.TestContext.GetTestInstallFolder(this.IsX64, Path.Combine(this.GetInstallFolderName(), filename));
23 }
24
25 public string GetInstallFolderName()
26 {
27 var row = this.WiData.Tables["Directory"].Rows.Single(r => r.FieldAsString(0) == "INSTALLFOLDER");
28 var value = row.FieldAsString(2);
29 var longNameIndex = value.IndexOf('|') + 1;
30 if (longNameIndex > 0)
31 {
32 return value.Substring(longNameIndex);
33 }
34 return value;
35 }
36
37 public string GetProperty(string name)
38 {
39 var row = this.WiData.Tables["Property"].Rows.Cast<PropertyRow>().Single(r => r.Property == name);
40 return row.Value;
41 }
42
43 public void VerifyInstalled(bool installed)
44 {
45 var productCode = this.GetProperty("ProductCode");
46 Assert.Equal(installed, MsiUtilities.IsProductInstalled(productCode));
47 }
48
49 public void VerifyInstalledWithVersion(bool installed)
50 {
51 var productCode = this.GetProperty("ProductCode");
52 Version prodVersion = new Version(this.GetProperty("ProductVersion"));
53 Assert.Equal(installed, MsiUtilities.IsProductInstalledWithVersion(productCode, prodVersion));
54 }
55
56 public void DeleteTestRegistryValue(string name)
57 {
58 using (var root = this.TestContext.GetTestRegistryRoot(this.IsX64))
59 {
60 Assert.NotNull(root);
61 root.DeleteValue(name);
62 }
63 }
64
65 public void VerifyTestRegistryRootDeleted()
66 {
67 using var testRegistryRoot = this.TestContext.GetTestRegistryRoot(this.IsX64);
68 Assert.Null(testRegistryRoot);
69 }
70
71 public void VerifyTestRegistryValue(string name, string expectedValue)
72 {
73 using (var root = this.TestContext.GetTestRegistryRoot(this.IsX64))
74 {
75 Assert.NotNull(root);
76 var actualValue = root.GetValue(name) as string;
77 Assert.Equal(expectedValue, actualValue);
78 }
79 }
80 }
81}
diff --git a/src/test/burn/WixTestTools/TestTool.cs b/src/test/burn/WixTestTools/TestTool.cs
new file mode 100644
index 00000000..be5fde42
--- /dev/null
+++ b/src/test/burn/WixTestTools/TestTool.cs
@@ -0,0 +1,245 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8 using System.Text.RegularExpressions;
9 using WixBuildTools.TestSupport;
10 using Xunit;
11
12 public class TestTool : ExternalExecutable
13 {
14 /// <summary>
15 /// Constructor for a TestTool
16 /// </summary>
17 public TestTool()
18 : this(null)
19 {
20 }
21
22 /// <summary>
23 /// Constructor for a TestTool
24 /// </summary>
25 /// <param name="toolFile">The full path to the tool. Eg. c:\bin\candle.exe</param>
26 public TestTool(string toolFile)
27 : base(toolFile)
28 {
29 this.PrintOutputToConsole = true;
30 }
31
32 /// <summary>
33 /// The arguments to pass to the tool
34 /// </summary>
35 public virtual string Arguments { get; set; }
36
37 /// <summary>
38 /// Stores the errors that occurred when a run was checked against its expected results
39 /// </summary>
40 public List<string> Errors { get; set; }
41
42 /// <summary>
43 /// A list of Regex's that are expected to match stderr
44 /// </summary>
45 public List<Regex> ExpectedErrorRegexs { get; set; } = new List<Regex>();
46
47 /// <summary>
48 /// The expected error strings to stderr
49 /// </summary>
50 public List<string> ExpectedErrorStrings { get; set; } = new List<string>();
51
52 /// <summary>
53 /// The expected exit code of the tool
54 /// </summary>
55 public int? ExpectedExitCode { get; set; }
56
57 /// <summary>
58 /// A list of Regex's that are expected to match stdout
59 /// </summary>
60 public List<Regex> ExpectedOutputRegexs { get; set; } = new List<Regex>();
61
62 /// <summary>
63 /// The expected output strings to stdout
64 /// </summary>
65 public List<string> ExpectedOutputStrings { get; set; } = new List<string>();
66
67 /// <summary>
68 /// Print output from the tool execution to the console
69 /// </summary>
70 public bool PrintOutputToConsole { get; set; }
71
72 /// <summary>
73 /// The working directory of the tool
74 /// </summary>
75 public string WorkingDirectory { get; set; }
76
77 /// <summary>
78 /// Print the errors from the last run
79 /// </summary>
80 public void PrintErrors()
81 {
82 if (null != this.Errors)
83 {
84 Console.WriteLine("Errors:");
85
86 foreach (string error in this.Errors)
87 {
88 Console.WriteLine(error);
89 }
90 }
91 }
92
93 /// <summary>
94 /// Run the tool
95 /// </summary>
96 /// <returns>The results of the run</returns>
97 public ExternalExecutableResult Run()
98 {
99 return this.Run(true);
100 }
101
102 /// <summary>
103 /// Run the tool
104 /// </summary>
105 /// <param name="exceptionOnError">Throw an exception if the expected results don't match the actual results</param>
106 /// <exception cref="System.Exception">Thrown when the expected results don't match the actual results</exception>
107 /// <returns>The results of the run</returns>
108 public virtual ExternalExecutableResult Run(bool assertOnError)
109 {
110 var result = this.Run(this.Arguments, workingDirectory: this.WorkingDirectory ?? String.Empty);
111
112 if (this.PrintOutputToConsole)
113 {
114 Console.WriteLine(FormatResult(result));
115 }
116
117 this.Errors = this.CheckResult(result);
118
119 if (assertOnError && 0 < this.Errors.Count)
120 {
121 if (this.PrintOutputToConsole)
122 {
123 this.PrintErrors();
124 }
125
126 Assert.Empty(this.Errors);
127 }
128
129 return result;
130 }
131
132 /// <summary>
133 /// Checks that the result from a run matches the expected results
134 /// </summary>
135 /// <param name="result">A result from a run</param>
136 /// <returns>A list of errors</returns>
137 public virtual List<string> CheckResult(ExternalExecutableResult result)
138 {
139 List<string> errors = new List<string>();
140
141 // Verify that the expected return code matched the actual return code
142 if (null != this.ExpectedExitCode && this.ExpectedExitCode != result.ExitCode)
143 {
144 errors.Add(String.Format("Expected exit code {0} did not match actual exit code {1}", this.ExpectedExitCode, result.ExitCode));
145 }
146
147 var standardErrorString = string.Join(Environment.NewLine, result.StandardError);
148
149 // Verify that the expected error string are in stderr
150 if (null != this.ExpectedErrorStrings)
151 {
152 foreach (string expectedString in this.ExpectedErrorStrings)
153 {
154 if (!standardErrorString.Contains(expectedString))
155 {
156 errors.Add(String.Format("The text '{0}' was not found in stderr", expectedString));
157 }
158 }
159 }
160
161 var standardOutputString = string.Join(Environment.NewLine, result.StandardOutput);
162
163 // Verify that the expected output string are in stdout
164 if (null != this.ExpectedOutputStrings)
165 {
166 foreach (string expectedString in this.ExpectedOutputStrings)
167 {
168 if (!standardOutputString.Contains(expectedString))
169 {
170 errors.Add(String.Format("The text '{0}' was not found in stdout", expectedString));
171 }
172 }
173 }
174
175 // Verify that the expected regular expressions match stderr
176 if (null != this.ExpectedOutputRegexs)
177 {
178 foreach (Regex expectedRegex in this.ExpectedOutputRegexs)
179 {
180 if (!expectedRegex.IsMatch(standardOutputString))
181 {
182 errors.Add(String.Format("Regex {0} did not match stdout", expectedRegex.ToString()));
183 }
184 }
185 }
186
187 // Verify that the expected regular expressions match stdout
188 if (null != this.ExpectedErrorRegexs)
189 {
190 foreach (Regex expectedRegex in this.ExpectedErrorRegexs)
191 {
192 if (!expectedRegex.IsMatch(standardErrorString))
193 {
194 errors.Add(String.Format("Regex {0} did not match stderr", expectedRegex.ToString()));
195 }
196 }
197 }
198
199 return errors;
200 }
201
202 /// <summary>
203 /// Clears all of the expected results and resets them to the default values
204 /// </summary>
205 public virtual void SetDefaultExpectedResults()
206 {
207 this.ExpectedErrorRegexs = new List<Regex>();
208 this.ExpectedErrorStrings = new List<string>();
209 this.ExpectedExitCode = null;
210 this.ExpectedOutputRegexs = new List<Regex>();
211 this.ExpectedOutputStrings = new List<string>();
212 }
213
214 /// <summary>
215 /// Returns a string with data contained in the result.
216 /// </summary>
217 /// <returns>A string</returns>
218 private static string FormatResult(ExternalExecutableResult result)
219 {
220 var returnValue = new StringBuilder();
221 returnValue.AppendLine();
222 returnValue.AppendLine("----------------");
223 returnValue.AppendLine("Tool run result:");
224 returnValue.AppendLine("----------------");
225 returnValue.AppendLine("Command:");
226 returnValue.AppendLine($"\"{result.StartInfo.FileName}\" {result.StartInfo.Arguments}");
227 returnValue.AppendLine();
228 returnValue.AppendLine("Standard Output:");
229 foreach (var line in result.StandardOutput ?? new string[0])
230 {
231 returnValue.AppendLine(line);
232 }
233 returnValue.AppendLine("Standard Error:");
234 foreach (var line in result.StandardError ?? new string[0])
235 {
236 returnValue.AppendLine(line);
237 }
238 returnValue.AppendLine("Exit Code:");
239 returnValue.AppendLine(Convert.ToString(result.ExitCode));
240 returnValue.AppendLine("----------------");
241
242 return returnValue.ToString();
243 }
244 }
245}
diff --git a/src/test/burn/WixTestTools/WixTestBase.cs b/src/test/burn/WixTestTools/WixTestBase.cs
new file mode 100644
index 00000000..bc050135
--- /dev/null
+++ b/src/test/burn/WixTestTools/WixTestBase.cs
@@ -0,0 +1,19 @@
1// 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.
2
3namespace WixTestTools
4{
5 using Xunit.Abstractions;
6
7 public abstract class WixTestBase
8 {
9 protected WixTestBase(ITestOutputHelper testOutputHelper)
10 {
11 this.TestContext = new WixTestContext(testOutputHelper);
12 }
13
14 /// <summary>
15 /// The test context for the current test.
16 /// </summary>
17 public WixTestContext TestContext { get; }
18 }
19}
diff --git a/src/test/burn/WixTestTools/WixTestContext.cs b/src/test/burn/WixTestTools/WixTestContext.cs
new file mode 100644
index 00000000..a4e666f1
--- /dev/null
+++ b/src/test/burn/WixTestTools/WixTestContext.cs
@@ -0,0 +1,75 @@
1// 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.
2
3namespace WixTestTools
4{
5 using System;
6 using System.IO;
7 using System.Linq;
8 using System.Reflection;
9 using Microsoft.Win32;
10 using WixBuildTools.TestSupport;
11 using Xunit.Abstractions;
12
13 public class WixTestContext
14 {
15 static readonly string RootDataPath = Path.GetFullPath(TestData.Get("TestData"));
16
17 public WixTestContext(ITestOutputHelper testOutputHelper)
18 {
19 var test = GetTest(testOutputHelper);
20 var splitClassName = test.TestCase.TestMethod.TestClass.Class.Name.Split('.');
21
22 this.TestGroupName = splitClassName.Last();
23 this.TestName = test.TestCase.TestMethod.Method.Name;
24
25 this.TestDataFolder = Path.Combine(RootDataPath, this.TestGroupName);
26 }
27
28 public string TestDataFolder { get; }
29
30 /// <summary>
31 /// Gets the name of the current test group.
32 /// </summary>
33 public string TestGroupName { get; }
34
35 public string TestName { get; }
36
37 /// <summary>
38 /// Gets the test install directory for the current test.
39 /// </summary>
40 /// <param name="additionalPath">Additional subdirectories under the test install directory.</param>
41 /// <returns>Full path to the test install directory.</returns>
42 /// <remarks>
43 /// The package or bundle must install into [ProgramFilesFolder]\~Test WiX\[TestGroupName]\([Additional]).
44 /// </remarks>
45 public string GetTestInstallFolder(bool x64, string additionalPath = null)
46 {
47 var baseDirectory = x64 ? Environment.SpecialFolder.ProgramFiles : Environment.SpecialFolder.ProgramFilesX86;
48 return Path.Combine(Environment.GetFolderPath(baseDirectory), "~Test WiX", this.TestGroupName, additionalPath ?? String.Empty);
49 }
50
51 /// <summary>
52 /// Gets the test registry key for the current test.
53 /// </summary>
54 /// <param name="additionalPath">Additional subkeys under the test registry key.</param>
55 /// <returns>Full path to the test registry key.</returns>
56 /// <remarks>
57 /// The package must write into HKLM\Software\WiX\Tests\[TestGroupName]\([Additional]).
58 /// </remarks>
59 public RegistryKey GetTestRegistryRoot(bool x64, string additionalPath = null)
60 {
61 var baseKey = x64 ? "Software" : @"Software\WOW6432Node";
62 var key = String.Format(@"{0}\WiX\Tests\{1}\{2}", baseKey, this.TestGroupName, additionalPath ?? String.Empty);
63 return Registry.LocalMachine.OpenSubKey(key, true);
64 }
65
66 private static ITest GetTest(ITestOutputHelper output)
67 {
68 // https://github.com/xunit/xunit/issues/416#issuecomment-378512739
69 var type = output.GetType();
70 var testMember = type.GetField("test", BindingFlags.Instance | BindingFlags.NonPublic);
71 var test = (ITest)testMember.GetValue(output);
72 return test;
73 }
74 }
75}
diff --git a/src/test/burn/WixTestTools/WixTestTools.csproj b/src/test/burn/WixTestTools/WixTestTools.csproj
new file mode 100644
index 00000000..58f02be7
--- /dev/null
+++ b/src/test/burn/WixTestTools/WixTestTools.csproj
@@ -0,0 +1,21 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netcoreapp3.1</TargetFramework>
7 <PlatformTarget>x64</PlatformTarget>
8 </PropertyGroup>
9
10 <ItemGroup>
11 <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
12 <PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
13 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.50" />
14 <PackageReference Include="WixToolset.Data" Version="4.0.218" />
15 <PackageReference Include="WixToolset.Mba.Core" Version="4.0.58" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <PackageReference Include="xunit" Version="2.4.1" />
20 </ItemGroup>
21</Project>
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/BasicFunctionalityTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/BasicFunctionalityTests.cs
new file mode 100644
index 00000000..5df86fff
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/BasicFunctionalityTests.cs
@@ -0,0 +1,176 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using Xunit;
8 using Xunit.Abstractions;
9
10 public class BasicFunctionalityTests : BurnE2ETests
11 {
12 public BasicFunctionalityTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
13
14 [Fact]
15 public void CanInstallAndUninstallSimpleBundle_x86_wixstdba()
16 {
17 var packageA = this.CreatePackageInstaller("PackageA");
18
19 var bundleA = this.CreateBundleInstaller("BundleA");
20
21 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
22
23 // Source file should *not* be installed
24 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
25
26 bundleA.Install();
27
28 var cachedBundlePath = bundleA.VerifyRegisteredAndInPackageCache();
29
30 // Source file should be installed
31 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
32
33 bundleA.Uninstall(cachedBundlePath);
34
35 // Source file should *not* be installed
36 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
37
38 bundleA.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
39 }
40
41 [Fact]
42 public void CanInstallAndUninstallSimpleBundle_x86_testba()
43 {
44 var packageA = this.CreatePackageInstaller("PackageA");
45
46 var bundleB = this.CreateBundleInstaller("BundleB");
47
48 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
49
50 // Source file should *not* be installed
51 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
52
53 bundleB.Install();
54
55 var cachedBundlePath = bundleB.VerifyRegisteredAndInPackageCache();
56
57 // Source file should be installed
58 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
59
60 bundleB.Uninstall(cachedBundlePath);
61
62 // Source file should *not* be installed
63 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
64
65 bundleB.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
66 }
67
68 [Fact]
69 public void CanInstallAndUninstallSimpleBundle_x86_dnctestba()
70 {
71 var packageA = this.CreatePackageInstaller("PackageA");
72
73 var bundleC = this.CreateBundleInstaller("BundleC");
74
75 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
76
77 // Source file should *not* be installed
78 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
79
80 bundleC.Install();
81
82 var cachedBundlePath = bundleC.VerifyRegisteredAndInPackageCache();
83
84 // Source file should be installed
85 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
86
87 bundleC.Uninstall(cachedBundlePath);
88
89 // Source file should *not* be installed
90 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
91
92 bundleC.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
93 }
94
95 [Fact]
96 public void CanInstallAndUninstallSimpleBundle_x64_wixstdba()
97 {
98 var packageA_x64 = this.CreatePackageInstaller("PackageA_x64");
99
100 var bundleA_x64 = this.CreateBundleInstaller("BundleA_x64");
101
102 var packageASourceCodeInstalled = packageA_x64.GetInstalledFilePath("Package.wxs");
103
104 // Source file should *not* be installed
105 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A x64 payload should not be there on test start: {packageASourceCodeInstalled}");
106
107 bundleA_x64.Install();
108
109 var cachedBundlePath = bundleA_x64.VerifyRegisteredAndInPackageCache();
110
111 // Source file should be installed
112 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A x64 payload installed at: ", packageASourceCodeInstalled));
113
114 bundleA_x64.Uninstall(cachedBundlePath);
115
116 // Source file should *not* be installed
117 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A x64 payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
118
119 bundleA_x64.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
120 }
121
122 [Fact]
123 public void CanInstallAndUninstallSimpleBundle_x64_testba()
124 {
125 var packageA_x64 = this.CreatePackageInstaller("PackageA_x64");
126
127 var bundleB_x64 = this.CreateBundleInstaller("BundleB_x64");
128
129 var packageASourceCodeInstalled = packageA_x64.GetInstalledFilePath("Package.wxs");
130
131 // Source file should *not* be installed
132 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A x64 payload should not be there on test start: {packageASourceCodeInstalled}");
133
134 bundleB_x64.Install();
135
136 var cachedBundlePath = bundleB_x64.VerifyRegisteredAndInPackageCache();
137
138 // Source file should be installed
139 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A x64 payload installed at: ", packageASourceCodeInstalled));
140
141 bundleB_x64.Uninstall(cachedBundlePath);
142
143 // Source file should *not* be installed
144 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A x64 payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
145
146 bundleB_x64.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
147 }
148
149 [Fact]
150 public void CanInstallAndUninstallSimpleBundle_x64_dnctestba()
151 {
152 var packageA_x64 = this.CreatePackageInstaller("PackageA_x64");
153
154 var bundleC_x64 = this.CreateBundleInstaller("BundleC_x64");
155
156 var packageASourceCodeInstalled = packageA_x64.GetInstalledFilePath("Package.wxs");
157
158 // Source file should *not* be installed
159 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A x64 payload should not be there on test start: {packageASourceCodeInstalled}");
160
161 bundleC_x64.Install();
162
163 var cachedBundlePath = bundleC_x64.VerifyRegisteredAndInPackageCache();
164
165 // Source file should be installed
166 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A x64 payload installed at: ", packageASourceCodeInstalled));
167
168 bundleC_x64.Uninstall(cachedBundlePath);
169
170 // Source file should *not* be installed
171 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A x64 payload should have been removed by uninstall from: ", packageASourceCodeInstalled));
172
173 bundleC_x64.VerifyUnregisteredAndRemovedFromPackageCache(cachedBundlePath);
174 }
175 }
176}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/BurnE2EFixture.cs b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2EFixture.cs
new file mode 100644
index 00000000..babfcbc3
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2EFixture.cs
@@ -0,0 +1,28 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Security.Principal;
7
8 public class BurnE2EFixture
9 {
10 const string RequiredEnvironmentVariableName = "RuntimeTestsEnabled";
11
12 public BurnE2EFixture()
13 {
14 using var identity = WindowsIdentity.GetCurrent();
15 var principal = new WindowsPrincipal(identity);
16 if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
17 {
18 throw new InvalidOperationException("These tests must run elevated.");
19 }
20
21 var testsEnabledString = Environment.GetEnvironmentVariable(RequiredEnvironmentVariableName);
22 if (!bool.TryParse(testsEnabledString, out var testsEnabled) || !testsEnabled)
23 {
24 throw new InvalidOperationException($"These tests affect machine state. Set the {RequiredEnvironmentVariableName} environment variable to true to accept the consequences.");
25 }
26 }
27 }
28}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs
new file mode 100644
index 00000000..392b675d
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs
@@ -0,0 +1,63 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7 using WixTestTools;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 [Collection("BurnE2E")]
12 public abstract class BurnE2ETests : WixTestBase, IDisposable
13 {
14 protected BurnE2ETests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
15
16 private Stack<IDisposable> Installers { get; } = new Stack<IDisposable>();
17
18 protected BundleInstaller CreateBundleInstaller(string name)
19 {
20 var installer = new BundleInstaller(this.TestContext, name);
21 this.Installers.Push(installer);
22 return installer;
23 }
24
25 protected PackageInstaller CreatePackageInstaller(string filename)
26 {
27 var installer = new PackageInstaller(this.TestContext, filename);
28 this.Installers.Push(installer);
29 return installer;
30 }
31
32 protected TestBAController CreateTestBAController()
33 {
34 var controller = new TestBAController(this.TestContext);
35 this.Installers.Push(controller);
36 return controller;
37 }
38
39 protected IWebServer CreateWebServer()
40 {
41 var webServer = new CoreOwinWebServer();
42 this.Installers.Push(webServer);
43 return webServer;
44 }
45
46 public void Dispose()
47 {
48 while (this.Installers.TryPop(out var installer))
49 {
50 try
51 {
52 installer.Dispose();
53 }
54 catch { }
55 }
56 }
57 }
58
59 [CollectionDefinition("BurnE2E", DisableParallelization = true)]
60 public class BurnE2ECollectionDefinition : ICollectionFixture<BurnE2EFixture>
61 {
62 }
63}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/CacheTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/CacheTests.cs
new file mode 100644
index 00000000..e8d37aef
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/CacheTests.cs
@@ -0,0 +1,133 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System.Collections.Generic;
6 using System.IO;
7 using WixBuildTools.TestSupport;
8 using WixTestTools;
9 using WixToolset.Mba.Core;
10 using Xunit;
11 using Xunit.Abstractions;
12
13 public class CacheTests : BurnE2ETests
14 {
15 public CacheTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
16
17 [Fact]
18 public void CanCache5GBFile()
19 {
20 var packageA = this.CreatePackageInstaller("PackageA");
21 var bundleC = this.CreateBundleInstaller("BundleC");
22
23 packageA.VerifyInstalled(false);
24
25 // Recreate the 5GB payload to avoid having to copy it to the VM to run the tests.
26 var targetFilePath = Path.Combine(this.TestContext.TestDataFolder, "fivegb.file");
27 if (!File.Exists(targetFilePath))
28 {
29 var testTool = new TestTool(Path.Combine(TestData.Get(), "win-x86", "TestExe.exe"))
30 {
31 Arguments = "/lf \"" + targetFilePath + "|5368709120\"",
32 ExpectedExitCode = 0,
33 };
34 testTool.Run(true);
35 }
36
37 bundleC.Install();
38 bundleC.VerifyRegisteredAndInPackageCache();
39
40 packageA.VerifyInstalled(true);
41 }
42
43 [Fact]
44 public void CanDownloadPayloadsFromMissingAttachedContainer()
45 {
46 var packageA = this.CreatePackageInstaller("PackageA");
47 var packageB = this.CreatePackageInstaller("PackageB");
48 var bundleA = this.CreateBundleInstaller("BundleA");
49 var testBAController = this.CreateTestBAController();
50 var webServer = this.CreateWebServer();
51
52 webServer.AddFiles(new Dictionary<string, string>
53 {
54 { "/BundleA/PackageA.msi", Path.Combine(this.TestContext.TestDataFolder, "PackageA.msi") },
55 { "/BundleA/PackageB.msi", Path.Combine(this.TestContext.TestDataFolder, "PackageB.msi") },
56 });
57 webServer.Start();
58
59 // Don't install PackageB initially so it will be installed when run from the package cache.
60 testBAController.SetPackageRequestedState("PackageB", RequestState.Absent);
61
62 packageA.VerifyInstalled(false);
63 packageB.VerifyInstalled(false);
64
65 // Manually copy bundle to separate directory, install from there, and then delete it
66 // so that when run from the package cache, it can't find the attached container.
67 using (var dfs = new DisposableFileSystem())
68 {
69 var tempDirectory = dfs.GetFolder(true);
70
71 var bundleAFileInfo = new FileInfo(bundleA.Bundle);
72 var bundleACopiedPath = Path.Combine(tempDirectory, bundleAFileInfo.Name);
73 bundleAFileInfo.CopyTo(bundleACopiedPath);
74
75 bundleA.Install(bundleACopiedPath);
76 }
77
78 var bundlePackageCachePath = bundleA.VerifyRegisteredAndInPackageCache();
79
80 packageA.VerifyInstalled(true);
81 packageB.VerifyInstalled(false);
82
83 testBAController.SetPackageRequestedState("PackageB", RequestState.Present);
84
85 bundleA.Modify(bundlePackageCachePath);
86 bundleA.VerifyRegisteredAndInPackageCache();
87
88 packageA.VerifyInstalled(true);
89 packageB.VerifyInstalled(true);
90 }
91
92 [Fact]
93 public void CanFindAttachedContainerFromRenamedBundle()
94 {
95 var packageA = this.CreatePackageInstaller("PackageA");
96 var packageB = this.CreatePackageInstaller("PackageB");
97 var bundleB = this.CreateBundleInstaller("BundleB");
98 var testBAController = this.CreateTestBAController();
99
100 // Don't install PackageB initially so it will be installed when run from the package cache.
101 testBAController.SetPackageRequestedState("PackageB", RequestState.Absent);
102
103 packageA.VerifyInstalled(false);
104 packageB.VerifyInstalled(false);
105
106 // Manually copy bundle to separate directory with new name and install from there
107 // so that when run from the package cache, it has to get the attached container from the renamed bundle.
108 using (var dfs = new DisposableFileSystem())
109 {
110 var tempDirectory = dfs.GetFolder(true);
111
112 var bundleBFileInfo = new FileInfo(bundleB.Bundle);
113 var bundleBCopiedPath = Path.Combine(tempDirectory, "RenamedBundle.exe");
114 bundleBFileInfo.CopyTo(bundleBCopiedPath);
115
116 bundleB.Install(bundleBCopiedPath);
117
118 var bundlePackageCachePath = bundleB.VerifyRegisteredAndInPackageCache();
119
120 packageA.VerifyInstalled(true);
121 packageB.VerifyInstalled(false);
122
123 testBAController.SetPackageRequestedState("PackageB", RequestState.Present);
124
125 bundleB.Modify(bundlePackageCachePath);
126 bundleB.VerifyRegisteredAndInPackageCache();
127
128 packageA.VerifyInstalled(true);
129 packageB.VerifyInstalled(true);
130 }
131 }
132 }
133}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
new file mode 100644
index 00000000..d563bbe7
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
@@ -0,0 +1,611 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using WixTestTools;
7 using WixToolset.Mba.Core;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class DependencyTests : BurnE2ETests
12 {
13 public DependencyTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 [Fact]
16 public void CanKeepSameExactPackageAfterUpgradingBundle()
17 {
18 var packageF = this.CreatePackageInstaller("PackageF");
19 var bundleKv1 = this.CreateBundleInstaller("BundleKv1");
20 var bundleKv2 = this.CreateBundleInstaller("BundleKv2");
21
22 packageF.VerifyInstalled(false);
23
24 bundleKv1.Install();
25 bundleKv1.VerifyRegisteredAndInPackageCache();
26
27 packageF.VerifyInstalled(true);
28
29 bundleKv2.Install();
30 bundleKv2.VerifyRegisteredAndInPackageCache();
31 bundleKv1.VerifyUnregisteredAndRemovedFromPackageCache();
32
33 packageF.VerifyInstalled(true);
34
35 bundleKv2.VerifyPackageIsCached("PackageF");
36
37 bundleKv2.Uninstall();
38 bundleKv2.VerifyUnregisteredAndRemovedFromPackageCache();
39
40 packageF.VerifyInstalled(false);
41 }
42
43 [Fact (Skip = "https://github.com/wixtoolset/issues/issues/6387")]
44 public void CanKeepSameExactPackageAfterUpgradingBundleWithSlipstreamedPatch()
45 {
46 var originalVersion = "1.0.0.0";
47 var patchedVersion = "1.0.1.0";
48 var testRegistryValue = "PackageA";
49 var testRegistryValueExe = "ExeA";
50
51 var packageA = this.CreatePackageInstaller("PackageAv1");
52 var bundleA = this.CreateBundleInstaller("BundleAv1");
53 var bundleC = this.CreateBundleInstaller("BundleC");
54
55 packageA.VerifyInstalled(false);
56
57 bundleA.Install();
58 bundleA.VerifyRegisteredAndInPackageCache();
59
60 packageA.VerifyInstalled(true);
61 packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion);
62 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, originalVersion);
63
64 // Verify https://github.com/wixtoolset/issues/issues/3294 - Uninstalling bundle registers a dependency on a package
65 bundleC.Install();
66 bundleC.VerifyRegisteredAndInPackageCache();
67 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
68
69 packageA.VerifyInstalled(true);
70 packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
71 bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
72
73 // Verify https://github.com/wixtoolset/issues/issues/2915 - Update bundle removes previously cached MSIs
74 bundleC.Repair();
75
76 bundleC.Uninstall();
77 bundleC.VerifyUnregisteredAndRemovedFromPackageCache();
78
79 packageA.VerifyInstalled(false);
80 }
81
82 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/exea")]
83 public void CanKeepUpgradedPackageAfterUninstallUpgradedBundle()
84 {
85 var testRegistryValueExe = "ExeA";
86
87 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
88 var packageAv101 = this.CreatePackageInstaller("PackageAv1_0_1");
89 var packageB = this.CreatePackageInstaller("PackageB");
90 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
91 var bundleAv101 = this.CreateBundleInstaller("BundleAv1_0_1");
92 var bundleB = this.CreateBundleInstaller("BundleB");
93
94 packageAv1.VerifyInstalledWithVersion(false);
95 packageAv101.VerifyInstalledWithVersion(false);
96 packageB.VerifyInstalled(false);
97
98 bundleAv1.Install();
99 bundleAv1.VerifyRegisteredAndInPackageCache();
100
101 packageAv1.VerifyInstalledWithVersion(true);
102 bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
103
104 bundleB.Install();
105 bundleB.VerifyRegisteredAndInPackageCache();
106
107 packageAv1.VerifyInstalledWithVersion(true);
108 bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
109 packageB.VerifyInstalled(true);
110
111 bundleAv101.Install();
112 bundleAv101.VerifyRegisteredAndInPackageCache();
113 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
114
115 packageAv1.VerifyInstalledWithVersion(false);
116 packageAv101.VerifyInstalledWithVersion(true);
117 bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.1.0");
118
119 bundleAv101.Uninstall();
120 bundleAv101.VerifyUnregisteredAndRemovedFromPackageCache();
121
122 packageAv101.VerifyInstalledWithVersion(true);
123 bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.1.0");
124 }
125
126#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES
127 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6387")]
128#else
129 [Fact(Skip = "addon/patch related bundle")]
130#endif
131 public void CanMinorUpgradeDependencyPackageFromPatchBundle()
132 {
133 var originalVersion = "1.0.0.0";
134 var patchedVersion = "1.0.1.0";
135 var testRegistryValue = "PackageA";
136
137 var packageA = this.CreatePackageInstaller("PackageAv1");
138 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
139 var packageBv101 = this.CreatePackageInstaller("PackageBv1_0_1");
140 var bundleJ = this.CreateBundleInstaller("BundleJ");
141 var bundleJ_Patch = this.CreateBundleInstaller("BundleJ_Patch");
142
143 packageA.VerifyInstalled(false);
144 packageBv1.VerifyInstalled(false);
145 packageBv101.VerifyInstalled(false);
146
147 bundleJ.Install();
148 bundleJ.VerifyRegisteredAndInPackageCache();
149
150 packageA.VerifyInstalled(true);
151 packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion);
152 packageBv1.VerifyInstalled(true);
153
154 bundleJ_Patch.Install();
155 bundleJ_Patch.VerifyRegisteredAndInPackageCache();
156
157 packageA.VerifyInstalled(true);
158 packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
159 packageBv1.VerifyInstalled(false);
160 packageBv101.VerifyInstalled(true);
161
162 bundleJ.Uninstall();
163 bundleJ.VerifyUnregisteredAndRemovedFromPackageCache();
164 bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache();
165
166 packageA.VerifyInstalled(false);
167 packageBv1.VerifyInstalled(false);
168 packageBv101.VerifyInstalled(false);
169 }
170
171#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES
172 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6387")]
173#else
174 [Fact(Skip = "addon/patch related bundle")]
175#endif
176 public void CanMinorUpgradeDependencyPackageFromPatchBundleThenUninstallToRestoreBase()
177 {
178 var originalVersion = "1.0.0.0";
179 var patchedVersion = "1.0.1.0";
180 var testRegistryValue = "PackageA";
181
182 var packageA = this.CreatePackageInstaller("PackageAv1");
183 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
184 var packageBv101 = this.CreatePackageInstaller("PackageBv1_0_1");
185 var bundleJ = this.CreateBundleInstaller("BundleJ");
186 var bundleJ_Patch = this.CreateBundleInstaller("BundleJ_Patch");
187
188 packageA.VerifyInstalled(false);
189 packageBv1.VerifyInstalled(false);
190 packageBv101.VerifyInstalled(false);
191
192 bundleJ.Install();
193 bundleJ.VerifyRegisteredAndInPackageCache();
194
195 packageA.VerifyInstalled(true);
196 packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion);
197 packageBv1.VerifyInstalled(true);
198
199 bundleJ_Patch.Install();
200 bundleJ_Patch.VerifyRegisteredAndInPackageCache();
201
202 packageA.VerifyInstalled(true);
203 packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
204 packageBv1.VerifyInstalled(false);
205 packageBv101.VerifyInstalled(true);
206
207 bundleJ_Patch.Uninstall();
208 bundleJ_Patch.VerifyUnregisteredAndRemovedFromPackageCache();
209
210 packageA.VerifyInstalled(true);
211 packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion);
212 packageBv1.VerifyInstalled(true);
213 packageBv101.VerifyInstalled(false);
214
215 bundleJ.Uninstall();
216 bundleJ.VerifyUnregisteredAndRemovedFromPackageCache();
217
218 packageA.VerifyInstalled(false);
219 packageBv1.VerifyInstalled(false);
220 packageBv101.VerifyInstalled(false);
221 }
222
223#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES
224 [Fact]
225#else
226 [Fact(Skip = "addon/patch related bundle")]
227#endif
228 public void CanUninstallBaseWithAddOnsWhenAllSharePackages()
229 {
230 var testRegistryValueExe = "ExeA";
231
232 var packageA = this.CreatePackageInstaller("PackageAv1");
233 var packageB = this.CreatePackageInstaller("PackageB");
234 var bundleF = this.CreateBundleInstaller("BundleF");
235 var bundleF_AddOnA = this.CreateBundleInstaller("BundleF_AddOnA");
236 var bundleF_AddOnB = this.CreateBundleInstaller("BundleF_AddOnB");
237
238 packageA.VerifyInstalled(false);
239 packageB.VerifyInstalled(false);
240
241 bundleF.Install();
242 bundleF.VerifyRegisteredAndInPackageCache();
243
244 packageA.VerifyInstalled(true);
245 packageB.VerifyInstalled(true);
246
247 bundleF_AddOnA.Install();
248 bundleF_AddOnA.VerifyRegisteredAndInPackageCache();
249
250 packageA.VerifyInstalled(true);
251 bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
252 packageB.VerifyInstalled(true);
253
254 bundleF_AddOnB.Install();
255 bundleF_AddOnB.VerifyRegisteredAndInPackageCache();
256
257 packageA.VerifyInstalled(true);
258 bundleF.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
259 packageB.VerifyInstalled(true);
260
261 bundleF.Uninstall();
262 bundleF.VerifyUnregisteredAndRemovedFromPackageCache();
263 bundleF_AddOnA.VerifyUnregisteredAndRemovedFromPackageCache();
264 bundleF_AddOnB.VerifyUnregisteredAndRemovedFromPackageCache();
265
266 packageA.VerifyInstalled(false);
267 bundleF.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
268 packageB.VerifyInstalled(false);
269 }
270
271 [Fact]
272 public void CanUninstallDependencyPackagesWithBundlesUninstalledInFifoOrder()
273 {
274 var testRegistryValueExe = "ExeA";
275
276 var packageA = this.CreatePackageInstaller("PackageAv1");
277 var packageB = this.CreatePackageInstaller("PackageB");
278 var bundleA = this.CreateBundleInstaller("BundleAv1");
279 var bundleB = this.CreateBundleInstaller("BundleB");
280
281 packageA.VerifyInstalled(false);
282 packageB.VerifyInstalled(false);
283
284 bundleA.Install();
285 bundleA.VerifyRegisteredAndInPackageCache();
286
287 packageA.VerifyInstalled(true);
288 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
289
290 bundleB.Install();
291 bundleB.VerifyRegisteredAndInPackageCache();
292
293 packageA.VerifyInstalled(true);
294 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
295 packageB.VerifyInstalled(true);
296
297 bundleA.Uninstall();
298 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
299
300 packageA.VerifyInstalled(true);
301 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
302 packageB.VerifyInstalled(true);
303
304 bundleB.Uninstall();
305 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
306
307 packageA.VerifyInstalled(false);
308 bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
309 packageB.VerifyInstalled(false);
310 }
311
312 [Fact]
313 public void CanUninstallDependencyPackagesWithBundlesUninstalledInReverseOrder()
314 {
315 var packageA = this.CreatePackageInstaller("PackageAv1");
316 var packageB = this.CreatePackageInstaller("PackageB");
317 var bundleA = this.CreateBundleInstaller("BundleAv1");
318 var bundleB = this.CreateBundleInstaller("BundleB");
319
320 packageA.VerifyInstalled(false);
321 packageB.VerifyInstalled(false);
322
323 bundleA.Install();
324 bundleA.VerifyRegisteredAndInPackageCache();
325
326 packageA.VerifyInstalled(true);
327
328 bundleB.Install();
329 bundleB.VerifyRegisteredAndInPackageCache();
330
331 packageA.VerifyInstalled(true);
332 packageB.VerifyInstalled(true);
333
334 bundleB.Uninstall();
335 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
336
337 packageA.VerifyInstalled(true);
338
339 bundleA.Uninstall();
340 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
341
342 packageA.VerifyInstalled(false);
343 packageB.VerifyInstalled(false);
344 }
345
346#if SUPPORT_ADDON_AND_PATCH_RELATED_BUNDLES
347 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6387")]
348#else
349 [Fact(Skip = "addon/patch related bundle")]
350#endif
351 public void CanUpgradePatchBundleWithAdditionalPatch()
352 {
353 var originalVersion = "1.0.0.0";
354 var patchedVersion = "1.0.1.0";
355 var patchedVersion2 = "1.0.2.0";
356 var testRegistryValue = "PackageA";
357
358 var packageA = this.CreatePackageInstaller("PackageAv1");
359 var packageB = this.CreatePackageInstaller("PackageBv1");
360 var bundleF = this.CreateBundleInstaller("BundleJ");
361 var bundleF_PatchAv101 = this.CreateBundleInstaller("BundleF_PatchAv1_0_1");
362 var bundleF_PatchAv102 = this.CreateBundleInstaller("BundleF_PatchAv1_0_2");
363
364 packageA.VerifyInstalled(false);
365 packageB.VerifyInstalled(false);
366
367 bundleF.Install();
368 bundleF.VerifyRegisteredAndInPackageCache();
369
370 packageA.VerifyInstalled(true);
371 packageA.VerifyTestRegistryValue(testRegistryValue, originalVersion);
372 packageB.VerifyInstalled(true);
373
374 bundleF_PatchAv101.Install();
375 bundleF_PatchAv101.VerifyRegisteredAndInPackageCache();
376
377 packageA.VerifyInstalled(true);
378 packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
379 packageB.VerifyInstalled(false);
380
381 bundleF_PatchAv102.Install();
382 bundleF_PatchAv102.VerifyRegisteredAndInPackageCache();
383
384 packageA.VerifyInstalled(true);
385 packageA.VerifyTestRegistryValue(testRegistryValue, patchedVersion2);
386 packageB.VerifyInstalled(false);
387
388 bundleF.Uninstall();
389 bundleF.VerifyUnregisteredAndRemovedFromPackageCache();
390 bundleF_PatchAv101.VerifyUnregisteredAndRemovedFromPackageCache();
391 bundleF_PatchAv102.VerifyUnregisteredAndRemovedFromPackageCache();
392
393 packageA.VerifyInstalled(false);
394 packageB.VerifyInstalled(false);
395 }
396
397 [Fact]
398 public void DoesntRegisterDependencyOnPackageNotSelectedForInstall()
399 {
400 var testRegistryValueExe = "ExeA";
401
402 var packageA = this.CreatePackageInstaller("PackageAv1");
403 var packageB = this.CreatePackageInstaller("PackageB");
404 var bundleA = this.CreateBundleInstaller("BundleAv1");
405 var bundleB = this.CreateBundleInstaller("BundleB");
406 var testBAController = this.CreateTestBAController();
407
408 packageA.VerifyInstalled(false);
409 packageB.VerifyInstalled(false);
410
411 bundleA.Install();
412 bundleA.VerifyRegisteredAndInPackageCache();
413
414 packageA.VerifyInstalled(true);
415 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
416
417 // Verify https://github.com/wixtoolset/issues/issues/3456 - Dependency registered on package though unselected to instal
418 testBAController.SetPackageRequestedState("PackageA", RequestState.None);
419 testBAController.SetPackageRequestedState("PackageB", RequestState.None);
420
421 bundleB.Install();
422 bundleB.VerifyRegisteredAndInPackageCache();
423
424 packageA.VerifyInstalled(true);
425 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
426 packageB.VerifyInstalled(false);
427
428 testBAController.ResetPackageStates("PackageA");
429 testBAController.ResetPackageStates("PackageB");
430
431 bundleA.Uninstall();
432 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
433
434 packageA.VerifyInstalled(false);
435 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
436 packageB.VerifyInstalled(false);
437
438 bundleB.Uninstall();
439 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
440
441 packageA.VerifyInstalled(false);
442 bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
443 packageB.VerifyInstalled(false);
444 }
445
446 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/3516")]
447 public void DoesntRollbackPackageInstallIfPreexistingDependents()
448 {
449 var packageA = this.CreatePackageInstaller("PackageAv1");
450 var packageC = this.CreatePackageInstaller("PackageC");
451 var bundleE = this.CreateBundleInstaller("BundleE");
452 var bundleL = this.CreateBundleInstaller("BundleL");
453 var testBAController = this.CreateTestBAController();
454
455 packageA.VerifyInstalled(false);
456 packageC.VerifyInstalled(false);
457
458 // Make PackageC fail.
459 testBAController.SetPackageCancelExecuteAtProgress("PackageC", 10);
460
461 bundleE.Install();
462 bundleE.VerifyRegisteredAndInPackageCache();
463
464 packageA.VerifyInstalled(true);
465 packageC.VerifyInstalled(false);
466
467 // Make PackageC install then rollback.
468 testBAController.SetPackageCancelExecuteAtProgress("PackageC", null);
469 testBAController.SetPackageCancelOnProgressAtProgress("PackageC", 10);
470
471 bundleL.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
472 bundleL.VerifyUnregisteredAndRemovedFromPackageCache();
473
474 packageA.VerifyInstalled(true);
475 packageC.VerifyInstalled(true);
476
477 testBAController.SetPackageCancelOnProgressAtProgress("PackageC", null);
478
479 bundleE.Uninstall();
480 bundleE.VerifyUnregisteredAndRemovedFromPackageCache();
481
482 packageA.VerifyInstalled(false);
483 packageC.VerifyInstalled(false);
484 }
485
486 [Fact]
487 public void RegistersDependencyOnFailedNonVitalPackages()
488 {
489 var packageA = this.CreatePackageInstaller("PackageAv1");
490 var packageC = this.CreatePackageInstaller("PackageC");
491 var bundleE = this.CreateBundleInstaller("BundleE");
492 var bundleL = this.CreateBundleInstaller("BundleL");
493 var testBAController = this.CreateTestBAController();
494
495 packageA.VerifyInstalled(false);
496 packageC.VerifyInstalled(false);
497
498 // Make PackageC fail.
499 testBAController.SetPackageCancelExecuteAtProgress("PackageC", 10);
500
501 // Verify https://github.com/wixtoolset/issues/issues/3406 - Non-vital failure result in bundle failure (install)
502 bundleE.Install();
503 bundleE.VerifyRegisteredAndInPackageCache();
504
505 packageA.VerifyInstalled(true);
506 packageC.VerifyInstalled(false);
507
508 // Verify https://github.com/wixtoolset/issues/issues/3406 - Non-vital failure result in bundle failure (repair)
509 bundleE.Repair();
510 bundleE.VerifyRegisteredAndInPackageCache();
511
512 packageA.VerifyInstalled(true);
513 packageC.VerifyInstalled(false);
514
515 testBAController.SetPackageCancelExecuteAtProgress("PackageC", null);
516
517 bundleL.Install();
518 bundleL.VerifyRegisteredAndInPackageCache();
519
520 packageA.VerifyInstalled(true);
521 packageC.VerifyInstalled(true);
522
523 // Verify https://github.com/wixtoolset/issues/issues/3516 - Burn registers dependency on failed packages
524 bundleL.Uninstall();
525 bundleL.VerifyUnregisteredAndRemovedFromPackageCache();
526
527 packageA.VerifyInstalled(true);
528 packageC.VerifyInstalled(true);
529
530 bundleE.Uninstall();
531 bundleE.VerifyUnregisteredAndRemovedFromPackageCache();
532
533 packageA.VerifyInstalled(false);
534 packageC.VerifyInstalled(false);
535 }
536
537 [Fact]
538 public void RemovesDependencyDuringUpgradeRollback()
539 {
540 var testRegistryValueExe = "ExeA";
541
542 var packageA = this.CreatePackageInstaller("PackageAv1");
543 var bundleA = this.CreateBundleInstaller("BundleAv1");
544 var bundleD = this.CreateBundleInstaller("BundleD");
545
546 packageA.VerifyInstalled(false);
547 bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
548
549 bundleA.Install();
550 bundleA.VerifyRegisteredAndInPackageCache();
551
552 packageA.VerifyInstalled(true);
553 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
554
555 // Verify https://github.com/wixtoolset/issues/issues/3341 - pkg dependecy not removed in rollback if pkg already present
556 bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE);
557 bundleD.VerifyUnregisteredAndRemovedFromPackageCache();
558
559 packageA.VerifyInstalled(true);
560 bundleA.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0");
561
562 bundleA.Uninstall();
563 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
564
565 packageA.VerifyInstalled(false);
566 bundleA.VerifyExeTestRegistryRootDeleted(testRegistryValueExe);
567 }
568
569 [Fact]
570 public void SkipsCrossScopeDependencyRegistration()
571 {
572 var packageA = this.CreatePackageInstaller("PackageAv1");
573 var packageDv1 = this.CreatePackageInstaller("PackageDv1");
574 var packageDv2 = this.CreatePackageInstaller("PackageDv2");
575 var bundleHv1 = this.CreateBundleInstaller("BundleHv1");
576 var bundleHv2 = this.CreateBundleInstaller("BundleHv2");
577
578 packageA.VerifyInstalled(false);
579 packageDv1.VerifyInstalled(false);
580 packageDv2.VerifyInstalled(false);
581
582 var bundleHv1InstallLogFilePath = bundleHv1.Install();
583 bundleHv1.VerifyRegisteredAndInPackageCache();
584
585 packageA.VerifyInstalled(true);
586 packageDv1.VerifyInstalled(true);
587
588 Assert.True(LogVerifier.MessageInLogFileRegex(bundleHv1InstallLogFilePath, @"Skipping cross-scope dependency registration on package: PackageA, bundle scope: PerUser, package scope: PerMachine"));
589
590 var bundleHv2InstallLogFilePath = bundleHv2.Install();
591 bundleHv2.VerifyRegisteredAndInPackageCache();
592 bundleHv1.VerifyUnregisteredAndRemovedFromPackageCache();
593
594 packageA.VerifyInstalled(true);
595 packageDv1.VerifyInstalled(false);
596 packageDv2.VerifyInstalled(true);
597
598 Assert.True(LogVerifier.MessageInLogFileRegex(bundleHv2InstallLogFilePath, @"Skipping cross-scope dependency registration on package: PackageA, bundle scope: PerUser, package scope: PerMachine"));
599 Assert.True(LogVerifier.MessageInLogFileRegex(bundleHv2InstallLogFilePath, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Upgrade, scope: PerUser, version: 1\.0\.0\.0, operation: MajorUpgrade, cached: Yes"));
600
601 bundleHv2.Uninstall();
602 bundleHv2.VerifyUnregisteredAndRemovedFromPackageCache();
603
604 // Verify that permanent packageA is still installed and then remove.
605 packageA.VerifyInstalled(true);
606 packageDv2.VerifyInstalled(false);
607 packageA.UninstallProduct();
608 packageA.VerifyInstalled(false);
609 }
610 }
611}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs
new file mode 100644
index 00000000..54a89469
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/ElevationTests.cs
@@ -0,0 +1,30 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using Xunit;
6 using Xunit.Abstractions;
7
8 public class ElevationTests : BurnE2ETests
9 {
10 public ElevationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
11
12 /// <summary>
13 /// This test calls Elevate after Detect, and then calls Plan in OnElevateBegin.
14 /// After calling Plan, it pumps some messages to simulate UI like the UAC callback.
15 /// </summary>
16 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6349")] // CAUTION: this test currently hangs because the Plan request gets dropped.
17 public void CanExplicitlyElevateAndPlanFromOnElevateBegin()
18 {
19 var packageA = this.CreatePackageInstaller("PackageA");
20 var bundleA = this.CreateBundleInstaller("BundleA");
21 var testBAController = this.CreateTestBAController();
22
23 testBAController.SetExplicitlyElevateAndPlanFromOnElevateBegin();
24
25 bundleA.Install();
26 bundleA.VerifyRegisteredAndInPackageCache();
27 packageA.VerifyInstalled(true);
28 }
29 }
30}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs
new file mode 100644
index 00000000..a11a5eb6
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs
@@ -0,0 +1,112 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using WixTestTools;
6 using Xunit;
7 using Xunit.Abstractions;
8
9 public class FailureTests : BurnE2ETests
10 {
11 public FailureTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
12
13 [Fact]
14 public void CanCancelMsiPackageVeryEarly()
15 {
16 var packageA = this.CreatePackageInstaller("PackageA");
17 var packageB = this.CreatePackageInstaller("PackageB");
18 var bundleA = this.CreateBundleInstaller("BundleA");
19 var testBAController = this.CreateTestBAController();
20
21 // Cancel package B right away.
22 testBAController.SetPackageCancelExecuteAtProgress("PackageB", 1);
23
24 bundleA.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
25 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
26
27 packageA.VerifyInstalled(false);
28 packageB.VerifyInstalled(false);
29 }
30
31 [Fact]
32 public void CanCancelMsiPackageVeryLate()
33 {
34 var packageA = this.CreatePackageInstaller("PackageA");
35 var packageB = this.CreatePackageInstaller("PackageB");
36 var bundleA = this.CreateBundleInstaller("BundleA");
37 var testBAController = this.CreateTestBAController();
38
39 // Cancel package B at the last moment possible.
40 testBAController.SetPackageCancelExecuteAtProgress("PackageB", 100);
41
42 bundleA.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
43 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
44
45 packageA.VerifyInstalled(false);
46 packageB.VerifyInstalled(false);
47 }
48
49 [Fact]
50 public void CanCancelMsiPackageInOnProgress()
51 {
52 var packageA = this.CreatePackageInstaller("PackageA");
53 var packageB = this.CreatePackageInstaller("PackageB");
54 var bundleA = this.CreateBundleInstaller("BundleA");
55 var testBAController = this.CreateTestBAController();
56
57 // Cancel package B during its OnProgress message.
58 testBAController.SetPackageCancelOnProgressAtProgress("PackageB", 100);
59
60 bundleA.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
61 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
62
63 packageA.VerifyInstalled(false);
64 packageB.VerifyInstalled(false);
65 }
66
67 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/5750")]
68 public void CanCancelExecuteWhileCaching()
69 {
70 var packageA = this.CreatePackageInstaller("PackageA");
71 var packageB = this.CreatePackageInstaller("PackageB");
72 var bundleB = this.CreateBundleInstaller("BundleB");
73 var testBAController = this.CreateTestBAController();
74
75 // Slow the caching of package B to ensure that package A starts installing and cancels.
76 testBAController.SetPackageCancelExecuteAtProgress("PackageA", 50);
77 testBAController.SetPackageSlowCache("PackageB", 2000);
78
79 bundleB.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
80 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
81
82 packageA.VerifyInstalled(false);
83 packageB.VerifyInstalled(false);
84 }
85
86 /// <summary>
87 /// BundleC has non-vital PackageA and vital PackageB.
88 /// PackageA is not compressed in the bundle and has a Name different from the source file. The Name points to a file that does not exist.
89 /// BundleC should be able to install successfully by ignoring the missing PackageA and installing PackageB.
90 /// </summary>
91 [Fact]
92 public void CanInstallWhenMissingNonVitalPackage()
93 {
94 var packageA = this.CreatePackageInstaller("PackageA");
95 var packageB = this.CreatePackageInstaller("PackageB");
96 var bundleC = this.CreateBundleInstaller("BundleC");
97
98 var bundleCInstallLogFilePath = bundleC.Install();
99 bundleC.VerifyRegisteredAndInPackageCache();
100 Assert.True(LogVerifier.MessageInLogFileRegex(bundleCInstallLogFilePath, "Skipping apply of package: PackageA due to cache error: 0x80070002. Continuing..."));
101
102 packageA.VerifyInstalled(false);
103 packageB.VerifyInstalled(true);
104
105 bundleC.Uninstall();
106 bundleC.VerifyUnregisteredAndRemovedFromPackageCache();
107
108 packageA.VerifyInstalled(false);
109 packageB.VerifyInstalled(false);
110 }
111 }
112}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs
new file mode 100644
index 00000000..eb649c86
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/ForwardCompatibleBundleTests.cs
@@ -0,0 +1,469 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using WixTestTools;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class ForwardCompatibleBundleTests : BurnE2ETests
12 {
13 public ForwardCompatibleBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 private const string BundleAProviderId = "~" + nameof(ForwardCompatibleBundleTests) + "_BundleA";
16 private const string BundleCProviderId = "~" + nameof(ForwardCompatibleBundleTests) + "_BundleC";
17 private const string V100 = "1.0.0.0";
18 private const string V200 = "2.0.0.0";
19
20 [Fact]
21 public void CanTrack1ForwardCompatibleDependentThroughMajorUpgrade()
22 {
23 string providerId = BundleAProviderId;
24 string parent = "~BundleAv1";
25 string parentSwitch = String.Concat("-parent ", parent);
26
27 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
28 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
29 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
30 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
31
32 packageAv1.VerifyInstalled(false);
33 packageAv2.VerifyInstalled(false);
34
35 // Install the v1 bundle with a parent.
36 bundleAv1.Install(arguments: parentSwitch);
37 bundleAv1.VerifyRegisteredAndInPackageCache();
38
39 packageAv1.VerifyInstalled(true);
40 packageAv2.VerifyInstalled(false);
41 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
42 Assert.Equal(V100, actualProviderVersion);
43 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
44
45 // Upgrade with the v2 bundle.
46 bundleAv2.Install();
47 bundleAv2.VerifyRegisteredAndInPackageCache();
48 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
49
50 packageAv1.VerifyInstalled(false);
51 packageAv2.VerifyInstalled(true);
52 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
53 Assert.Equal(V200, actualProviderVersion);
54 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
55
56 // Uninstall the v2 bundle and nothing should happen because there is still a parent.
57 bundleAv2.Uninstall();
58 bundleAv2.VerifyRegisteredAndInPackageCache();
59
60 packageAv1.VerifyInstalled(false);
61 packageAv2.VerifyInstalled(true);
62 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
63 Assert.Equal(V200, actualProviderVersion);
64 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
65
66 // Uninstall the v1 bundle with passthrough and all should be removed.
67 bundleAv1.Uninstall(arguments: parentSwitch);
68 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
69 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
70
71 packageAv1.VerifyInstalled(false);
72 packageAv2.VerifyInstalled(false);
73 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
74 }
75
76 [Fact]
77 public void CanTrack1ForwardCompatibleDependentThroughMajorUpgradeWithParentNone()
78 {
79 string providerId = BundleAProviderId;
80 string parent = "~BundleAv1";
81 string parentSwitch = String.Concat("-parent ", parent);
82
83 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
84 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
85 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
86 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
87
88 packageAv1.VerifyInstalled(false);
89 packageAv2.VerifyInstalled(false);
90
91 // Install the v1 bundle with a parent.
92 bundleAv1.Install(arguments: parentSwitch);
93 bundleAv1.VerifyRegisteredAndInPackageCache();
94
95 packageAv1.VerifyInstalled(true);
96 packageAv2.VerifyInstalled(false);
97 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
98 Assert.Equal(V100, actualProviderVersion);
99 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
100
101 // Upgrade with the v2 bundle but prevent self parent being registered.
102 bundleAv2.Install(arguments: "-parent:none");
103 bundleAv2.VerifyRegisteredAndInPackageCache();
104 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
105
106 packageAv1.VerifyInstalled(false);
107 packageAv2.VerifyInstalled(true);
108 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
109 Assert.Equal(V200, actualProviderVersion);
110 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
111
112 // Uninstall the v1 bundle with passthrough and all should be removed.
113 bundleAv1.Uninstall(arguments: parentSwitch);
114 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
115 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
116
117 packageAv1.VerifyInstalled(false);
118 packageAv2.VerifyInstalled(false);
119 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
120 }
121
122 [Fact]
123 public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgrade()
124 {
125 string providerId = BundleAProviderId;
126 string parent = "~BundleAv1";
127 string parent2 = "~BundleAv1_Parent2";
128 string parentSwitch = String.Concat("-parent ", parent);
129 string parent2Switch = String.Concat("-parent ", parent2);
130
131 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
132 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
133 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
134 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
135
136 packageAv1.VerifyInstalled(false);
137 packageAv2.VerifyInstalled(false);
138
139 // Install the v1 bundle with a parent.
140 bundleAv1.Install(arguments: parentSwitch);
141 bundleAv1.VerifyRegisteredAndInPackageCache();
142
143 packageAv1.VerifyInstalled(true);
144 packageAv2.VerifyInstalled(false);
145 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
146 Assert.Equal(V100, actualProviderVersion);
147 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
148
149 // Install the v1 bundle with a second parent.
150 bundleAv1.Install(arguments: parent2Switch);
151 bundleAv1.VerifyRegisteredAndInPackageCache();
152
153 packageAv1.VerifyInstalled(true);
154 packageAv2.VerifyInstalled(false);
155 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
156 Assert.Equal(V100, actualProviderVersion);
157 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
158
159 // Upgrade with the v2 bundle.
160 bundleAv2.Install();
161 bundleAv2.VerifyRegisteredAndInPackageCache();
162 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
163
164 packageAv1.VerifyInstalled(false);
165 packageAv2.VerifyInstalled(true);
166 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
167 Assert.Equal(V200, actualProviderVersion);
168 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
169 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
170
171 // Uninstall the v2 bundle and nothing should happen because there is still a parent.
172 bundleAv2.Uninstall();
173 bundleAv2.VerifyRegisteredAndInPackageCache();
174
175 packageAv1.VerifyInstalled(false);
176 packageAv2.VerifyInstalled(true);
177 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
178 Assert.Equal(V200, actualProviderVersion);
179 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
180 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
181
182 // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent.
183 bundleAv1.Uninstall(arguments: parentSwitch);
184 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
185 bundleAv2.VerifyRegisteredAndInPackageCache();
186
187 packageAv1.VerifyInstalled(false);
188 packageAv2.VerifyInstalled(true);
189 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
190 Assert.Equal(V200, actualProviderVersion);
191 Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent));
192 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
193
194 // Uninstall the v1 bundle with passthrough with second parent and all should be removed.
195 bundleAv1.Uninstall(arguments: parent2Switch);
196 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
197 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
198
199 packageAv1.VerifyInstalled(false);
200 packageAv2.VerifyInstalled(false);
201 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
202 }
203
204 [Fact]
205 public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgradePerUser()
206 {
207 string providerId = BundleCProviderId;
208 string parent = "~BundleCv1";
209 string parent2 = "~BundleCv1_Parent2";
210 string parentSwitch = String.Concat("-parent ", parent);
211 string parent2Switch = String.Concat("-parent ", parent2);
212
213 var packageCv1 = this.CreatePackageInstaller("PackageCv1");
214 var packageCv2 = this.CreatePackageInstaller("PackageCv2");
215 var bundleCv1 = this.CreateBundleInstaller("BundleCv1");
216 var bundleCv2 = this.CreateBundleInstaller("BundleCv2");
217
218 packageCv1.VerifyInstalled(false);
219 packageCv2.VerifyInstalled(false);
220
221 // Install the v1 bundle with a parent.
222 bundleCv1.Install(arguments: parentSwitch);
223 bundleCv1.VerifyRegisteredAndInPackageCache();
224
225 packageCv1.VerifyInstalled(true);
226 packageCv2.VerifyInstalled(false);
227 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
228 Assert.Equal(V100, actualProviderVersion);
229 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
230
231 // Install the v1 bundle with a second parent.
232 bundleCv1.Install(arguments: parent2Switch);
233 bundleCv1.VerifyRegisteredAndInPackageCache();
234
235 packageCv1.VerifyInstalled(true);
236 packageCv2.VerifyInstalled(false);
237 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
238 Assert.Equal(V100, actualProviderVersion);
239 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
240
241 // Upgrade with the v2 bundle.
242 bundleCv2.Install();
243 bundleCv2.VerifyRegisteredAndInPackageCache();
244 bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache();
245
246 packageCv1.VerifyInstalled(false);
247 packageCv2.VerifyInstalled(true);
248 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
249 Assert.Equal(V200, actualProviderVersion);
250 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
251 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
252
253 // Uninstall the v2 bundle and nothing should happen because there is still a parent.
254 bundleCv2.Uninstall();
255 bundleCv2.VerifyRegisteredAndInPackageCache();
256
257 packageCv1.VerifyInstalled(false);
258 packageCv2.VerifyInstalled(true);
259 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
260 Assert.Equal(V200, actualProviderVersion);
261 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
262 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
263
264 // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent.
265 bundleCv1.Uninstall(arguments: parentSwitch);
266 bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache();
267 bundleCv2.VerifyRegisteredAndInPackageCache();
268
269 packageCv1.VerifyInstalled(false);
270 packageCv2.VerifyInstalled(true);
271 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
272 Assert.Equal(V200, actualProviderVersion);
273 Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent));
274 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
275
276 // Uninstall the v1 bundle with passthrough with second parent and all should be removed.
277 bundleCv1.Uninstall(arguments: parent2Switch);
278 bundleCv1.VerifyUnregisteredAndRemovedFromPackageCache();
279 bundleCv2.VerifyUnregisteredAndRemovedFromPackageCache();
280
281 packageCv1.VerifyInstalled(false);
282 packageCv2.VerifyInstalled(false);
283 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
284 }
285
286 [Fact]
287 public void CanTrack2ForwardCompatibleDependentsThroughMajorUpgradeWithParent()
288 {
289 string providerId = BundleAProviderId;
290 string parent = "~BundleAv1";
291 string parent2 = "~BundleAv1_Parent2";
292 string parent3 = "~BundleAv1_Parent3";
293 string parentSwitch = String.Concat("-parent ", parent);
294 string parent2Switch = String.Concat("-parent ", parent2);
295 string parent3Switch = String.Concat("-parent ", parent3);
296
297 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
298 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
299 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
300 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
301
302 packageAv1.VerifyInstalled(false);
303 packageAv2.VerifyInstalled(false);
304
305 // Install the v1 bundle with a parent.
306 bundleAv1.Install(arguments: parentSwitch);
307 bundleAv1.VerifyRegisteredAndInPackageCache();
308
309 packageAv1.VerifyInstalled(true);
310 packageAv2.VerifyInstalled(false);
311 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
312 Assert.Equal(V100, actualProviderVersion);
313 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
314
315 // Install the v1 bundle with a second parent.
316 bundleAv1.Install(arguments: parent2Switch);
317 bundleAv1.VerifyRegisteredAndInPackageCache();
318
319 packageAv1.VerifyInstalled(true);
320 packageAv2.VerifyInstalled(false);
321 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
322 Assert.Equal(V100, actualProviderVersion);
323 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
324
325 // Upgrade with the v2 bundle.
326 bundleAv2.Install(arguments: parent3Switch);
327 bundleAv2.VerifyRegisteredAndInPackageCache();
328 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
329
330 packageAv1.VerifyInstalled(false);
331 packageAv2.VerifyInstalled(true);
332 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
333 Assert.Equal(V200, actualProviderVersion);
334 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
335 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
336 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent3));
337
338 // Uninstall the v2 bundle and nothing should happen because there is still a parent.
339 bundleAv2.Uninstall(arguments: parent3Switch);
340 bundleAv2.VerifyRegisteredAndInPackageCache();
341
342 packageAv1.VerifyInstalled(false);
343 packageAv2.VerifyInstalled(true);
344 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
345 Assert.Equal(V200, actualProviderVersion);
346 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
347 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
348 Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent3));
349
350 // Uninstall one parent of the v1 bundle and nothing should happen because there is still a parent.
351 bundleAv1.Uninstall(arguments: parentSwitch);
352 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
353 bundleAv2.VerifyRegisteredAndInPackageCache();
354
355 packageAv1.VerifyInstalled(false);
356 packageAv2.VerifyInstalled(true);
357 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
358 Assert.Equal(V200, actualProviderVersion);
359 Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent));
360 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent2));
361
362 // Uninstall the v1 bundle with passthrough with second parent and all should be removed.
363 bundleAv1.Uninstall(arguments: parent2Switch);
364 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
365 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
366
367 packageAv1.VerifyInstalled(false);
368 packageAv2.VerifyInstalled(false);
369 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
370 }
371
372 [Fact]
373 public void CanUninstallForwardCompatibleWithBundlesUninstalledInFifoOrder()
374 {
375 string providerId = BundleAProviderId;
376 string parent = "~BundleAv1";
377 string parentSwitch = String.Concat("-parent ", parent);
378
379 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
380 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
381 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
382 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
383
384 packageAv1.VerifyInstalled(false);
385 packageAv2.VerifyInstalled(false);
386
387 bundleAv2.Install();
388 bundleAv2.VerifyRegisteredAndInPackageCache();
389
390 packageAv1.VerifyInstalled(false);
391 packageAv2.VerifyInstalled(true);
392 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
393 Assert.Equal(V200, actualProviderVersion);
394
395 // Install the v1 bundle with a parent which should passthrough to v2.
396 bundleAv1.Install(arguments: parentSwitch);
397 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
398
399 packageAv1.VerifyInstalled(false);
400 packageAv2.VerifyInstalled(true);
401 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
402
403 bundleAv2.Uninstall();
404 bundleAv2.VerifyRegisteredAndInPackageCache();
405
406 packageAv1.VerifyInstalled(false);
407 packageAv2.VerifyInstalled(true);
408 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
409
410 // Uninstall the v1 bundle with passthrough and all should be removed.
411 bundleAv1.Uninstall(arguments: parentSwitch);
412 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
413 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
414
415 packageAv1.VerifyInstalled(false);
416 packageAv2.VerifyInstalled(false);
417 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
418 }
419
420 [Fact]
421 public void CanUninstallForwardCompatibleWithBundlesUninstalledInReverseOrder()
422 {
423 string providerId = BundleAProviderId;
424 string parent = "~BundleAv1";
425 string parentSwitch = String.Concat("-parent ", parent);
426
427 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
428 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
429 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
430 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
431
432 packageAv1.VerifyInstalled(false);
433 packageAv2.VerifyInstalled(false);
434
435 bundleAv2.Install();
436 bundleAv2.VerifyRegisteredAndInPackageCache();
437
438 packageAv1.VerifyInstalled(false);
439 packageAv2.VerifyInstalled(true);
440 Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion));
441 Assert.Equal(V200, actualProviderVersion);
442
443 // Install the v1 bundle with a parent which should passthrough to v2.
444 bundleAv1.Install(arguments: parentSwitch);
445 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
446
447 packageAv1.VerifyInstalled(false);
448 packageAv2.VerifyInstalled(true);
449 Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent));
450
451 // Uninstall the v1 bundle with the same parent which should passthrough to v2 and remove parent.
452 bundleAv1.Uninstall(arguments: parentSwitch);
453 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
454 bundleAv2.VerifyRegisteredAndInPackageCache();
455
456 packageAv1.VerifyInstalled(false);
457 packageAv2.VerifyInstalled(true);
458 Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent));
459
460 // Uninstall the v2 bundle and all should be removed.
461 bundleAv2.Uninstall();
462 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
463
464 packageAv1.VerifyInstalled(false);
465 packageAv2.VerifyInstalled(false);
466 Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion));
467 }
468 }
469}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/IWebServer.cs b/src/test/burn/WixToolsetTest.BurnE2E/IWebServer.cs
new file mode 100644
index 00000000..3bb8a23e
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/IWebServer.cs
@@ -0,0 +1,20 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7
8 public interface IWebServer : IDisposable
9 {
10 /// <summary>
11 /// Registers a collection of relative URLs (the key) with its absolute path to the file (the value).
12 /// </summary>
13 void AddFiles(Dictionary<string, string> physicalPathsByRelativeUrl);
14
15 /// <summary>
16 /// Starts the web server on a new thread.
17 /// </summary>
18 void Start();
19 }
20} \ No newline at end of file
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/LayoutTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/LayoutTests.cs
new file mode 100644
index 00000000..1e36e2a5
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/LayoutTests.cs
@@ -0,0 +1,68 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System.Collections.Generic;
6 using System.IO;
7 using WixBuildTools.TestSupport;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class LayoutTests : BurnE2ETests
12 {
13 public LayoutTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 [Fact]
16 public void CanLayoutBundleInPlaceWithMissingPayloads()
17 {
18 var bundleA = this.CreateBundleInstaller("BundleA");
19 var webServer = this.CreateWebServer();
20
21 webServer.AddFiles(new Dictionary<string, string>
22 {
23 { "/BundleA/LayoutOnlyPayload", Path.Combine(this.TestContext.TestDataFolder, "BundleA.wxs") },
24 { "/BundleA/packages.cab", Path.Combine(this.TestContext.TestDataFolder, "packages.cab") },
25 });
26 webServer.Start();
27
28 using var dfs = new DisposableFileSystem();
29 var layoutDirectory = dfs.GetFolder(true);
30
31 // Manually copy bundle to layout directory and then run from there so the non-compressed payloads have to be resolved.
32 var bundleAFileInfo = new FileInfo(bundleA.Bundle);
33 var bundleACopiedPath = Path.Combine(layoutDirectory, bundleAFileInfo.Name);
34 bundleAFileInfo.CopyTo(bundleACopiedPath);
35
36 bundleA.Layout(bundleACopiedPath, layoutDirectory);
37 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
38
39 Assert.True(File.Exists(bundleACopiedPath));
40 Assert.True(File.Exists(Path.Combine(layoutDirectory, "packages.cab")));
41 Assert.True(File.Exists(Path.Combine(layoutDirectory, "BundleA.wxs")));
42 }
43
44 [Fact]
45 public void CanLayoutBundleToNewDirectory()
46 {
47 var bundleA = this.CreateBundleInstaller("BundleA");
48 var webServer = this.CreateWebServer();
49
50 webServer.AddFiles(new Dictionary<string, string>
51 {
52 { "/BundleA/LayoutOnlyPayload", Path.Combine(this.TestContext.TestDataFolder, "BundleA.wxs") },
53 { "/BundleA/packages.cab", Path.Combine(this.TestContext.TestDataFolder, "packages.cab") },
54 });
55 webServer.Start();
56
57 using var dfs = new DisposableFileSystem();
58 var layoutDirectory = dfs.GetFolder();
59
60 bundleA.Layout(layoutDirectory);
61 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
62
63 Assert.True(File.Exists(Path.Combine(layoutDirectory, "BundleA.exe")));
64 Assert.True(File.Exists(Path.Combine(layoutDirectory, "packages.cab")));
65 Assert.True(File.Exists(Path.Combine(layoutDirectory, "BundleA.wxs")));
66 }
67 }
68}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/MsiTransactionTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/MsiTransactionTests.cs
new file mode 100644
index 00000000..3d9748bb
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/MsiTransactionTests.cs
@@ -0,0 +1,128 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using WixTestTools;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class MsiTransactionTests : BurnE2ETests
12 {
13 public MsiTransactionTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 [Fact]
16 public void CanUpgradeBundleWithMsiTransaction()
17 {
18 var packageA = this.CreatePackageInstaller("PackageA");
19 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
20 var packageBv2 = this.CreatePackageInstaller("PackageBv2");
21 var packageCv1 = this.CreatePackageInstaller("PackageCv1");
22 var packageCv2 = this.CreatePackageInstaller("PackageCv2");
23 var packageD = this.CreatePackageInstaller("PackageD");
24
25 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
26 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
27
28 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
29 var packageBv1SourceCodeInstalled = packageBv1.GetInstalledFilePath("Package.wxs");
30 var packageBv2SourceCodeInstalled = packageBv2.GetInstalledFilePath("Package.wxs");
31 var packageCv1SourceCodeInstalled = packageCv1.GetInstalledFilePath("Package.wxs");
32 var packageCv2SourceCodeInstalled = packageCv2.GetInstalledFilePath("Package.wxs");
33 var packageDSourceCodeInstalled = packageD.GetInstalledFilePath("Package.wxs");
34
35 // Source file should *not* be installed
36 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
37 Assert.False(File.Exists(packageBv1SourceCodeInstalled), $"Package Bv1 payload should not be there on test start: {packageBv1SourceCodeInstalled}");
38 Assert.False(File.Exists(packageBv2SourceCodeInstalled), $"Package Bv2 payload should not be there on test start: {packageBv2SourceCodeInstalled}");
39 Assert.False(File.Exists(packageCv1SourceCodeInstalled), $"Package Cv1 payload should not be there on test start: {packageCv1SourceCodeInstalled}");
40 Assert.False(File.Exists(packageCv2SourceCodeInstalled), $"Package Cv2 payload should not be there on test start: {packageCv2SourceCodeInstalled}");
41 Assert.False(File.Exists(packageDSourceCodeInstalled), $"Package D payload should not be there on test start: {packageDSourceCodeInstalled}");
42
43 bundleAv1.Install();
44
45 var bundleAv1CachedPath = bundleAv1.VerifyRegisteredAndInPackageCache();
46
47 // Source file should be installed
48 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
49 Assert.True(File.Exists(packageBv1SourceCodeInstalled), String.Concat("Should have found Package Bv1 payload installed at: ", packageBv1SourceCodeInstalled));
50 Assert.True(File.Exists(packageCv1SourceCodeInstalled), String.Concat("Should have found Package Cv1 payload installed at: ", packageCv1SourceCodeInstalled));
51
52 bundleAv2.Install();
53
54 var bundleAv2CachedPath = bundleAv2.VerifyRegisteredAndInPackageCache();
55
56 // Source file should be upgraded
57 Assert.True(File.Exists(packageDSourceCodeInstalled), String.Concat("Should have found Package D payload installed at: ", packageDSourceCodeInstalled));
58 Assert.True(File.Exists(packageBv2SourceCodeInstalled), String.Concat("Should have found Package Bv2 payload installed at: ", packageBv2SourceCodeInstalled));
59 Assert.True(File.Exists(packageCv2SourceCodeInstalled), String.Concat("Should have found Package Cv2 payload installed at: ", packageCv2SourceCodeInstalled));
60 Assert.False(File.Exists(packageCv1SourceCodeInstalled), String.Concat("Package Cv1 payload should have been removed by upgrade uninstall from: ", packageCv1SourceCodeInstalled));
61 Assert.False(File.Exists(packageBv1SourceCodeInstalled), String.Concat("Package Bv1 payload should have been removed by upgrade uninstall from: ", packageBv1SourceCodeInstalled));
62 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Package A payload should have been removed by upgrade uninstall from: ", packageASourceCodeInstalled));
63
64 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(bundleAv1CachedPath);
65
66 // Uninstall everything.
67 bundleAv2.Uninstall();
68
69 // Source file should *not* be installed
70 Assert.False(File.Exists(packageDSourceCodeInstalled), String.Concat("Package D payload should have been removed by uninstall from: ", packageDSourceCodeInstalled));
71 Assert.False(File.Exists(packageBv2SourceCodeInstalled), String.Concat("Package Bv2 payload should have been removed by uninstall from: ", packageBv2SourceCodeInstalled));
72 Assert.False(File.Exists(packageCv2SourceCodeInstalled), String.Concat("Package Cv2 payload should have been removed by uninstall from: ", packageCv2SourceCodeInstalled));
73
74 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(bundleAv2CachedPath);
75 }
76
77 /// <summary>
78 /// Installs 2 bundles:
79 /// BundleBv1- installs package Bv1
80 /// BundleBv2- installs packages A, Bv2, F
81 /// package Bv2 performs a major upgrade of package Bv1
82 /// package F fails
83 /// Thus, rolling back the transaction should reinstall package Bv1
84 /// </summary>
85 [Fact]
86 public void CanRelyOnMsiTransactionRollback()
87 {
88 var packageA = this.CreatePackageInstaller("PackageA");
89 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
90 var packageBv2 = this.CreatePackageInstaller("PackageBv2");
91 this.CreatePackageInstaller("PackageF");
92
93 var bundleBv1 = this.CreateBundleInstaller("BundleBv1");
94 var bundleBv2 = this.CreateBundleInstaller("BundleBv2");
95
96 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
97 var packageBv1SourceCodeInstalled = packageBv1.GetInstalledFilePath("Package.wxs");
98 var packageBv2SourceCodeInstalled = packageBv2.GetInstalledFilePath("Package.wxs");
99
100 // Source file should *not* be installed
101 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
102 Assert.False(File.Exists(packageBv1SourceCodeInstalled), $"Package Bv1 payload should not be there on test start: {packageBv1SourceCodeInstalled}");
103 Assert.False(File.Exists(packageBv2SourceCodeInstalled), $"Package Bv2 payload should not be there on test start: {packageBv2SourceCodeInstalled}");
104
105 bundleBv1.Install();
106
107 bundleBv1.VerifyRegisteredAndInPackageCache();
108
109 // Source file should be installed
110 Assert.True(File.Exists(packageBv1SourceCodeInstalled), String.Concat("Should have found Package Bv1 payload installed at: ", packageBv1SourceCodeInstalled));
111
112 bundleBv2.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE);
113
114 // Bundle v2 should be registered since it installed a non-permanent package.
115 bundleBv2.VerifyRegisteredAndInPackageCache();
116
117 // Bundle v1 should not have been removed since the install of v2 failed in the middle of the chain.
118 bundleBv1.VerifyRegisteredAndInPackageCache();
119
120 // Source file should be installed
121 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
122
123 // Previous source file should be installed
124 Assert.True(File.Exists(packageBv1SourceCodeInstalled), String.Concat("Should have found Package Bv1 payload installed at: ", packageBv1SourceCodeInstalled));
125 Assert.False(File.Exists(packageBv2SourceCodeInstalled), String.Concat("Should not have found Package Bv2 payload installed at: ", packageBv2SourceCodeInstalled));
126 }
127 }
128}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/PatchTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/PatchTests.cs
new file mode 100644
index 00000000..0c7fdc98
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/PatchTests.cs
@@ -0,0 +1,137 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using System.Xml;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class PatchTests : BurnE2ETests
12 {
13 public PatchTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 [Fact]
16 public void CanRunDetectMultipleTimesWithPatches()
17 {
18 var testBAController = this.CreateTestBAController();
19 testBAController.SetRedetectCount(1);
20
21 this.CanInstallBundleWithPatchThenRemoveIt();
22 }
23
24 [Fact]
25 public void CanInstallBundleWithPatchThenRemoveIt()
26 {
27 var originalVersion = "1.0.0.0";
28 var patchedVersion = "1.0.1.0";
29 var testRegistryValue = "PackageA";
30
31 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
32 var bundleA = this.CreateBundleInstaller("BundleA");
33 var bundlePatchA = this.CreateBundleInstaller("BundlePatchA");
34
35 bundleA.Install();
36 bundleA.VerifyRegisteredAndInPackageCache();
37
38 packageAv1.VerifyInstalled(true);
39 packageAv1.VerifyTestRegistryValue(testRegistryValue, originalVersion);
40
41 bundlePatchA.Install();
42 bundlePatchA.VerifyRegisteredAndInPackageCache();
43
44 packageAv1.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
45
46 bundlePatchA.Uninstall();
47 bundlePatchA.VerifyUnregisteredAndRemovedFromPackageCache();
48
49 packageAv1.VerifyTestRegistryValue(testRegistryValue, originalVersion);
50
51 bundleA.Uninstall();
52 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
53
54 packageAv1.VerifyInstalled(false);
55 packageAv1.VerifyTestRegistryRootDeleted();
56 }
57
58 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6380")]
59 public void CanPatchSwidTag()
60 {
61 var originalVersion = "1.0.0.0";
62 var patchedVersion = "1.0.1.0";
63 var packageTagName = "~PatchTests - PackageA";
64 var bundleTagName = "~PatchTests - BundleA";
65 var bundlePatchTagName = "~PatchTests - BundlePatchA";
66
67 this.CreatePackageInstaller("PackageAv1");
68 var bundleA = this.CreateBundleInstaller("BundleA");
69 var bundlePatchA = this.CreateBundleInstaller("BundlePatchA");
70
71 bundleA.Install();
72 VerifySwidTagVersion(bundleTagName, originalVersion);
73 VerifySwidTagVersion(packageTagName, originalVersion);
74
75 bundlePatchA.Install();
76 VerifySwidTagVersion(bundlePatchTagName, patchedVersion);
77 VerifySwidTagVersion(packageTagName, patchedVersion);
78
79 bundlePatchA.Uninstall();
80 VerifySwidTagVersion(packageTagName, originalVersion);
81
82 bundleA.Uninstall();
83 VerifySwidTagVersion(bundleTagName, null);
84 VerifySwidTagVersion(packageTagName, null);
85 }
86
87 [Fact]
88 public void CanInstallBundleWithPatchesTargetingSingleProductThenRemoveIt()
89 {
90 var originalVersion = "1.0.0.0";
91 var patchedVersion = "1.0.1.0";
92 var testRegistryValue = "PackageA";
93 var testRegistryValue2 = "PackageA2";
94
95 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
96 var bundlePatchA2 = this.CreateBundleInstaller("BundlePatchA2");
97
98 packageAv1.InstallProduct();
99 packageAv1.VerifyInstalled(true);
100 packageAv1.VerifyTestRegistryValue(testRegistryValue, originalVersion);
101 packageAv1.VerifyTestRegistryValue(testRegistryValue2, originalVersion);
102
103 bundlePatchA2.Install();
104 bundlePatchA2.VerifyRegisteredAndInPackageCache();
105
106 packageAv1.VerifyTestRegistryValue(testRegistryValue, patchedVersion);
107 packageAv1.VerifyTestRegistryValue(testRegistryValue2, patchedVersion);
108
109 bundlePatchA2.Uninstall();
110 bundlePatchA2.VerifyUnregisteredAndRemovedFromPackageCache();
111
112 packageAv1.VerifyTestRegistryValue(testRegistryValue, originalVersion);
113 packageAv1.VerifyTestRegistryValue(testRegistryValue2, originalVersion);
114 }
115
116 private static void VerifySwidTagVersion(string tagName, string expectedVersion)
117 {
118 var regidFolder = Environment.ExpandEnvironmentVariables(@"%ProgramData%\regid.1995-08.com.example");
119 var tagPath = Path.Combine(regidFolder, "regid.1995-08.com.example " + tagName + ".swidtag");
120 string version = null;
121
122 if (File.Exists(tagPath))
123 {
124 var doc = new XmlDocument();
125 doc.Load(tagPath);
126
127 var ns = new XmlNamespaceManager(doc.NameTable);
128 ns.AddNamespace("s", "http://standards.iso.org/iso/19770/-2/2009/schema.xsd");
129
130 var versionNode = doc.SelectSingleNode("/s:software_identification_tag/s:product_version/s:name", ns);
131 version = versionNode?.InnerText ?? String.Empty;
132 }
133
134 Assert.Equal(expectedVersion, version);
135 }
136 }
137}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs
new file mode 100644
index 00000000..ced2e08e
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs
@@ -0,0 +1,76 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using Xunit;
8 using Xunit.Abstractions;
9
10 public class PrereqBaTests : BurnE2ETests
11 {
12 public PrereqBaTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
13
14 /// <summary>
15 /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist,
16 /// with an MSI package to represent the prerequisite package.
17 /// This verifies that:
18 /// The preqba doesn't infinitely reload itself after failing to load the managed BA.
19 /// The engine automatically uninstalls the bundle since only permanent packages were installed.
20 /// </summary>
21 [Fact]
22 public void DncPreqBaDetectsInfiniteLoop()
23 {
24 var packageA = this.CreatePackageInstaller("PackageA");
25 this.CreatePackageInstaller("PackageF");
26
27 var bundleA = this.CreateBundleInstaller("BundleA");
28
29 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
30
31 // Source file should *not* be installed
32 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
33
34 bundleA.Install();
35
36 // Part of the test is Install actually completing.
37
38 // Source file should be installed
39 Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled));
40
41 // No non-permanent packages should have ended up installed or cached so it should have unregistered.
42 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
43 }
44
45 /// <summary>
46 /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist,
47 /// with an MSI package to represent the prerequisite package.
48 /// This verifies that:
49 /// The preqba doesn't infinitely reload itself after failing to load the managed BA.
50 /// The engine automatically uninstalls the bundle since only permanent packages were installed.
51 /// </summary>
52 [Fact]
53 public void MbaPreqBaDetectsInfiniteLoop()
54 {
55 var packageB = this.CreatePackageInstaller("PackageB");
56 this.CreatePackageInstaller("PackageF");
57
58 var bundleB = this.CreateBundleInstaller("BundleB");
59
60 var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs");
61
62 // Source file should *not* be installed
63 Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}");
64
65 bundleB.Install();
66
67 // Part of the test is Install actually completing.
68
69 // Source file should be installed
70 Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled));
71
72 // No non-permanent packages should have ended up installed or cached so it should have unregistered.
73 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
74 }
75 }
76}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/RegistrationTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/RegistrationTests.cs
new file mode 100644
index 00000000..51122c28
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/RegistrationTests.cs
@@ -0,0 +1,78 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using Xunit;
7 using Xunit.Abstractions;
8
9 public class RegistrationTests : BurnE2ETests
10 {
11 public RegistrationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
12
13 [Fact]
14 public void AutomaticallyUncachesBundleWhenNotInstalled()
15 {
16 var bundleA = this.CreateBundleInstaller("BundleA");
17 var testBAController = this.CreateTestBAController();
18
19 var cachedBundlePath = bundleA.ManuallyCache();
20
21 testBAController.SetQuitAfterDetect();
22
23 bundleA.Install(cachedBundlePath);
24
25 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
26 }
27
28 [Fact]
29 public void AutomaticallyUninstallsBundleWithoutBADoingApply()
30 {
31 this.InstallBundleThenManuallyUninstallPackageAndRemovePackageFromCacheThenRunAndQuitWithoutApply(true);
32 }
33
34 [Fact]
35 public void AutomaticallyUninstallsBundleWithoutBADoingDetect()
36 {
37 this.InstallBundleThenManuallyUninstallPackageAndRemovePackageFromCacheThenRunAndQuitWithoutApply(false);
38 }
39
40 [Fact]
41 public void RegistersInARPIfPrecached()
42 {
43 var bundleA = this.CreateBundleInstaller("BundleA");
44
45 bundleA.ManuallyCache();
46
47 // Verifies https://github.com/wixtoolset/issues/issues/5702
48 bundleA.Install();
49 bundleA.VerifyRegisteredAndInPackageCache();
50 }
51
52 private void InstallBundleThenManuallyUninstallPackageAndRemovePackageFromCacheThenRunAndQuitWithoutApply(bool detect)
53 {
54 var packageA = this.CreatePackageInstaller("PackageA");
55 var bundleA = this.CreateBundleInstaller("BundleA");
56 var testBAController = this.CreateTestBAController();
57
58 bundleA.Install();
59 bundleA.VerifyRegisteredAndInPackageCache();
60 packageA.VerifyInstalled(true);
61
62 packageA.UninstallProduct();
63 bundleA.RemovePackageFromCache("PackageA");
64
65 if (detect)
66 {
67 testBAController.SetQuitAfterDetect();
68 }
69 else
70 {
71 testBAController.SetImmediatelyQuit();
72 }
73 bundleA.Install();
74 packageA.VerifyInstalled(false);
75 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
76 }
77 }
78}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs
new file mode 100644
index 00000000..6539db34
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/RollbackBoundaryTests.cs
@@ -0,0 +1,52 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using Xunit;
8 using Xunit.Abstractions;
9
10 public class RollbackBoundaryTests : BurnE2ETests
11 {
12 public RollbackBoundaryTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
13
14 /// <summary>
15 /// Installs 1 bundle:
16 /// chain - non-vital rollback boundary, package F, package A, vital rollback boundary, package B
17 /// package F fails
18 /// package A and B are permanent
19 /// Execution is supposed to be:
20 /// package F (fails)
21 /// rollback to non-vital rollback boundary which ignores the error and skips over package A
22 /// install package B
23 /// unregister since no non-permanent packages should be installed or cached.
24 /// </summary>
25 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6309")]
26 public void NonVitalRollbackBoundarySkipsToNextRollbackBoundary()
27 {
28 var packageA = this.CreatePackageInstaller("PackageA");
29 var packageB = this.CreatePackageInstaller("PackageB");
30 this.CreatePackageInstaller("PackageC");
31 this.CreatePackageInstaller("PackageF");
32
33 var bundleA = this.CreateBundleInstaller("BundleA");
34
35 var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs");
36 var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs");
37
38 // Source file should *not* be installed
39 Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}");
40 Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}");
41
42 bundleA.Install();
43
44 // No non-permanent packages should have ended up installed or cached so it should have unregistered.
45 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
46
47 // Only PackageB source file should be installed
48 Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled));
49 Assert.False(File.Exists(packageASourceCodeInstalled), String.Concat("Should not have found Package A payload installed at: ", packageASourceCodeInstalled));
50 }
51 }
52}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/SlipstreamTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/SlipstreamTests.cs
new file mode 100644
index 00000000..29632e2e
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/SlipstreamTests.cs
@@ -0,0 +1,353 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using WixTestTools;
8 using WixToolset.Mba.Core;
9 using Xunit;
10 using Xunit.Abstractions;
11
12 public class SlipstreamTests : BurnE2ETests
13 {
14 public SlipstreamTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
15
16 private const string V090 = "0.9.0.0";
17 private const string V100 = "1.0.0.0";
18 private const string V101 = "1.0.1.0";
19
20 [Fact]
21 public void CanInstallBundleWithSlipstreamedPatchThenRemoveIt()
22 {
23 var testRegistryValue = "PackageA";
24
25 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
26 var bundleA = this.CreateBundleInstaller("BundleA");
27
28 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
29 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
30
31 bundleA.Install();
32 bundleA.VerifyRegisteredAndInPackageCache();
33 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
34 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
35
36 bundleA.Uninstall();
37 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
38 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
39 packageAv1.VerifyTestRegistryRootDeleted();
40 }
41
42 /// <summary>
43 /// BundleA installs PackageA with slipstreamed PatchA.
44 /// BundleOnlyPatchA is installed which contains PatchA (which should be a no-op).
45 /// BundleOnlyPatchA in uninstalled which should do nothing since BundleA has a dependency on it.
46 /// Bundle is installed which should remove everything.
47 /// </summary>
48 [Fact]
49 public void ReferenceCountsSlipstreamedPatch()
50 {
51 var testRegistryValue = "PackageA";
52
53 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
54 var bundleOnlyPatchA = this.CreateBundleInstaller("BundleOnlyPatchA");
55 var bundleA = this.CreateBundleInstaller("BundleA");
56
57 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
58 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
59
60 bundleA.Install();
61 bundleA.VerifyRegisteredAndInPackageCache();
62 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
63 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
64
65 bundleOnlyPatchA.Install();
66 bundleOnlyPatchA.VerifyRegisteredAndInPackageCache();
67 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
68 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
69
70 bundleOnlyPatchA.Uninstall();
71 bundleOnlyPatchA.VerifyUnregisteredAndRemovedFromPackageCache();
72 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
73 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
74
75 bundleA.Uninstall();
76 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
77 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
78 packageAv1.VerifyTestRegistryRootDeleted();
79 }
80
81 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6350")]
82 public void CanInstallBundleWithSlipstreamedPatchThenRepairIt()
83 {
84 this.InstallBundleWithSlipstreamedPatchThenRepairIt(false);
85 }
86
87 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6350")]
88 public void CanInstallReversedBundleWithSlipstreamedPatchThenRepairIt()
89 {
90 this.InstallBundleWithSlipstreamedPatchThenRepairIt(true);
91 }
92
93 private void InstallBundleWithSlipstreamedPatchThenRepairIt(bool isReversed)
94 {
95 var bundleName = isReversed ? "BundleAReverse" : "BundleA";
96 var testRegistryValue = "PackageA";
97
98 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
99 var bundleA = this.CreateBundleInstaller(bundleName);
100
101 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
102 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
103
104 bundleA.Install();
105 bundleA.VerifyRegisteredAndInPackageCache();
106 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
107 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
108
109 // Delete the installed file and registry key so we have something to repair.
110 File.Delete(packageAv1SourceCodeInstalled);
111 packageAv1.DeleteTestRegistryValue(testRegistryValue);
112
113 bundleA.Repair();
114 bundleA.VerifyRegisteredAndInPackageCache();
115 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
116 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
117
118 bundleA.Uninstall();
119 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
120 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
121 packageAv1.VerifyTestRegistryRootDeleted();
122 }
123
124 [Fact]
125 public void CanInstallSlipstreamedPatchThroughForcedRepair()
126 {
127 this.InstallSlipstreamedPatchThroughForcedRepair(false);
128 }
129
130 [Fact]
131 public void CanInstallSlipstreamedPatchThroughReversedForcedRepair()
132 {
133 this.InstallSlipstreamedPatchThroughForcedRepair(true);
134 }
135
136 private void InstallSlipstreamedPatchThroughForcedRepair(bool isReversed)
137 {
138 var bundleName = isReversed ? "BundleAReverse" : "BundleA";
139 var testRegistryValue = "PackageA";
140
141 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
142 var bundleA = this.CreateBundleInstaller(bundleName);
143 var bundleOnlyA = this.CreateBundleInstaller("BundleOnlyA");
144 var testBAController = this.CreateTestBAController();
145
146 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
147 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
148
149 bundleOnlyA.Install();
150 bundleOnlyA.VerifyRegisteredAndInPackageCache();
151 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
152 packageAv1.VerifyTestRegistryValue(testRegistryValue, V100);
153
154 // Delete the installed file and registry key so we have something to repair.
155 File.Delete(packageAv1SourceCodeInstalled);
156 packageAv1.DeleteTestRegistryValue(testRegistryValue);
157
158 testBAController.SetPackageRequestedState("PackageA", RequestState.Repair);
159 testBAController.SetPackageRequestedState("PatchA", RequestState.Repair);
160
161 bundleA.Install();
162 bundleA.VerifyRegisteredAndInPackageCache();
163 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
164 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
165
166 testBAController.ResetPackageStates("PackageA");
167 testBAController.ResetPackageStates("PatchA");
168
169 bundleA.Uninstall();
170 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
171 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
172 packageAv1.VerifyTestRegistryValue(testRegistryValue, V100);
173
174 bundleOnlyA.Uninstall();
175 bundleOnlyA.VerifyUnregisteredAndRemovedFromPackageCache();
176 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
177 packageAv1.VerifyTestRegistryRootDeleted();
178 }
179
180 [Fact]
181 public void CanUninstallSlipstreamedPatchAlone()
182 {
183 var testRegistryValue = "PackageA";
184
185 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
186 var bundleA = this.CreateBundleInstaller("BundleA");
187 var testBAController = this.CreateTestBAController();
188
189 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
190 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
191
192 bundleA.Install();
193 bundleA.VerifyRegisteredAndInPackageCache();
194 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
195 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
196
197 testBAController.SetPackageRequestedState("PatchA", RequestState.Absent);
198
199 bundleA.Modify();
200 bundleA.VerifyRegisteredAndInPackageCache();
201 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
202 packageAv1.VerifyTestRegistryValue(testRegistryValue, V100);
203
204 bundleA.Uninstall();
205 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
206 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
207 packageAv1.VerifyTestRegistryRootDeleted();
208 }
209
210 [Fact]
211 public void CanModifyToUninstallPackageWithSlipstreamedPatch()
212 {
213 var testRegistryValue = "PackageA";
214
215 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
216 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
217 var bundleB = this.CreateBundleInstaller("BundleB");
218 var testBAController = this.CreateTestBAController();
219
220 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
221 var packageBv1SourceCodeInstalled = packageBv1.GetInstalledFilePath("Package.wxs");
222 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
223 Assert.False(File.Exists(packageBv1SourceCodeInstalled), $"PackageBv1 payload should not be there on test start: {packageBv1SourceCodeInstalled}");
224
225 bundleB.Install();
226 bundleB.VerifyRegisteredAndInPackageCache();
227 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
228 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
229 Assert.True(File.Exists(packageBv1SourceCodeInstalled), String.Concat("Should have found PackageBv1 payload installed at: ", packageBv1SourceCodeInstalled));
230
231 testBAController.SetPackageRequestedState("PackageA", RequestState.Absent);
232 testBAController.SetPackageRequestedState("PatchA", RequestState.Absent);
233
234 bundleB.Modify();
235 bundleB.VerifyRegisteredAndInPackageCache();
236 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should have been removed by modify from: {packageAv1SourceCodeInstalled}");
237
238 testBAController.ResetPackageStates("PackageA");
239 testBAController.ResetPackageStates("PatchA");
240
241 bundleB.Uninstall();
242 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
243 Assert.False(File.Exists(packageBv1SourceCodeInstalled), String.Concat("PackageBv1 payload should have been removed by uninstall from: ", packageBv1SourceCodeInstalled));
244 packageBv1.VerifyTestRegistryRootDeleted();
245 }
246
247 [Fact]
248 public void UninstallsPackageWithSlipstreamedPatchDuringRollback()
249 {
250 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
251 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
252 var bundleB = this.CreateBundleInstaller("BundleB");
253 var testBAController = this.CreateTestBAController();
254
255 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
256 var packageBv1SourceCodeInstalled = packageBv1.GetInstalledFilePath("Package.wxs");
257 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
258 Assert.False(File.Exists(packageBv1SourceCodeInstalled), $"PackageBv1 payload should not be there on test start: {packageBv1SourceCodeInstalled}");
259
260 testBAController.SetPackageCancelExecuteAtProgress("PackageB", 50);
261
262 bundleB.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT);
263 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
264 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should have been removed by rollback from: {packageAv1SourceCodeInstalled}");
265 Assert.False(File.Exists(packageBv1SourceCodeInstalled), String.Concat("PackageBv1 payload should not have been installed from: ", packageBv1SourceCodeInstalled));
266 packageBv1.VerifyTestRegistryRootDeleted();
267 }
268
269 [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6359")]
270 public void CanAutomaticallyPredetermineSlipstreamPatchesAtBuildTime()
271 {
272 var testRegistryValueA = "PackageA";
273 var testRegistryValueA2 = "PackageA2";
274 var testRegistryValueB = "PackageB";
275 var testRegistryValueB2 = "PackageB2";
276
277 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
278 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
279 var bundleC = this.CreateBundleInstaller("BundleC");
280
281 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
282 var packageBv1SourceCodeInstalled = packageBv1.GetInstalledFilePath("Package.wxs");
283 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
284 Assert.False(File.Exists(packageBv1SourceCodeInstalled), $"PackageBv1 payload should not be there on test start: {packageBv1SourceCodeInstalled}");
285
286 bundleC.Install();
287 bundleC.VerifyRegisteredAndInPackageCache();
288 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
289 // Product A should've slipstreamed both patches.
290 packageAv1.VerifyTestRegistryValue(testRegistryValueA, V101);
291 packageAv1.VerifyTestRegistryValue(testRegistryValueA2, V101);
292 // Product B should've only slipstreamed patch AB2.
293 packageBv1.VerifyTestRegistryValue(testRegistryValueB, V100);
294 packageBv1.VerifyTestRegistryValue(testRegistryValueB2, V101);
295
296 bundleC.Uninstall();
297 bundleC.VerifyUnregisteredAndRemovedFromPackageCache();
298 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
299 Assert.False(File.Exists(packageBv1SourceCodeInstalled), String.Concat("PackageBv1 payload should have been removed by uninstall from: ", packageBv1SourceCodeInstalled));
300 packageAv1.VerifyTestRegistryRootDeleted();
301 }
302
303 [Fact]
304 public void CanInstallSlipstreamedPatchWithPackageDuringMajorUpgrade()
305 {
306 var testRegistryValue = "PackageA";
307
308 var packageAv0 = this.CreatePackageInstaller("PackageAv0_9_0");
309 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
310 var bundleA = this.CreateBundleInstaller("BundleA");
311
312 packageAv1.VerifyInstalled(false);
313
314 packageAv0.InstallProduct();
315 packageAv0.VerifyInstalled(true);
316 packageAv1.VerifyTestRegistryValue(testRegistryValue, V090);
317
318 bundleA.Install();
319 bundleA.VerifyRegisteredAndInPackageCache();
320 packageAv0.VerifyInstalled(false);
321 packageAv1.VerifyInstalled(true);
322 packageAv1.VerifyTestRegistryValue(testRegistryValue, V101);
323
324 bundleA.Uninstall();
325 bundleA.VerifyUnregisteredAndRemovedFromPackageCache();
326 packageAv1.VerifyInstalled(false);
327 packageAv1.VerifyTestRegistryRootDeleted();
328 }
329
330 [Fact]
331 public void RespectsSlipstreamedPatchInstallCondition()
332 {
333 var testRegistryValue = "PackageA";
334
335 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
336 var bundleD = this.CreateBundleInstaller("BundleD");
337
338 var packageAv1SourceCodeInstalled = packageAv1.GetInstalledFilePath("Package.wxs");
339 Assert.False(File.Exists(packageAv1SourceCodeInstalled), $"PackageAv1 payload should not be there on test start: {packageAv1SourceCodeInstalled}");
340
341 bundleD.Install();
342 bundleD.VerifyRegisteredAndInPackageCache();
343 Assert.True(File.Exists(packageAv1SourceCodeInstalled), String.Concat("Should have found PackageAv1 payload installed at: ", packageAv1SourceCodeInstalled));
344 // The patch was not supposed to be installed.
345 packageAv1.VerifyTestRegistryValue(testRegistryValue, V100);
346
347 bundleD.Uninstall();
348 bundleD.VerifyUnregisteredAndRemovedFromPackageCache();
349 Assert.False(File.Exists(packageAv1SourceCodeInstalled), String.Concat("PackageAv1 payload should have been removed by uninstall from: ", packageAv1SourceCodeInstalled));
350 packageAv1.VerifyTestRegistryRootDeleted();
351 }
352 }
353}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs b/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs
new file mode 100644
index 00000000..6e4fe6c6
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/TestBAController.cs
@@ -0,0 +1,187 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using Microsoft.Win32;
7 using WixTestTools;
8 using WixToolset.Mba.Core;
9
10 public class TestBAController : IDisposable
11 {
12 public TestBAController(WixTestContext testContext, bool x64 = false)
13 {
14 this.TestGroupName = testContext.TestGroupName;
15 this.BaseRegKeyPath = x64 ? @"Software\WiX\Tests" : @"Software\WOW6432Node\WiX\Tests";
16 this.TestBaseRegKeyPath = String.Format(@"{0}\TestBAControl\{1}", this.BaseRegKeyPath, this.TestGroupName);
17 }
18
19 private string BaseRegKeyPath { get; }
20
21 private string TestBaseRegKeyPath { get; }
22
23 public string TestGroupName { get; }
24
25 /// <summary>
26 /// Sets a test value in the registry to communicate with the TestBA.
27 /// </summary>
28 /// <param name="name">Name of the value to set.</param>
29 /// <param name="value">Value to set. If this is null, the value is removed.</param>
30 public void SetBurnTestValue(string name, string value)
31 {
32 using (var testKey = Registry.LocalMachine.CreateSubKey(this.TestBaseRegKeyPath))
33 {
34 if (String.IsNullOrEmpty(value))
35 {
36 testKey.DeleteValue(name, false);
37 }
38 else
39 {
40 testKey.SetValue(name, value);
41 }
42 }
43 }
44
45 public void SetExplicitlyElevateAndPlanFromOnElevateBegin(string value = "true")
46 {
47 this.SetBurnTestValue("ExplicitlyElevateAndPlanFromOnElevateBegin", value);
48 }
49
50 public void SetImmediatelyQuit(string value = "true")
51 {
52 this.SetBurnTestValue("ImmediatelyQuit", value);
53 }
54
55 public void SetQuitAfterDetect(string value = "true")
56 {
57 this.SetBurnTestValue("QuitAfterDetect", value);
58 }
59
60 /// <summary>
61 /// Slows the cache progress of a package.
62 /// </summary>
63 /// <param name="packageId">Package identity.</param>
64 /// <param name="delay">Sets or removes the delay on a package being cached.</param>
65 public void SetPackageSlowCache(string packageId, int? delay)
66 {
67 this.SetPackageState(packageId, "SlowCache", delay.HasValue ? delay.ToString() : null);
68 }
69
70 /// <summary>
71 /// Cancels the cache of a package at a particular progress point.
72 /// </summary>
73 /// <param name="packageId">Package identity.</param>
74 /// <param name="cancelPoint">Sets or removes the cancel progress on a package being cached.</param>
75 public void SetPackageCancelCacheAtProgress(string packageId, int? cancelPoint)
76 {
77 this.SetPackageState(packageId, "CancelCacheAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null);
78 }
79
80 /// <summary>
81 /// Slows the execute progress of a package.
82 /// </summary>
83 /// <param name="packageId">Package identity.</param>
84 /// <param name="delay">Sets or removes the delay on a package being executed.</param>
85 public void SetPackageSlowExecute(string packageId, int? delay)
86 {
87 this.SetPackageState(packageId, "SlowExecute", delay.HasValue ? delay.ToString() : null);
88 }
89
90 /// <summary>
91 /// Cancels the execute of a package at a particular progress point.
92 /// </summary>
93 /// <param name="packageId">Package identity.</param>
94 /// <param name="cancelPoint">Sets or removes the cancel progress on a package being executed.</param>
95 public void SetPackageCancelExecuteAtProgress(string packageId, int? cancelPoint)
96 {
97 this.SetPackageState(packageId, "CancelExecuteAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null);
98 }
99
100 /// <summary>
101 /// Cancels the execute of a package at the next progess after the specified MSI action start.
102 /// </summary>
103 /// <param name="packageId">Package identity.</param>
104 /// <param name="actionName">Sets or removes the cancel progress on a package being executed.</param>
105 public void SetPackageCancelExecuteAtActionStart(string packageId, string actionName)
106 {
107 this.SetPackageState(packageId, "CancelExecuteAtActionStart", actionName);
108 }
109
110 /// <summary>
111 /// Cancels the execute of a package at a particular OnProgress point.
112 /// </summary>
113 /// <param name="packageId">Package identity.</param>
114 /// <param name="cancelPoint">Sets or removes the cancel OnProgress point on a package being executed.</param>
115 public void SetPackageCancelOnProgressAtProgress(string packageId, int? cancelPoint)
116 {
117 this.SetPackageState(packageId, "CancelOnProgressAtProgress", cancelPoint.HasValue ? cancelPoint.ToString() : null);
118 }
119
120 /// <summary>
121 /// Sets the requested state for a package that the TestBA will return to the engine during plan.
122 /// </summary>
123 /// <param name="packageId">Package identity.</param>
124 /// <param name="state">State to request.</param>
125 public void SetPackageRequestedState(string packageId, RequestState state)
126 {
127 this.SetPackageState(packageId, "Requested", state.ToString());
128 }
129
130 /// <summary>
131 /// Sets the requested state for a package that the TestBA will return to the engine during plan.
132 /// </summary>
133 /// <param name="packageId">Package identity.</param>
134 /// <param name="state">State to request.</param>
135 public void SetPackageFeatureState(string packageId, string featureId, FeatureState state)
136 {
137 this.SetPackageState(packageId, String.Concat(featureId, "Requested"), state.ToString());
138 }
139
140 /// <summary>
141 /// Sets the number of times to re-run the Detect phase.
142 /// </summary>
143 /// <param name="state">Number of times to run Detect (after the first, normal, Detect).</param>
144 public void SetRedetectCount(int redetectCount)
145 {
146 this.SetPackageState(null, "RedetectCount", redetectCount.ToString());
147 }
148
149 /// <summary>
150 /// Resets the state for a package that the TestBA will return to the engine during plan.
151 /// </summary>
152 /// <param name="packageId">Package identity.</param>
153 public void ResetPackageStates(string packageId)
154 {
155 var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty);
156 Registry.LocalMachine.DeleteSubKey(key);
157 }
158
159 public void SetVerifyArguments(string verifyArguments)
160 {
161 this.SetBurnTestValue("VerifyArguments", verifyArguments);
162
163 }
164
165 private void SetPackageState(string packageId, string name, string value)
166 {
167 var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty);
168 using (var packageKey = Registry.LocalMachine.CreateSubKey(key))
169 {
170 if (String.IsNullOrEmpty(value))
171 {
172 packageKey.DeleteValue(name, false);
173 }
174 else
175 {
176 packageKey.SetValue(name, value);
177 }
178 }
179 }
180
181 public void Dispose()
182 {
183 Registry.LocalMachine.DeleteSubKeyTree($@"{this.BaseRegKeyPath}\{this.TestGroupName}", false);
184 Registry.LocalMachine.DeleteSubKeyTree($@"{this.BaseRegKeyPath}\TestBAControl", false);
185 }
186 }
187}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/UpdateBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/UpdateBundleTests.cs
new file mode 100644
index 00000000..9fcd428b
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/UpdateBundleTests.cs
@@ -0,0 +1,245 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.IO;
9 using Xunit;
10 using Xunit.Abstractions;
11
12 public class UpdateBundleTests : BurnE2ETests
13 {
14 public UpdateBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
15
16 [Fact]
17 public void CanLaunchUpdateBundleFromLocalSourceInsteadOfInstall()
18 {
19 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
20 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
21 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
22 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
23
24 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\"");
25
26 packageAv1.VerifyInstalled(false);
27 packageAv2.VerifyInstalled(false);
28
29 // Install the v2 bundle by getting v1 to launch it as an update bundle.
30 bundleAv1.Install(arguments: updateBundleSwitch);
31 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
32 bundleAv2.VerifyRegisteredAndInPackageCache();
33
34 packageAv1.VerifyInstalled(false);
35 packageAv2.VerifyInstalled(true);
36
37 bundleAv2.Uninstall();
38 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
39 packageAv2.VerifyInstalled(false);
40 }
41
42 [Fact]
43 public void CanLaunchUpdateBundleFromLocalSourceInsteadOfModify()
44 {
45 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
46 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
47 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
48 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
49
50 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\"");
51
52 packageAv1.VerifyInstalled(false);
53 packageAv2.VerifyInstalled(false);
54
55 bundleAv1.Install();
56 bundleAv1.VerifyRegisteredAndInPackageCache();
57
58 packageAv1.VerifyInstalled(true);
59 packageAv2.VerifyInstalled(false);
60
61 // Install the v2 bundle by getting v1 to launch it as an update bundle.
62 bundleAv1.Modify(arguments: updateBundleSwitch);
63 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
64 bundleAv2.VerifyRegisteredAndInPackageCache();
65
66 packageAv1.VerifyInstalled(false);
67 packageAv2.VerifyInstalled(true);
68
69 bundleAv2.Uninstall();
70 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
71 packageAv2.VerifyInstalled(false);
72 }
73
74 [Fact]
75 public void ForwardsArgumentsToUpdateBundle()
76 {
77 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
78 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
79 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
80 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
81 var testBAController = this.CreateTestBAController();
82
83 const string verifyArguments = "these arguments should exist";
84 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\" ", verifyArguments);
85
86 testBAController.SetVerifyArguments(verifyArguments);
87
88 packageAv1.VerifyInstalled(false);
89 packageAv2.VerifyInstalled(false);
90
91 // Install the v2 bundle by getting v1 to launch it as an update bundle.
92 bundleAv1.Install(arguments: updateBundleSwitch);
93 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
94 bundleAv2.VerifyRegisteredAndInPackageCache();
95
96 packageAv1.VerifyInstalled(false);
97 packageAv2.VerifyInstalled(true);
98
99 // Attempt to uninstall bundleA2 without the verify arguments passed and expect failure code.
100 bundleAv2.Uninstall(expectedExitCode: -1);
101
102 // Remove the required arguments and uninstall again.
103 testBAController.SetVerifyArguments(null);
104 bundleAv2.Uninstall();
105 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
106 packageAv2.VerifyInstalled(false);
107 }
108
109 // Installs bundle Bv1.0 then tries to update to latest version during modify (but no server exists).
110 [Fact]
111 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenServerIsntResponsive()
112 {
113 var packageB = this.CreatePackageInstaller("PackageBv1");
114 var bundleB = this.CreateBundleInstaller("BundleBv1");
115
116 packageB.VerifyInstalled(false);
117
118 bundleB.Install();
119 bundleB.VerifyRegisteredAndInPackageCache();
120
121 packageB.VerifyInstalled(true);
122
123 // Run the v1 bundle requesting an update bundle.
124 bundleB.Modify(arguments: "-checkupdate");
125 bundleB.VerifyRegisteredAndInPackageCache();
126
127 // Verify nothing changed.
128 packageB.VerifyInstalled(true);
129
130 bundleB.Uninstall();
131 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
132 packageB.VerifyInstalled(false);
133 }
134
135 // Installs bundle Bv1.0 then tries to update to latest version during modify (server exists, no feed).
136 [Fact]
137 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenFeedIsMissing()
138 {
139 var packageB = this.CreatePackageInstaller("PackageBv1");
140 var bundleB = this.CreateBundleInstaller("BundleBv1");
141 var webServer = this.CreateWebServer();
142
143 webServer.Start();
144
145 packageB.VerifyInstalled(false);
146
147 bundleB.Install();
148 bundleB.VerifyRegisteredAndInPackageCache();
149
150 packageB.VerifyInstalled(true);
151
152 // Run the v1 bundle requesting an update bundle.
153 bundleB.Modify(arguments: "-checkupdate");
154 bundleB.VerifyRegisteredAndInPackageCache();
155
156 // Verify nothing changed.
157 packageB.VerifyInstalled(true);
158
159 bundleB.Uninstall();
160 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
161 packageB.VerifyInstalled(false);
162 }
163
164 // Installs bundle Bv1.0 then tries to update to latest version during modify (server exists, v1.0 feed).
165 [Fact]
166 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenAlreadyLatestVersion()
167 {
168 var packageB = this.CreatePackageInstaller("PackageBv1");
169 var bundleB = this.CreateBundleInstaller("BundleBv1");
170 var webServer = this.CreateWebServer();
171
172 webServer.AddFiles(new Dictionary<string, string>
173 {
174 { "/BundleB/feed", Path.Combine(this.TestContext.TestDataFolder, "FeedBv1.0.xml") },
175 });
176 webServer.Start();
177
178 packageB.VerifyInstalled(false);
179
180 bundleB.Install();
181 bundleB.VerifyRegisteredAndInPackageCache();
182
183 packageB.VerifyInstalled(true);
184
185 // Run the v1 bundle requesting an update bundle.
186 bundleB.Modify(arguments: "-checkupdate");
187 bundleB.VerifyRegisteredAndInPackageCache();
188
189 // Verify nothing changed.
190 packageB.VerifyInstalled(true);
191
192 bundleB.Uninstall();
193 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
194 packageB.VerifyInstalled(false);
195 }
196
197 // Installs bundle Bv1.0 then does an update to bundle Bv2.0 during modify (server exists, v2.0 feed).
198 [Fact]
199 public void CanLaunchUpdateBundleFromDownloadInsteadOfModify()
200 {
201 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
202 var packageBv2 = this.CreatePackageInstaller("PackageBv2");
203 var bundleBv1 = this.CreateBundleInstaller("BundleBv1");
204 var bundleBv2 = this.CreateBundleInstaller("BundleBv2");
205 var webServer = this.CreateWebServer();
206
207 webServer.AddFiles(new Dictionary<string, string>
208 {
209 { "/BundleB/feed", Path.Combine(this.TestContext.TestDataFolder, "FeedBv2.0.xml") },
210 { "/BundleB/2.0/BundleB.exe", bundleBv2.Bundle },
211 });
212 webServer.Start();
213
214 packageBv1.VerifyInstalled(false);
215 packageBv2.VerifyInstalled(false);
216
217 bundleBv1.Install();
218 bundleBv1.VerifyRegisteredAndInPackageCache();
219
220 packageBv1.VerifyInstalled(true);
221 packageBv2.VerifyInstalled(false);
222
223 // Run the v1 bundle requesting an update bundle.
224 bundleBv1.Modify(arguments: "-checkupdate");
225
226 // The modify -> update is asynchronous, so we need to wait until the real BundleB is done
227 var childBundles = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(bundleBv2.Bundle));
228 foreach (var childBundle in childBundles)
229 {
230 childBundle.WaitForExit();
231 }
232
233 bundleBv1.VerifyUnregisteredAndRemovedFromPackageCache();
234 bundleBv2.VerifyRegisteredAndInPackageCache();
235
236 packageBv1.VerifyInstalled(false);
237 packageBv2.VerifyInstalled(true);
238
239 bundleBv2.Uninstall();
240 bundleBv2.VerifyUnregisteredAndRemovedFromPackageCache();
241 packageBv1.VerifyInstalled(false);
242 packageBv2.VerifyInstalled(false);
243 }
244 }
245}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs
new file mode 100644
index 00000000..70c0c474
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs
@@ -0,0 +1,36 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.IO;
7 using WixTestTools;
8 using Xunit;
9 using Xunit.Abstractions;
10
11 public class UpgradeRelatedBundleTests : BurnE2ETests
12 {
13 public UpgradeRelatedBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
14
15 [Fact]
16 public void ReportsRelatedBundleMissingFromCache()
17 {
18 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
19 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
20 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
21 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
22
23 bundleAv1.Install();
24 bundleAv1.VerifyRegisteredAndInPackageCache();
25
26 bundleAv1.ManuallyUncache();
27
28 // Verify https://github.com/wixtoolset/issues/issues/4991
29 var bundleAv2InstallLogFilePath = bundleAv2.Install();
30 bundleAv2.VerifyRegisteredAndInPackageCache();
31
32 Assert.True(LogVerifier.MessageInLogFileRegex(bundleAv2InstallLogFilePath, @"OnDetectRelatedBundle\(\) - id: \{[0-9A-Za-z\-]{36}\}, missing from cache: True"));
33 Assert.True(LogVerifier.MessageInLogFileRegex(bundleAv2InstallLogFilePath, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Upgrade, scope: PerMachine, version: 1\.0\.0\.0, operation: MajorUpgrade, cached: No"));
34 }
35 }
36}
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs b/src/test/burn/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs
new file mode 100644
index 00000000..89825813
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs
@@ -0,0 +1,70 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using Microsoft.AspNetCore.Builder;
9 using Microsoft.AspNetCore.Hosting;
10 using Microsoft.Extensions.FileProviders;
11 using Microsoft.Extensions.FileProviders.Physical;
12 using Microsoft.Extensions.Hosting;
13 using Microsoft.Extensions.Primitives;
14
15 public class CoreOwinWebServer : IWebServer, IFileProvider
16 {
17 private Dictionary<string, string> PhysicalPathsByRelativeUrl { get; } = new Dictionary<string, string>();
18
19 private IHost WebHost { get; set; }
20
21 public void AddFiles(Dictionary<string, string> physicalPathsByRelativeUrl)
22 {
23 foreach (var kvp in physicalPathsByRelativeUrl)
24 {
25 this.PhysicalPathsByRelativeUrl.Add(kvp.Key, kvp.Value);
26 }
27 }
28
29 public void Start()
30 {
31 this.WebHost = Host.CreateDefaultBuilder()
32 .ConfigureWebHostDefaults(webBuilder =>
33 {
34 // Use localhost instead of * to avoid firewall issues.
35 webBuilder.UseUrls("http://localhost:9999");
36 webBuilder.Configure(appBuilder =>
37 {
38 appBuilder.UseStaticFiles(new StaticFileOptions
39 {
40 FileProvider = this,
41 RequestPath = "/e2e",
42 ServeUnknownFileTypes = true,
43 });
44 });
45 })
46 .Build();
47 this.WebHost.Start();
48 }
49
50 public void Dispose()
51 {
52 var waitTime = TimeSpan.FromSeconds(5);
53 this.WebHost?.StopAsync(waitTime).Wait(waitTime);
54 }
55
56 public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
57
58 public IFileInfo GetFileInfo(string subpath)
59 {
60 if (this.PhysicalPathsByRelativeUrl.TryGetValue(subpath, out var filepath))
61 {
62 return new PhysicalFileInfo(new FileInfo(filepath));
63 }
64
65 return new NotFoundFileInfo(subpath);
66 }
67
68 public IChangeToken Watch(string filter) => throw new NotImplementedException();
69 }
70} \ No newline at end of file
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj b/src/test/burn/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj
new file mode 100644
index 00000000..2aee1157
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj
@@ -0,0 +1,33 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netcoreapp3.1</TargetFramework>
7 <PlatformTarget>x64</PlatformTarget>
8 <RollForward>Major</RollForward>
9 </PropertyGroup>
10
11 <ItemGroup>
12 <Content Include="runtests.cmd" CopyToOutputDirectory="PreserveNewest" />
13 </ItemGroup>
14
15 <ItemGroup>
16 <ProjectReference Include="..\WixTestTools\WixTestTools.csproj" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <PackageReference Include="Microsoft.AspNetCore.Owin" Version="3.1.13" />
21 <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
22 <PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
23 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.50" />
24 <PackageReference Include="WixToolset.Data" Version="4.0.218" />
25 <PackageReference Include="WixToolset.Mba.Core" Version="4.0.58" />
26 </ItemGroup>
27
28 <ItemGroup>
29 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
30 <PackageReference Include="xunit" Version="2.4.1" />
31 <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" PrivateAssets="All" />
32 </ItemGroup>
33</Project>
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/runtests.cmd b/src/test/burn/WixToolsetTest.BurnE2E/runtests.cmd
new file mode 100644
index 00000000..4c6dc8ee
--- /dev/null
+++ b/src/test/burn/WixToolsetTest.BurnE2E/runtests.cmd
@@ -0,0 +1,2 @@
1SET RuntimeTestsEnabled=true
2dotnet test WixToolsetTest.BurnE2E.dll -v normal \ No newline at end of file
diff --git a/src/test/burn/appveyor.cmd b/src/test/burn/appveyor.cmd
new file mode 100644
index 00000000..c0d965e5
--- /dev/null
+++ b/src/test/burn/appveyor.cmd
@@ -0,0 +1,11 @@
1@setlocal
2@pushd %~dp0
3@set _C=Release
4
5msbuild -p:Configuration=%_C% -warnaserror -Restore || exit /b
6msbuild -p:Configuration=%_C% src\TestData -Restore || exit /b
7
8dotnet test -c %_C% --no-build src\WixToolsetTest.BurnE2E || exit /b
9
10@popd
11@endlocal
diff --git a/src/test/burn/appveyor.yml b/src/test/burn/appveyor.yml
new file mode 100644
index 00000000..d12975dc
--- /dev/null
+++ b/src/test/burn/appveyor.yml
@@ -0,0 +1,27 @@
1# 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.
2
3
4image: Visual Studio 2019
5
6environment:
7 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8 DOTNET_CLI_TELEMETRY_OPTOUT: 1
9 NUGET_XMLDOC_MODE: skip
10 RuntimeTestsEnabled: true
11
12
13install:
14 - reg add HKLM\Software\Policies\Microsoft\Windows\Installer /t REG_SZ /v Logging /d voicewarmupx /f
15 - reg add HKLM\Software\WOW6432Node\Policies\Microsoft\Windows\Installer /t REG_SZ /v Logging /d voicewarmupx /f
16
17build_script:
18 - appveyor.cmd
19
20test: off
21
22skip_branch_with_pr: true
23skip_tags: true
24
25on_finish:
26 - ps: 7z a ('logs_' + (Get-Date).tostring("yyyyMMddHHmmss") + '.zip') $env:TEMP\*.log $env:TEMP\..\*.log
27 - ps: Push-AppveyorArtifact logs_*.zip
diff --git a/src/test/burn/global.json b/src/test/burn/global.json
new file mode 100644
index 00000000..697f5687
--- /dev/null
+++ b/src/test/burn/global.json
@@ -0,0 +1,8 @@
1{
2 "msbuild-sdks": {
3 "WixToolset.Sdk": "4.0.0-build-0213"
4 },
5 "sdk": {
6 "allowPrerelease": false
7 }
8}
diff --git a/src/test/burn/nuget.config b/src/test/burn/nuget.config
new file mode 100644
index 00000000..9187a22e
--- /dev/null
+++ b/src/test/burn/nuget.config
@@ -0,0 +1,16 @@
1<?xml version="1.0" encoding="utf-8"?>
2<configuration>
3 <packageSources>
4 <clear />
5 <add key="wixtoolset-balutil" value="https://ci.appveyor.com/nuget/wixtoolset-balutil" />
6 <add key="wixtoolset-bal-wixext" value="https://ci.appveyor.com/nuget/wixtoolset-bal-wixext" />
7 <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" />
8 <add key="wixtoolset-dependency-wixext" value="https://ci.appveyor.com/nuget/wixtoolset-dependency-wixext" />
9 <add key="wixtoolset-dtf" value="https://ci.appveyor.com/nuget/wixtoolset-dtf" />
10 <add key="wixtoolset-netfx-wixext" value="https://ci.appveyor.com/nuget/wixtoolset-netfx-wixext" />
11 <add key="wixtoolset-tools" value="https://ci.appveyor.com/nuget/wixtoolset-tools" />
12 <add key="wixtoolset-util-wixext" value="https://ci.appveyor.com/nuget/wixtoolset-util-wixext" />
13 <add key="wixbuildtools" value="https://ci.appveyor.com/nuget/wixbuildtools" />
14 <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
15 </packageSources>
16</configuration> \ No newline at end of file