aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-17 15:46:23 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-17 16:20:10 -0600
commit15b1946325bf1cfd1794b997f2cbbbcfeb648e92 (patch)
tree511a4c77ac2de6feeb153bdc541950a14f8031e3
parentbadde27bf66fcacef2d625af0bd7590ecdc5804f (diff)
downloadwix-15b1946325bf1cfd1794b997f2cbbbcfeb648e92.tar.gz
wix-15b1946325bf1cfd1794b997f2cbbbcfeb648e92.tar.bz2
wix-15b1946325bf1cfd1794b997f2cbbbcfeb648e92.zip
Port the rest of the FailureTests from the old repo.
-rw-r--r--src/TestData/FailureTests/BundleB/Bundle.wxs26
-rw-r--r--src/TestData/FailureTests/BundleB/BundleB.wixproj16
-rw-r--r--src/TestData/FailureTests/BundleC/BundleC.wixproj19
-rw-r--r--src/TestData/FailureTests/BundleC/BundleC.wxs11
-rw-r--r--src/WixTestTools/LogVerifier.cs252
-rw-r--r--src/WixToolsetTest.BurnE2E/FailureTests.cs45
6 files changed, 369 insertions, 0 deletions
diff --git a/src/TestData/FailureTests/BundleB/Bundle.wxs b/src/TestData/FailureTests/BundleB/Bundle.wxs
new file mode 100644
index 00000000..ea3d029e
--- /dev/null
+++ b/src/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/TestData/FailureTests/BundleB/BundleB.wixproj b/src/TestData/FailureTests/BundleB/BundleB.wixproj
new file mode 100644
index 00000000..6d36d120
--- /dev/null
+++ b/src/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.83" />
14 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.61" />
15 </ItemGroup>
16</Project> \ No newline at end of file
diff --git a/src/TestData/FailureTests/BundleC/BundleC.wixproj b/src/TestData/FailureTests/BundleC/BundleC.wixproj
new file mode 100644
index 00000000..03f611fc
--- /dev/null
+++ b/src/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.83" />
17 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.61" />
18 </ItemGroup>
19</Project> \ No newline at end of file
diff --git a/src/TestData/FailureTests/BundleC/BundleC.wxs b/src/TestData/FailureTests/BundleC/BundleC.wxs
new file mode 100644
index 00000000..48c4ab72
--- /dev/null
+++ b/src/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/WixTestTools/LogVerifier.cs b/src/WixTestTools/LogVerifier.cs
new file mode 100644
index 00000000..0252a9f9
--- /dev/null
+++ b/src/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/WixToolsetTest.BurnE2E/FailureTests.cs b/src/WixToolsetTest.BurnE2E/FailureTests.cs
index bc505527..a11a5eb6 100644
--- a/src/WixToolsetTest.BurnE2E/FailureTests.cs
+++ b/src/WixToolsetTest.BurnE2E/FailureTests.cs
@@ -63,5 +63,50 @@ namespace WixToolsetTest.BurnE2E
63 packageA.VerifyInstalled(false); 63 packageA.VerifyInstalled(false);
64 packageB.VerifyInstalled(false); 64 packageB.VerifyInstalled(false);
65 } 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 }
66 } 111 }
67} 112}