diff options
Diffstat (limited to 'src/test')
12 files changed, 439 insertions, 7 deletions
diff --git a/src/test/burn/Directory.wixproj.targets b/src/test/burn/Directory.wixproj.targets index 17a46e2a..4037e865 100644 --- a/src/test/burn/Directory.wixproj.targets +++ b/src/test/burn/Directory.wixproj.targets | |||
@@ -7,6 +7,7 @@ | |||
7 | <WebServerBaseUrl Condition=" '$(WebServerBaseUrl)' == '' ">http://localhost:9999/e2e/</WebServerBaseUrl> | 7 | <WebServerBaseUrl Condition=" '$(WebServerBaseUrl)' == '' ">http://localhost:9999/e2e/</WebServerBaseUrl> |
8 | <DefineConstants>TestGroupName=$(TestGroupName);PackageName=$(PackageName);BundleName=$(BundleName);WebServerBaseUrl=$(WebServerBaseUrl);$(DefineConstants)</DefineConstants> | 8 | <DefineConstants>TestGroupName=$(TestGroupName);PackageName=$(PackageName);BundleName=$(BundleName);WebServerBaseUrl=$(WebServerBaseUrl);$(DefineConstants)</DefineConstants> |
9 | <DefineConstants Condition=" '$(BA)' != '' ">BA=$(BA);$(DefineConstants)</DefineConstants> | 9 | <DefineConstants Condition=" '$(BA)' != '' ">BA=$(BA);$(DefineConstants)</DefineConstants> |
10 | <DefineConstants Condition=" '$(BundleLogDirectory)' != '' ">BundleLogDirectory=$(BundleLogDirectory);$(DefineConstants)</DefineConstants> | ||
10 | <DefineConstants Condition=" '$(CabPrefix)' != '' ">CabPrefix=$(CabPrefix);$(DefineConstants)</DefineConstants> | 11 | <DefineConstants Condition=" '$(CabPrefix)' != '' ">CabPrefix=$(CabPrefix);$(DefineConstants)</DefineConstants> |
11 | <DefineConstants Condition=" '$(IncludeSoftwareTag)' == 'true' ">SoftwareTag=1;$(DefineConstants)</DefineConstants> | 12 | <DefineConstants Condition=" '$(IncludeSoftwareTag)' == 'true' ">SoftwareTag=1;$(DefineConstants)</DefineConstants> |
12 | <DefineConstants Condition=" '$(ProductCode)' != '' ">ProductCode=$(ProductCode);$(DefineConstants)</DefineConstants> | 13 | <DefineConstants Condition=" '$(ProductCode)' != '' ">ProductCode=$(ProductCode);$(DefineConstants)</DefineConstants> |
diff --git a/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.wixproj b/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.wixproj new file mode 100644 index 00000000..3686200c --- /dev/null +++ b/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.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>{EFCF768F-1B06-4B68-9DE0-9244F8212D31}</UpgradeCode> | ||
6 | <BundleLogDirectory>[LocalAppDataFolder]Temp</BundleLogDirectory> | ||
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="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" /> | ||
14 | </ItemGroup> | ||
15 | <ItemGroup> | ||
16 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
17 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
18 | </ItemGroup> | ||
19 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.wxs b/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.wxs new file mode 100644 index 00000000..e3872eb1 --- /dev/null +++ b/src/test/burn/TestData/LongPathTests/NonCompressedBundle/NonCompressedBundle.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 Compressed="no" Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" /> | ||
8 | </PackageGroup> | ||
9 | </Fragment> | ||
10 | </Wix> | ||
diff --git a/src/test/burn/TestData/LongPathTests/PackageA/PackageA.wixproj b/src/test/burn/TestData/LongPathTests/PackageA/PackageA.wixproj new file mode 100644 index 00000000..798452e7 --- /dev/null +++ b/src/test/burn/TestData/LongPathTests/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>{4DC05A2A-382D-4E7D-B6DA-163908396373}</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/Templates/Bundle.wxs b/src/test/burn/TestData/Templates/Bundle.wxs index b211d9c3..612e67f5 100644 --- a/src/test/burn/TestData/Templates/Bundle.wxs +++ b/src/test/burn/TestData/Templates/Bundle.wxs | |||
@@ -3,10 +3,13 @@ | |||
3 | <?ifndef Version?> | 3 | <?ifndef Version?> |
4 | <?define Version = 1.0.0.0?> | 4 | <?define Version = 1.0.0.0?> |
5 | <?endif?> | 5 | <?endif?> |
6 | <?ifndef BundleLogDirectory?> | ||
7 | <?define BundleLogDirectory = .?> | ||
8 | <?endif?> | ||
6 | 9 | ||
7 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | 10 | <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"> | 11 | <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes"> |
9 | <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" /> | 12 | <Log Prefix="$(var.BundleLogDirectory)\~$(var.TestGroupName)_$(var.BundleName)" /> |
10 | 13 | ||
11 | <Variable Name="TestGroupName" Value="$(var.TestGroupName)" /> | 14 | <Variable Name="TestGroupName" Value="$(var.TestGroupName)" /> |
12 | 15 | ||
diff --git a/src/test/burn/TestExe/Task.cs b/src/test/burn/TestExe/Task.cs index 59f774fb..0d283c6c 100644 --- a/src/test/burn/TestExe/Task.cs +++ b/src/test/burn/TestExe/Task.cs | |||
@@ -2,8 +2,10 @@ | |||
2 | 2 | ||
3 | using System; | 3 | using System; |
4 | using System.Collections.Generic; | 4 | using System.Collections.Generic; |
5 | using System.ComponentModel; | ||
5 | using System.Diagnostics; | 6 | using System.Diagnostics; |
6 | using System.IO; | 7 | using System.IO; |
8 | using System.Runtime.InteropServices; | ||
7 | using Microsoft.Win32; | 9 | using Microsoft.Win32; |
8 | 10 | ||
9 | namespace TestExe | 11 | namespace TestExe |
@@ -151,6 +153,67 @@ namespace TestExe | |||
151 | } | 153 | } |
152 | } | 154 | } |
153 | 155 | ||
156 | public class DeleteManifestsTask : Task | ||
157 | { | ||
158 | public DeleteManifestsTask(string Data) : base(Data) { } | ||
159 | |||
160 | public override void RunTask() | ||
161 | { | ||
162 | string filePath = System.Environment.ExpandEnvironmentVariables(this.data); | ||
163 | IntPtr type = new IntPtr(24); //RT_MANIFEST | ||
164 | IntPtr name = new IntPtr(1); //CREATEPROCESS_MANIFEST_RESOURCE_ID | ||
165 | DeleteResource(filePath, type, name, 1033); | ||
166 | } | ||
167 | |||
168 | private static void DeleteResource(string filePath, IntPtr type, IntPtr name, ushort language, bool throwOnError = false) | ||
169 | { | ||
170 | bool discard = true; | ||
171 | IntPtr handle = BeginUpdateResourceW(filePath, false); | ||
172 | try | ||
173 | { | ||
174 | if (handle == IntPtr.Zero) | ||
175 | { | ||
176 | throw new Win32Exception(); | ||
177 | } | ||
178 | |||
179 | if (!UpdateResourceW(handle, type, name, language, IntPtr.Zero, 0)) | ||
180 | { | ||
181 | throw new Win32Exception(); | ||
182 | } | ||
183 | |||
184 | discard = false; | ||
185 | } | ||
186 | catch | ||
187 | { | ||
188 | if (throwOnError) | ||
189 | { | ||
190 | throw; | ||
191 | } | ||
192 | } | ||
193 | finally | ||
194 | { | ||
195 | if (handle != IntPtr.Zero) | ||
196 | { | ||
197 | if (!EndUpdateResourceW(handle, discard) && throwOnError) | ||
198 | { | ||
199 | throw new Win32Exception(); | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | |||
205 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
206 | private extern static IntPtr BeginUpdateResourceW(string fileName, [MarshalAs(UnmanagedType.Bool)] bool deleteExistingResources); | ||
207 | |||
208 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
209 | [return: MarshalAs(UnmanagedType.Bool)] | ||
210 | private extern static bool UpdateResourceW(IntPtr hUpdate, IntPtr type, IntPtr name, ushort language, IntPtr pData, uint cb); | ||
211 | |||
212 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
213 | [return: MarshalAs(UnmanagedType.Bool)] | ||
214 | private extern static bool EndUpdateResourceW(IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)] bool discard); | ||
215 | } | ||
216 | |||
154 | public class TaskParser | 217 | public class TaskParser |
155 | { | 218 | { |
156 | 219 | ||
@@ -197,6 +260,10 @@ namespace TestExe | |||
197 | t = new FileExistsTask(args[i + 1]); | 260 | t = new FileExistsTask(args[i + 1]); |
198 | tasks.Add(t); | 261 | tasks.Add(t); |
199 | break; | 262 | break; |
263 | case "/dm": | ||
264 | t = new DeleteManifestsTask(args[i + 1]); | ||
265 | tasks.Add(t); | ||
266 | break; | ||
200 | #if NET35 | 267 | #if NET35 |
201 | case "/pinfo": | 268 | case "/pinfo": |
202 | t = new ProcessInfoTask(args[i + 1]); | 269 | t = new ProcessInfoTask(args[i + 1]); |
diff --git a/src/test/burn/WixTestTools/BundleInstaller.cs b/src/test/burn/WixTestTools/BundleInstaller.cs index 5551d3c0..0f2cfa8f 100644 --- a/src/test/burn/WixTestTools/BundleInstaller.cs +++ b/src/test/burn/WixTestTools/BundleInstaller.cs | |||
@@ -28,6 +28,8 @@ namespace WixTestTools | |||
28 | 28 | ||
29 | public int? AlternateExitCode { get; set; } | 29 | public int? AlternateExitCode { get; set; } |
30 | 30 | ||
31 | public string LogDirectory { get; set; } | ||
32 | |||
31 | public int? LastExitCode { get; set; } | 33 | public int? LastExitCode { get; set; } |
32 | 34 | ||
33 | /// <summary> | 35 | /// <summary> |
@@ -194,7 +196,7 @@ namespace WixTestTools | |||
194 | sb.Append(" -quiet"); | 196 | sb.Append(" -quiet"); |
195 | 197 | ||
196 | // Generate the log file name. | 198 | // Generate the log file name. |
197 | 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)); | 199 | string logFile = Path.Combine(this.LogDirectory ?? Path.GetTempPath(), String.Format("{0}_{1}_{2:yyyyMMddhhmmss}_{4}_{3}.log", this.TestGroupName, this.TestName, DateTime.UtcNow, Path.GetFileNameWithoutExtension(this.Bundle), mode)); |
198 | sb.AppendFormat(" -log \"{0}\"", logFile); | 200 | sb.AppendFormat(" -log \"{0}\"", logFile); |
199 | 201 | ||
200 | // Set operation. | 202 | // Set operation. |
diff --git a/src/test/burn/WixTestTools/MSIExec.cs b/src/test/burn/WixTestTools/MSIExec.cs index a10a48d6..5f57da7b 100644 --- a/src/test/burn/WixTestTools/MSIExec.cs +++ b/src/test/burn/WixTestTools/MSIExec.cs | |||
@@ -110,7 +110,7 @@ namespace WixTestTools | |||
110 | this.NoRestart = true; | 110 | this.NoRestart = true; |
111 | this.ForceRestart = false; | 111 | this.ForceRestart = false; |
112 | this.PromptRestart = false; | 112 | this.PromptRestart = false; |
113 | this.LogFile = string.Empty; | 113 | this.LogFile = String.Empty; |
114 | this.LoggingOptions = MSIExecLoggingOptions.VOICEWARMUP; | 114 | this.LoggingOptions = MSIExecLoggingOptions.VOICEWARMUP; |
115 | this.OtherArguments = String.Empty; | 115 | this.OtherArguments = String.Empty; |
116 | } | 116 | } |
@@ -230,14 +230,14 @@ namespace WixTestTools | |||
230 | } | 230 | } |
231 | 231 | ||
232 | // logfile and logging options | 232 | // logfile and logging options |
233 | if (0 != loggingOptionsString.Length || !string.IsNullOrEmpty(this.LogFile)) | 233 | if (0 != loggingOptionsString.Length || !String.IsNullOrEmpty(this.LogFile)) |
234 | { | 234 | { |
235 | arguments.Append(" /l"); | 235 | arguments.Append(" /l"); |
236 | if (0 != loggingOptionsString.Length) | 236 | if (0 != loggingOptionsString.Length) |
237 | { | 237 | { |
238 | arguments.AppendFormat("{0} ", loggingOptionsString); | 238 | arguments.AppendFormat("{0} ", loggingOptionsString); |
239 | } | 239 | } |
240 | if (!string.IsNullOrEmpty(this.LogFile)) | 240 | if (!String.IsNullOrEmpty(this.LogFile)) |
241 | { | 241 | { |
242 | arguments.AppendFormat(" \"{0}\" ", this.LogFile); | 242 | arguments.AppendFormat(" \"{0}\" ", this.LogFile); |
243 | } | 243 | } |
@@ -268,7 +268,7 @@ namespace WixTestTools | |||
268 | }; | 268 | }; |
269 | 269 | ||
270 | // product | 270 | // product |
271 | if (!string.IsNullOrEmpty(this.Product)) | 271 | if (!String.IsNullOrEmpty(this.Product)) |
272 | { | 272 | { |
273 | arguments.AppendFormat(" \"{0}\" ", this.Product); | 273 | arguments.AppendFormat(" \"{0}\" ", this.Product); |
274 | } | 274 | } |
@@ -311,6 +311,12 @@ namespace WixTestTools | |||
311 | ERROR_CALL_NOT_IMPLEMENTED = 120, | 311 | ERROR_CALL_NOT_IMPLEMENTED = 120, |
312 | 312 | ||
313 | /// <summary> | 313 | /// <summary> |
314 | /// ERROR_FILENAME_EXCED_RANGE 206 | ||
315 | /// The filename or extension is too long. | ||
316 | /// </summary> | ||
317 | ERROR_FILENAME_EXCED_RANGE = 206, | ||
318 | |||
319 | /// <summary> | ||
314 | /// ERROR_APPHELP_BLOCK 1259 | 320 | /// ERROR_APPHELP_BLOCK 1259 |
315 | /// If Windows Installer determines a product may be incompatible with the current operating system, | 321 | /// 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. | 322 | /// it displays a dialog box informing the user and asking whether to try to install anyway. |
diff --git a/src/test/burn/WixTestTools/TestTool.cs b/src/test/burn/WixTestTools/TestTool.cs index eb77c75b..79e7004c 100644 --- a/src/test/burn/WixTestTools/TestTool.cs +++ b/src/test/burn/WixTestTools/TestTool.cs | |||
@@ -229,7 +229,7 @@ namespace WixTestTools | |||
229 | returnValue.AppendLine("Tool run result:"); | 229 | returnValue.AppendLine("Tool run result:"); |
230 | returnValue.AppendLine("----------------"); | 230 | returnValue.AppendLine("----------------"); |
231 | returnValue.AppendLine("Command:"); | 231 | returnValue.AppendLine("Command:"); |
232 | returnValue.AppendLine($"\"{result.StartInfo.FileName}\" {result.StartInfo.Arguments}"); | 232 | returnValue.AppendLine($"\"{result.FileName}\" {result.Arguments}"); |
233 | returnValue.AppendLine(); | 233 | returnValue.AppendLine(); |
234 | returnValue.AppendLine("Standard Output:"); | 234 | returnValue.AppendLine("Standard Output:"); |
235 | foreach (var line in result.StandardOutput ?? new string[0]) | 235 | foreach (var line in result.StandardOutput ?? new string[0]) |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/LongPathTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/LongPathTests.cs new file mode 100644 index 00000000..ba793d7a --- /dev/null +++ b/src/test/burn/WixToolsetTest.BurnE2E/LongPathTests.cs | |||
@@ -0,0 +1,298 @@ | |||
1 | // Copyright (c) .NET Foundation 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 | namespace WixToolsetTest.BurnE2E | ||
4 | { | ||
5 | using System; | ||
6 | using System.ComponentModel; | ||
7 | using System.IO; | ||
8 | using System.Runtime.InteropServices; | ||
9 | using Microsoft.Win32; | ||
10 | using WixBuildTools.TestSupport; | ||
11 | using WixTestTools; | ||
12 | using WixToolset.Mba.Core; | ||
13 | using Xunit; | ||
14 | using Xunit.Abstractions; | ||
15 | |||
16 | public class LongPathTests : BurnE2ETests | ||
17 | { | ||
18 | public LongPathTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } | ||
19 | |||
20 | [RuntimeFact] | ||
21 | public void CanInstallAndUninstallSimpleBundle_x86_wixstdba() | ||
22 | { | ||
23 | this.CanInstallAndUninstallSimpleBundle("PackageA", "BundleA"); | ||
24 | } | ||
25 | |||
26 | [RuntimeFact] | ||
27 | public void CanInstallAndUninstallSimpleBundle_x86_testba() | ||
28 | { | ||
29 | this.CanInstallAndUninstallSimpleBundle("PackageA", "BundleB"); | ||
30 | } | ||
31 | |||
32 | [RuntimeFact] | ||
33 | public void CanInstallAndUninstallSimpleBundle_x86_dnctestba() | ||
34 | { | ||
35 | this.CanInstallAndUninstallSimpleBundle("PackageA", "BundleC"); | ||
36 | } | ||
37 | |||
38 | [RuntimeFact] | ||
39 | public void CanInstallAndUninstallSimpleBundle_x86_wixba() | ||
40 | { | ||
41 | this.CanInstallAndUninstallSimpleBundle("PackageA", "BundleD"); | ||
42 | } | ||
43 | |||
44 | [RuntimeFact] | ||
45 | public void CanInstallAndUninstallSimpleBundle_x64_wixstdba() | ||
46 | { | ||
47 | this.CanInstallAndUninstallSimpleBundle("PackageA_x64", "BundleA_x64"); | ||
48 | } | ||
49 | |||
50 | [RuntimeFact] | ||
51 | public void CanInstallAndUninstallSimplePerUserBundle_x64_wixstdba() | ||
52 | { | ||
53 | this.CanInstallAndUninstallSimpleBundle("PackageApu_x64", "BundleApu_x64", "PackagePerUser.wxs", unchecked((int)0xc0000005)); | ||
54 | } | ||
55 | |||
56 | [RuntimeFact] | ||
57 | public void CanInstallAndUninstallSimpleBundle_x64_testba() | ||
58 | { | ||
59 | this.CanInstallAndUninstallSimpleBundle("PackageA_x64", "BundleB_x64"); | ||
60 | } | ||
61 | |||
62 | [RuntimeFact] | ||
63 | public void CanInstallAndUninstallSimpleBundle_x64_dnctestba() | ||
64 | { | ||
65 | this.CanInstallAndUninstallSimpleBundle("PackageA_x64", "BundleC_x64"); | ||
66 | } | ||
67 | |||
68 | [RuntimeFact] | ||
69 | public void CanInstallAndUninstallSimpleBundle_x64_dncwixba() | ||
70 | { | ||
71 | this.CanInstallAndUninstallSimpleBundle("PackageA_x64", "BundleD_x64"); | ||
72 | } | ||
73 | |||
74 | private void CanInstallAndUninstallSimpleBundle(string packageName, string bundleName, string fileName = "Package.wxs", int? alternateExitCode = null) | ||
75 | { | ||
76 | var package = this.CreatePackageInstaller(Path.Combine("..", "BasicFunctionalityTests", packageName)); | ||
77 | |||
78 | var bundle = this.CreateBundleInstaller(Path.Combine("..", "BasicFunctionalityTests", bundleName)); | ||
79 | bundle.AlternateExitCode = alternateExitCode; | ||
80 | |||
81 | using var dfs = new DisposableFileSystem(); | ||
82 | var baseFolder = GetLongPath(dfs.GetFolder()); | ||
83 | |||
84 | var packageSourceCodeInstalled = package.GetInstalledFilePath(fileName); | ||
85 | |||
86 | // Source file should *not* be installed | ||
87 | Assert.False(File.Exists(packageSourceCodeInstalled), $"{packageName} payload should not be there on test start: {packageSourceCodeInstalled}"); | ||
88 | |||
89 | var bundleFileInfo = new FileInfo(bundle.Bundle); | ||
90 | var bundleCopiedPath = Path.Combine(baseFolder, bundleFileInfo.Name); | ||
91 | bundleFileInfo.CopyTo(bundleCopiedPath); | ||
92 | |||
93 | bundle.Install(bundleCopiedPath); | ||
94 | bundle.VerifyRegisteredAndInPackageCache(); | ||
95 | |||
96 | // Source file should be installed | ||
97 | Assert.True(File.Exists(packageSourceCodeInstalled), $"Should have found {packageName} payload installed at: {packageSourceCodeInstalled}"); | ||
98 | |||
99 | if (alternateExitCode == bundle.LastExitCode) | ||
100 | { | ||
101 | WixAssert.Skip($"Install exited with {bundle.LastExitCode}"); | ||
102 | } | ||
103 | |||
104 | bundle.Uninstall(bundleCopiedPath); | ||
105 | |||
106 | // Source file should *not* be installed | ||
107 | Assert.False(File.Exists(packageSourceCodeInstalled), $"{packageName} payload should have been removed by uninstall from: {packageSourceCodeInstalled}"); | ||
108 | |||
109 | bundle.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
110 | |||
111 | if (alternateExitCode == bundle.LastExitCode) | ||
112 | { | ||
113 | WixAssert.Skip($"Uninstall exited with {bundle.LastExitCode}"); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | [RuntimeFact] | ||
118 | public void CanLayoutNonCompressedBundleToLongPath() | ||
119 | { | ||
120 | var nonCompressedBundle = this.CreateBundleInstaller("NonCompressedBundle"); | ||
121 | var testBAController = this.CreateTestBAController(); | ||
122 | |||
123 | testBAController.SetPackageRequestedState("NetFx48Web", RequestState.None); | ||
124 | |||
125 | using var dfs = new DisposableFileSystem(); | ||
126 | var layoutDirectory = GetLongPath(dfs.GetFolder()); | ||
127 | |||
128 | nonCompressedBundle.Layout(layoutDirectory); | ||
129 | nonCompressedBundle.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
130 | |||
131 | Assert.True(File.Exists(Path.Combine(layoutDirectory, "NonCompressedBundle.exe"))); | ||
132 | Assert.True(File.Exists(Path.Combine(layoutDirectory, "PackageA.msi"))); | ||
133 | Assert.True(File.Exists(Path.Combine(layoutDirectory, "1a.cab"))); | ||
134 | Assert.False(File.Exists(Path.Combine(layoutDirectory, @"redist\ndp48-web.exe"))); | ||
135 | } | ||
136 | |||
137 | [RuntimeFact] | ||
138 | public void CanInstallNonCompressedBundleWithLongTempPath() | ||
139 | { | ||
140 | this.InstallNonCompressedBundle(longTemp: true, useOriginalTempForLog: true); | ||
141 | } | ||
142 | |||
143 | [RuntimeFact] | ||
144 | public void CannotInstallNonCompressedBundleWithLongPackageCachePath() | ||
145 | { | ||
146 | var installLogPath = this.InstallNonCompressedBundle((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE, longPackageCache: true); | ||
147 | Assert.True(LogVerifier.MessageInLogFile(installLogPath, @"Error 0x80070643: Failed to install MSI package")); | ||
148 | } | ||
149 | |||
150 | [RuntimeFact] | ||
151 | public void CannotInstallNonCompressedBundleWithLongWorkingPath() | ||
152 | { | ||
153 | var installLogPath = this.InstallNonCompressedBundle((int)MSIExec.MSIExecReturnCode.ERROR_FILENAME_EXCED_RANGE | unchecked((int)0x80070000), longWorkingPath: true); | ||
154 | Assert.True(LogVerifier.MessageInLogFile(installLogPath, @"Error 0x800700ce: Failed to load BA DLL")); | ||
155 | } | ||
156 | |||
157 | public string InstallNonCompressedBundle(int expectedExitCode = 0, bool longTemp = false, bool useOriginalTempForLog = false, bool longWorkingPath = false, bool longPackageCache = false, int? alternateExitCode = null) | ||
158 | { | ||
159 | var deletePolicyKey = false; | ||
160 | string originalEngineWorkingDirectoryValue = null; | ||
161 | string originalPackageCacheValue = null; | ||
162 | var originalTemp = Environment.GetEnvironmentVariable("TMP"); | ||
163 | var packageA = this.CreatePackageInstaller("PackageA"); | ||
164 | var nonCompressedBundle = this.CreateBundleInstaller("NonCompressedBundle"); | ||
165 | var policyPath = nonCompressedBundle.GetFullBurnPolicyRegistryPath(); | ||
166 | string installLogPath = null; | ||
167 | |||
168 | try | ||
169 | { | ||
170 | using var dfs = new DisposableFileSystem(); | ||
171 | var originalBaseFolder = dfs.GetFolder(); | ||
172 | var baseFolder = GetLongPath(originalBaseFolder); | ||
173 | var sourceFolder = Path.Combine(baseFolder, "source"); | ||
174 | var workingFolder = Path.Combine(baseFolder, "working"); | ||
175 | var tempFolder = Path.Combine(originalBaseFolder, new string('d', 260 - originalBaseFolder.Length - 2)); | ||
176 | var packageCacheFolder = Path.Combine(baseFolder, "package cache"); | ||
177 | |||
178 | var copyResult = TestDataFolderFileSystem.RobocopyFolder(this.TestContext.TestDataFolder, sourceFolder); | ||
179 | Assert.True(copyResult.ExitCode >= 0 && copyResult.ExitCode < 8, $"Exit code: {copyResult.ExitCode}\r\nOutput: {String.Join("\r\n", copyResult.StandardOutput)}\r\nError: {String.Join("\r\n", copyResult.StandardError)}"); | ||
180 | |||
181 | var bundleFileInfo = new FileInfo(nonCompressedBundle.Bundle); | ||
182 | var bundleCopiedPath = Path.Combine(sourceFolder, bundleFileInfo.Name); | ||
183 | |||
184 | var policyKey = Registry.LocalMachine.OpenSubKey(policyPath, writable: true); | ||
185 | if (policyKey == null) | ||
186 | { | ||
187 | policyKey = Registry.LocalMachine.CreateSubKey(policyPath, writable: true); | ||
188 | deletePolicyKey = true; | ||
189 | } | ||
190 | |||
191 | using (policyKey) | ||
192 | { | ||
193 | originalEngineWorkingDirectoryValue = policyKey.GetValue("EngineWorkingDirectory") as string; | ||
194 | originalPackageCacheValue = policyKey.GetValue("PackageCache") as string; | ||
195 | |||
196 | if (longWorkingPath) | ||
197 | { | ||
198 | policyKey.SetValue("EngineWorkingDirectory", workingFolder); | ||
199 | } | ||
200 | |||
201 | if (longPackageCache) | ||
202 | { | ||
203 | policyKey.SetValue("PackageCache", packageCacheFolder); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | if (longTemp) | ||
208 | { | ||
209 | Environment.SetEnvironmentVariable("TMP", tempFolder); | ||
210 | |||
211 | if (useOriginalTempForLog) | ||
212 | { | ||
213 | nonCompressedBundle.LogDirectory = originalTemp; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | try | ||
218 | { | ||
219 | nonCompressedBundle.AlternateExitCode = alternateExitCode; | ||
220 | installLogPath = nonCompressedBundle.Install(bundleCopiedPath, expectedExitCode); | ||
221 | |||
222 | if (alternateExitCode == nonCompressedBundle.LastExitCode) | ||
223 | { | ||
224 | WixAssert.Skip($"Install exited with {nonCompressedBundle.LastExitCode}"); | ||
225 | } | ||
226 | } | ||
227 | finally | ||
228 | { | ||
229 | TestDataFolderFileSystem.RobocopyFolder(tempFolder, originalTemp); | ||
230 | } | ||
231 | |||
232 | installLogPath = Path.Combine(originalTemp, Path.GetFileName(installLogPath)); | ||
233 | |||
234 | if (expectedExitCode == 0) | ||
235 | { | ||
236 | var registration = nonCompressedBundle.VerifyRegisteredAndInPackageCache(); | ||
237 | packageA.VerifyInstalled(true); | ||
238 | |||
239 | nonCompressedBundle.Uninstall(registration.CachePath); | ||
240 | |||
241 | if (alternateExitCode == nonCompressedBundle.LastExitCode) | ||
242 | { | ||
243 | WixAssert.Skip($"Uninstall exited with {nonCompressedBundle.LastExitCode}"); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | nonCompressedBundle.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
248 | packageA.VerifyInstalled(false); | ||
249 | |||
250 | return installLogPath; | ||
251 | } | ||
252 | finally | ||
253 | { | ||
254 | Environment.SetEnvironmentVariable("TMP", originalTemp); | ||
255 | |||
256 | if (deletePolicyKey) | ||
257 | { | ||
258 | Registry.LocalMachine.DeleteSubKeyTree(policyPath); | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | using (var policyKey = Registry.LocalMachine.OpenSubKey(policyPath, writable: true)) | ||
263 | { | ||
264 | policyKey?.SetValue("EngineWorkingDirectory", originalEngineWorkingDirectoryValue); | ||
265 | policyKey?.SetValue("PackageCache", originalPackageCacheValue); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | private static string GetLongPath(string baseFolder) | ||
272 | { | ||
273 | Directory.CreateDirectory(baseFolder); | ||
274 | |||
275 | // Try to create a directory that is longer than MAX_PATH but without the \\?\ prefix to detect OS support for long paths. | ||
276 | // Need to PInvoke CreateDirectoryW directly because .NET methods will append the \\?\ prefix. | ||
277 | foreach (var c in new char[] { 'a', 'b', 'c' }) | ||
278 | { | ||
279 | baseFolder = Path.Combine(baseFolder, new string(c, 100)); | ||
280 | if (!CreateDirectoryW(baseFolder, IntPtr.Zero)) | ||
281 | { | ||
282 | int lastError = Marshal.GetLastWin32Error(); | ||
283 | if (lastError == 206) | ||
284 | { | ||
285 | WixAssert.Skip($"MAX_PATH is being enforced ({baseFolder})"); | ||
286 | } | ||
287 | throw new Win32Exception(lastError); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | return baseFolder; | ||
292 | } | ||
293 | |||
294 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
295 | [return: MarshalAs(UnmanagedType.Bool)] | ||
296 | private extern static bool CreateDirectoryW(string lpPathName, IntPtr lpSecurityAttributes); | ||
297 | } | ||
298 | } | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/testhost.longpathaware.manifest b/src/test/burn/WixToolsetTest.BurnE2E/testhost.longpathaware.manifest new file mode 100644 index 00000000..a56ab91a --- /dev/null +++ b/src/test/burn/WixToolsetTest.BurnE2E/testhost.longpathaware.manifest | |||
@@ -0,0 +1,11 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
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 | <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | ||
6 | <application xmlns="urn:schemas-microsoft-com:asm.v3"> | ||
7 | <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> | ||
8 | <ws2:longPathAware>true</ws2:longPathAware> | ||
9 | </windowsSettings> | ||
10 | </application> | ||
11 | </assembly> | ||
diff --git a/src/test/burn/test_burn.cmd b/src/test/burn/test_burn.cmd index 83401614..80467f39 100644 --- a/src/test/burn/test_burn.cmd +++ b/src/test/burn/test_burn.cmd | |||
@@ -9,11 +9,16 @@ | |||
9 | @if /i "%1"=="test" set RuntimeTestsEnabled=true | 9 | @if /i "%1"=="test" set RuntimeTestsEnabled=true |
10 | @if not "%1"=="" shift & goto parse_args | 10 | @if not "%1"=="" shift & goto parse_args |
11 | 11 | ||
12 | @set _B=%~dp0..\..\..\build\IntegrationBurn\%_C% | ||
13 | |||
12 | @echo Burn integration tests %_C% | 14 | @echo Burn integration tests %_C% |
13 | 15 | ||
14 | msbuild -t:Build -Restore -p:Configuration=%_C% -warnaserror -bl:%_L%\test_burn_build.binlog || exit /b | 16 | msbuild -t:Build -Restore -p:Configuration=%_C% -warnaserror -bl:%_L%\test_burn_build.binlog || exit /b |
15 | msbuild -t:Build -Restore TestData\TestData.proj -p:Configuration=%_C% -m -bl:%_L%\test_burn_data_build.binlog || exit /b | 17 | msbuild -t:Build -Restore TestData\TestData.proj -p:Configuration=%_C% -m -bl:%_L%\test_burn_data_build.binlog || exit /b |
16 | 18 | ||
19 | "%_B%\net35\win-x86\testexe.exe" /dm "%_B%\netcoreapp3.1\testhost.exe" | ||
20 | mt.exe -manifest "WixToolsetTest.BurnE2E\testhost.longpathaware.manifest" -updateresource:"%_B%\netcoreapp3.1\testhost.exe" | ||
21 | |||
17 | @if not "%RuntimeTestsEnabled%"=="true" goto :LExit | 22 | @if not "%RuntimeTestsEnabled%"=="true" goto :LExit |
18 | 23 | ||
19 | dotnet test -c %_C% --no-build WixToolsetTest.BurnE2E -l "trx;LogFileName=%_L%\TestResults\WixToolsetTest.BurnE2E.trx" || exit /b | 24 | dotnet test -c %_C% --no-build WixToolsetTest.BurnE2E -l "trx;LogFileName=%_L%\TestResults\WixToolsetTest.BurnE2E.trx" || exit /b |