main
cs 261 lines 9.83 KB
Raw
1 // Copyright (c) .NET Foundation 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.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 readonly 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 {
33 throw new ArgumentNullException("fileName");
34 }
35
36 if (!File.Exists(fileName))
37 {
38 throw new ArgumentException(String.Format(@"File doesn't exist:{0}", fileName), "fileName");
39 }
40
41 this.logFile = fileName;
42 }
43
44 /// <summary>
45 /// Constructor for log files where the exact file name is known.
46 /// </summary>
47 /// <param name="directory">The directory in which the log file is located.</param>
48 /// <param name="fileName">The name of the log file.</param>
49 public LogVerifier(string directory, string fileName)
50 : this(Path.Combine(directory, fileName))
51 { }
52
53 /// <summary>
54 /// Scans a log file line by line until the regex pattern is matched or eof is reached.
55 /// This method would be used in the case where the log file is very large, the regex doesn't
56 /// span multiple lines, and only one match is required.
57 /// </summary>
58 /// <param name="regex">A regular expression</param>
59 /// <returns>True if a match is found, False otherwise.</returns>
60 public bool LineByLine(Regex regex)
61 {
62 string line;
63 StreamReader sr = new StreamReader(this.logFile);
64
65 // Read from a file stream line by line.
66 while ((line = sr.ReadLine()) != null)
67 {
68 if (regex.Match(line).Success)
69 {
70 sr.Close();
71 sr.Dispose();
72 return true;
73 }
74 }
75 return false;
76 }
77
78
79 /// <summary>
80 /// Scans a log file line by line until the regex pattern is matched or eof is reached.
81 /// This method would be used in the case where the log file is very large, the regex doesn't
82 /// span multiple lines, and only one match is required.
83 /// No RegexOptions are used and matches are case sensitive.
84 /// </summary>
85 /// <param name="regex">A regular expression string.</param>
86 /// <returns>True if a match is found, False otherwise.</returns>
87 public bool LineByLine(string regex)
88 {
89 return this.LineByLine(new Regex(regex));
90 }
91
92
93 /// <summary>
94 /// Scans a log file for matches to the regex.
95 /// </summary>
96 /// <param name="regex">A regular expression</param>
97 /// <returns>The number of matches</returns>
98 public int EntireFileAtOnce(Regex regex)
99 {
100 string logFileText = this.ReadLogFile();
101 return regex.Matches(logFileText).Count;
102 }
103
104 /// <summary>
105 /// Scans a log file for matches to the regex.
106 /// </summary>
107 /// <param name="match">A string to find.</param>
108 /// <returns>If the string is found.</returns>
109 public bool EntireFileAtOncestr(string match)
110 {
111 string logFileText = this.ReadLogFile();
112 return logFileText.Contains(match);
113 }
114
115 /// <summary>
116 /// Scans a log file for matches to the regex string.
117 /// Only the Multiline RegexOption is used and matches are case sensitive.
118 /// </summary>
119 /// <param name="regex">A regular expression</param>
120 /// <returns>The number of matches</returns>
121 public int EntireFileAtOnce(string regex)
122 {
123 return this.EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline));
124 }
125
126 /// <summary>
127 /// Scans a log file for matches to the regex string.
128 /// </summary>
129 /// <param name="regex">A regular expression</param>
130 /// <param name="ignoreCase">Specify whether to perform case sensitive matches</param>
131 /// <returns>The number of matches</returns>
132 public int EntireFileAtOnce(string regex, bool ignoreCase)
133 {
134 if (!ignoreCase)
135 {
136 return this.EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline));
137 }
138 else
139 {
140 return this.EntireFileAtOnce(new Regex(regex, RegexOptions.Multiline | RegexOptions.IgnoreCase));
141 }
142 }
143
144 /// <summary>
145 /// Search through the log and Assert.Fail() if a specified string is not found.
146 /// </summary>
147 /// <param name="match">Search expression</param>
148 /// <param name="ignoreCase">Perform case insensitive match</param>
149 public void AssertTextInLog(string match, bool ignoreCase)
150 {
151 Assert.True(this.EntireFileAtOncestr(match),
152 String.Format("The log does not contain a match for the {1}string \"{0}\" ", match, ignoreCase ? "case insensitive " : ""));
153 }
154
155 /// <summary>
156 /// Search through the log and Assert.Fail() if a specified string is not found.
157 /// </summary>
158 /// <param name="regex">Search expression</param>
159 /// <param name="ignoreCase">Perform case insensitive match</param>
160 public void AssertTextInLog(Regex regex, bool ignoreCase)
161 {
162 Assert.True(this.EntireFileAtOnce(regex) >= 1,
163 String.Format("The log does not contain a match to the regular expression \"{0}\" ", regex.ToString()));
164 }
165
166 /// <summary>
167 /// Search through the log and Assert.Fail() if a specified string is not found.
168 /// </summary>
169 /// <param name="regex">Search expression</param>
170 /// <param name="ignoreCase">Perform case insensitive match</param>
171 public void AssertTextInLog(string regex)
172 {
173 this.AssertTextInLog(regex, true);
174 }
175
176 /// <summary>
177 /// Search through the log and Assert.Fail() if a specified string is not found.
178 /// </summary>
179 /// <param name="regex">Search expression</param>
180 /// <param name="ignoreCase">Perform case insensitive match</param>
181 public void AssertTextInLog(Regex regex)
182 {
183 this.AssertTextInLog(regex, true);
184 }
185
186
187 /// <summary>
188 /// Search through the log and Assert.Fail() if a specified string is found.
189 /// </summary>
190 /// <param name="regex">Search expression</param>
191 /// <param name="ignoreCase">Perform case insensitive match</param>
192 public void AssertTextNotInLog(Regex regex, bool ignoreCase)
193 {
194 Assert.True(this.EntireFileAtOnce(regex) < 1,
195 String.Format("The log contain a match to the regular expression \"{0}\" ", regex.ToString()));
196 }
197
198 /// <summary>
199 /// Search through the log and Assert.Fail() if a specified string is not found.
200 /// </summary>
201 /// <param name="regex">Search expression</param>
202 /// <param name="ignoreCase">Perform case insensitive match</param>
203 public void AssertTextNotInLog(string regex, bool ignoreCase)
204 {
205 Assert.False(this.EntireFileAtOncestr(regex),
206 String.Format("The log does not contain a match to the regular expression \"{0}\" ", regex));
207 }
208
209 /// <summary>
210 /// Checks if a meesage is in a file
211 /// </summary>
212 /// <param name="logFileName">The full path to the log file</param>
213 /// <param name="message">Search expression</param>
214 /// <returns>True if the message was found, false otherwise</returns>
215 public static bool MessageInLogFile(string logFileName, string message)
216 {
217 LogVerifier logVerifier = new LogVerifier(logFileName);
218 return logVerifier.EntireFileAtOncestr(message);
219 }
220
221 /// <summary>
222 /// Checks if a meesage is in a file
223 /// </summary>
224 /// <param name="logFileName">The full path to the log file</param>
225 /// <param name="message">Search expression (regex)</param>
226 /// <returns>True if the message was found, false otherwise</returns>
227 public static bool MessageInLogFileRegex(string logFileName, string regexMessage)
228 {
229 LogVerifier logVerifier = new LogVerifier(logFileName);
230 return logVerifier.EntireFileAtOnce(regexMessage) > 0;
231 }
232
233 /// <summary>
234 /// Read in the entire log file at once.
235 /// </summary>
236 /// <returns>Contents of log file.</returns>
237 private string ReadLogFile()
238 {
239 // Retry a few times.
240 for (int retry = 0; ; ++retry)
241 {
242 try
243 {
244 using (StreamReader sr = new StreamReader(this.logFile))
245 {
246 return sr.ReadToEnd();
247 }
248 }
249 catch // we'll catch everything a few times until we give up.
250 {
251 if (retry > 4)
252 {
253 throw;
254 }
255
256 System.Threading.Thread.Sleep(1000);
257 }
258 }
259 }
260 }
261 }