1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package com.oracle.java.testlibrary; 25 26 import java.io.IOException; 27 import java.util.regex.Matcher; 28 import java.util.regex.Pattern; 29 30 public final class OutputAnalyzer { 31 32 private final String stdout; 33 private final String stderr; 34 private final int exitValue; 35 36 /** 37 * Create an OutputAnalyzer, a utility class for verifying output and exit 38 * value from a Process 39 * 40 * @param process Process to analyze 41 * @throws IOException If an I/O error occurs. 42 */ 43 public OutputAnalyzer(Process process) throws IOException { 44 OutputBuffer output = ProcessTools.getOutput(process); 45 exitValue = process.exitValue(); 46 this.stdout = output.getStdout(); 47 this.stderr = output.getStderr(); 48 } 49 50 /** 51 * Create an OutputAnalyzer, a utility class for verifying output 52 * 53 * @param buf String buffer to analyze 54 */ 55 public OutputAnalyzer(String buf) { 56 this(buf, buf); 57 } 58 59 /** 60 * Create an OutputAnalyzer, a utility class for verifying output 61 * 62 * @param stdout stdout buffer to analyze 63 * @param stderr stderr buffer to analyze 64 */ 65 public OutputAnalyzer(String stdout, String stderr) { 66 this.stdout = stdout; 67 this.stderr = stderr; 68 exitValue = -1; 69 } 70 71 /** 72 * Verify that the stdout and stderr contents of output buffer contains the string 73 * 74 * @param expectedString String that buffer should contain 75 * @throws RuntimeException If the string was not found 76 */ 77 public OutputAnalyzer shouldContain(String expectedString) { 78 if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) { 79 reportDiagnosticSummary(); 80 throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n"); 81 } 82 return this; 83 } 84 85 /** 86 * Verify that the stdout contents of output buffer contains the string 87 * 88 * @param expectedString String that buffer should contain 89 * @throws RuntimeException If the string was not found 90 */ 91 public OutputAnalyzer stdoutShouldContain(String expectedString) { 92 if (!stdout.contains(expectedString)) { 93 reportDiagnosticSummary(); 94 throw new RuntimeException("'" + expectedString + "' missing from stdout \n"); 95 } 96 return this; 97 } 98 99 /** 100 * Verify that the stderr contents of output buffer contains the string 101 * 102 * @param expectedString String that buffer should contain 103 * @throws RuntimeException If the string was not found 104 */ 105 public OutputAnalyzer stderrShouldContain(String expectedString) { 106 if (!stderr.contains(expectedString)) { 107 reportDiagnosticSummary(); 108 throw new RuntimeException("'" + expectedString + "' missing from stderr \n"); 109 } 110 return this; 111 } 112 113 /** 114 * Verify that the stdout and stderr contents of output buffer does not contain the string 115 * 116 * @param expectedString String that the buffer should not contain 117 * @throws RuntimeException If the string was found 118 */ 119 public OutputAnalyzer shouldNotContain(String notExpectedString) { 120 if (stdout.contains(notExpectedString)) { 121 reportDiagnosticSummary(); 122 throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); 123 } 124 if (stderr.contains(notExpectedString)) { 125 reportDiagnosticSummary(); 126 throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); 127 } 128 return this; 129 } 130 131 /** 132 * Verify that the stdout contents of output buffer does not contain the string 133 * 134 * @param expectedString String that the buffer should not contain 135 * @throws RuntimeException If the string was found 136 */ 137 public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) { 138 if (stdout.contains(notExpectedString)) { 139 reportDiagnosticSummary(); 140 throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); 141 } 142 return this; 143 } 144 145 /** 146 * Verify that the stderr contents of output buffer does not contain the string 147 * 148 * @param expectedString String that the buffer should not contain 149 * @throws RuntimeException If the string was found 150 */ 151 public OutputAnalyzer stderrShouldNotContain(String notExpectedString) { 152 if (stderr.contains(notExpectedString)) { 153 reportDiagnosticSummary(); 154 throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); 155 } 156 return this; 157 } 158 159 /** 160 * Verify that the stdout and stderr contents of output buffer matches 161 * the pattern 162 * 163 * @param pattern 164 * @throws RuntimeException If the pattern was not found 165 */ 166 public OutputAnalyzer shouldMatch(String pattern) { 167 Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 168 Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 169 if (!stdoutMatcher.find() && !stderrMatcher.find()) { 170 reportDiagnosticSummary(); 171 throw new RuntimeException("'" + pattern 172 + "' missing from stdout/stderr \n"); 173 } 174 return this; 175 } 176 177 /** 178 * Verify that the stdout contents of output buffer matches the 179 * pattern 180 * 181 * @param pattern 182 * @throws RuntimeException If the pattern was not found 183 */ 184 public OutputAnalyzer stdoutShouldMatch(String pattern) { 185 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 186 if (!matcher.find()) { 187 reportDiagnosticSummary(); 188 throw new RuntimeException("'" + pattern 189 + "' missing from stdout \n"); 190 } 191 return this; 192 } 193 194 /** 195 * Verify that the stderr contents of output buffer matches the 196 * pattern 197 * 198 * @param pattern 199 * @throws RuntimeException If the pattern was not found 200 */ 201 public OutputAnalyzer stderrShouldMatch(String pattern) { 202 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 203 if (!matcher.find()) { 204 reportDiagnosticSummary(); 205 throw new RuntimeException("'" + pattern 206 + "' missing from stderr \n"); 207 } 208 return this; 209 } 210 211 /** 212 * Verify that the stdout and stderr contents of output buffer does not 213 * match the pattern 214 * 215 * @param pattern 216 * @throws RuntimeException If the pattern was found 217 */ 218 public OutputAnalyzer shouldNotMatch(String pattern) { 219 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 220 if (matcher.find()) { 221 reportDiagnosticSummary(); 222 throw new RuntimeException("'" + pattern 223 + "' found in stdout: '" + matcher.group() + "' \n"); 224 } 225 matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 226 if (matcher.find()) { 227 reportDiagnosticSummary(); 228 throw new RuntimeException("'" + pattern 229 + "' found in stderr: '" + matcher.group() + "' \n"); 230 } 231 return this; 232 } 233 234 /** 235 * Verify that the stdout contents of output buffer does not match the 236 * pattern 237 * 238 * @param pattern 239 * @throws RuntimeException If the pattern was found 240 */ 241 public OutputAnalyzer stdoutShouldNotMatch(String pattern) { 242 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 243 if (matcher.find()) { 244 reportDiagnosticSummary(); 245 throw new RuntimeException("'" + pattern 246 + "' found in stdout \n"); 247 } 248 return this; 249 } 250 251 /** 252 * Verify that the stderr contents of output buffer does not match the 253 * pattern 254 * 255 * @param pattern 256 * @throws RuntimeException If the pattern was found 257 */ 258 public OutputAnalyzer stderrShouldNotMatch(String pattern) { 259 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 260 if (matcher.find()) { 261 reportDiagnosticSummary(); 262 throw new RuntimeException("'" + pattern 263 + "' found in stderr \n"); 264 } 265 return this; 266 } 267 268 /** 269 * Get the captured group of the first string matching the pattern. 270 * stderr is searched before stdout. 271 * 272 * @param pattern The multi-line pattern to match 273 * @param group The group to capture 274 * @return The matched string or null if no match was found 275 */ 276 public String firstMatch(String pattern, int group) { 277 Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 278 Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 279 if (stderrMatcher.find()) { 280 return stderrMatcher.group(group); 281 } 282 if (stdoutMatcher.find()) { 283 return stdoutMatcher.group(group); 284 } 285 return null; 286 } 287 288 /** 289 * Get the first string matching the pattern. 290 * stderr is searched before stdout. 291 * 292 * @param pattern The multi-line pattern to match 293 * @return The matched string or null if no match was found 294 */ 295 public String firstMatch(String pattern) { 296 return firstMatch(pattern, 0); 297 } 298 299 /** 300 * Verify the exit value of the process 301 * 302 * @param expectedExitValue Expected exit value from process 303 * @throws RuntimeException If the exit value from the process did not match the expected value 304 */ 305 public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) { 306 if (getExitValue() != expectedExitValue) { 307 reportDiagnosticSummary(); 308 throw new RuntimeException("Expected to get exit value of [" 309 + expectedExitValue + "]\n"); 310 } 311 return this; 312 } 313 314 315 /** 316 * Report summary that will help to diagnose the problem 317 * Currently includes: 318 * - standard input produced by the process under test 319 * - standard output 320 * - exit code 321 * Note: the command line is printed by the ProcessTools 322 */ 323 private void reportDiagnosticSummary() { 324 String msg = 325 " stdout: [" + stdout + "];\n" + 326 " stderr: [" + stderr + "]\n" + 327 " exitValue = " + getExitValue() + "\n"; 328 329 System.err.println(msg); 330 } 331 332 333 /** 334 * Get the contents of the output buffer (stdout and stderr) 335 * 336 * @return Content of the output buffer 337 */ 338 public String getOutput() { 339 return stdout + stderr; 340 } 341 342 /** 343 * Get the contents of the stdout buffer 344 * 345 * @return Content of the stdout buffer 346 */ 347 public String getStdout() { 348 return stdout; 349 } 350 351 /** 352 * Get the contents of the stderr buffer 353 * 354 * @return Content of the stderr buffer 355 */ 356 public String getStderr() { 357 return stderr; 358 } 359 360 /** 361 * Get the process exit value 362 * 363 * @return Process exit value 364 */ 365 public int getExitValue() { 366 return exitValue; 367 } 368 }