diff options
Diffstat (limited to 'src/test/burn/WixTestTools/TestTool.cs')
-rw-r--r-- | src/test/burn/WixTestTools/TestTool.cs | 245 |
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 | |||
3 | namespace 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 | } | ||