aboutsummaryrefslogtreecommitdiff
path: root/src/test/burn/WixTestTools/TestTool.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/burn/WixTestTools/TestTool.cs')
-rw-r--r--src/test/burn/WixTestTools/TestTool.cs245
1 files changed, 245 insertions, 0 deletions
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}