1 /* 2 * Copyright (c) 2013, 2015, 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 jdk.test.lib; 25 26 import java.io.IOException; 27 import java.util.Arrays; 28 import java.util.List; 29 import java.util.regex.Matcher; 30 import java.util.regex.Pattern; 31 32 public final class OutputAnalyzer { 33 34 private final String stdout; 35 private final String stderr; 36 private final int exitValue; 37 38 /** 39 * Create an OutputAnalyzer, a utility class for verifying output and exit 40 * value from a Process 41 * 42 * @param process Process to analyze 43 * @throws IOException If an I/O error occurs. 44 * 45 * @deprecated This class is deprecated. Use the one from 46 * {@code <root>/test/lib/share/classes/jdk/test/lib/process} 47 */ 48 @Deprecated 49 public OutputAnalyzer(Process process) throws IOException { 50 OutputBuffer output = ProcessTools.getOutput(process); 51 exitValue = process.exitValue(); 52 this.stdout = output.getStdout(); 53 this.stderr = output.getStderr(); 54 } 55 56 /** 57 * Create an OutputAnalyzer, a utility class for verifying output 58 * 59 * @param buf String buffer to analyze 60 */ 61 public OutputAnalyzer(String buf) { 62 this(buf, buf); 63 } 64 65 /** 66 * Create an OutputAnalyzer, a utility class for verifying output 67 * 68 * @param stdout stdout buffer to analyze 69 * @param stderr stderr buffer to analyze 70 */ 71 public OutputAnalyzer(String stdout, String stderr) { 72 this.stdout = stdout; 73 this.stderr = stderr; 74 exitValue = -1; 75 } 76 77 /** 78 * Verify that the stdout contents of output buffer is empty 79 * 80 * @throws RuntimeException 81 * If stdout was not empty 82 */ 83 public void stdoutShouldBeEmpty() { 84 if (!getStdout().isEmpty()) { 85 reportDiagnosticSummary(); 86 throw new RuntimeException("stdout was not empty"); 87 } 88 } 89 90 /** 91 * Verify that the stderr contents of output buffer is empty 92 * 93 * @throws RuntimeException 94 * If stderr was not empty 95 */ 96 public void stderrShouldBeEmpty() { 97 if (!getStderr().isEmpty()) { 98 reportDiagnosticSummary(); 99 throw new RuntimeException("stderr was not empty"); 100 } 101 } 102 103 /** 104 * Verify that the stdout contents of output buffer is not empty 105 * 106 * @throws RuntimeException 107 * If stdout was empty 108 */ 109 public void stdoutShouldNotBeEmpty() { 110 if (getStdout().isEmpty()) { 111 reportDiagnosticSummary(); 112 throw new RuntimeException("stdout was empty"); 113 } 114 } 115 116 /** 117 * Verify that the stderr contents of output buffer is not empty 118 * 119 * @throws RuntimeException 120 * If stderr was empty 121 */ 122 public void stderrShouldNotBeEmpty() { 123 if (getStderr().isEmpty()) { 124 reportDiagnosticSummary(); 125 throw new RuntimeException("stderr was empty"); 126 } 127 } 128 129 /** 130 * Verify that the stdout and stderr contents of output buffer contains the string 131 * 132 * @param expectedString String that buffer should contain 133 * @throws RuntimeException If the string was not found 134 */ 135 public OutputAnalyzer shouldContain(String expectedString) { 136 if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) { 137 reportDiagnosticSummary(); 138 throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n"); 139 } 140 return this; 141 } 142 143 /** 144 * Verify that the stdout contents of output buffer contains the string 145 * 146 * @param expectedString String that buffer should contain 147 * @throws RuntimeException If the string was not found 148 */ 149 public OutputAnalyzer stdoutShouldContain(String expectedString) { 150 if (!stdout.contains(expectedString)) { 151 reportDiagnosticSummary(); 152 throw new RuntimeException("'" + expectedString + "' missing from stdout \n"); 153 } 154 return this; 155 } 156 157 /** 158 * Verify that the stderr contents of output buffer contains the string 159 * 160 * @param expectedString String that buffer should contain 161 * @throws RuntimeException If the string was not found 162 */ 163 public OutputAnalyzer stderrShouldContain(String expectedString) { 164 if (!stderr.contains(expectedString)) { 165 reportDiagnosticSummary(); 166 throw new RuntimeException("'" + expectedString + "' missing from stderr \n"); 167 } 168 return this; 169 } 170 171 /** 172 * Verify that the stdout and stderr contents of output buffer does not contain the string 173 * 174 * @param expectedString String that the buffer should not contain 175 * @throws RuntimeException If the string was found 176 */ 177 public OutputAnalyzer shouldNotContain(String notExpectedString) { 178 if (stdout.contains(notExpectedString)) { 179 reportDiagnosticSummary(); 180 throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); 181 } 182 if (stderr.contains(notExpectedString)) { 183 reportDiagnosticSummary(); 184 throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); 185 } 186 return this; 187 } 188 189 /** 190 * Verify that the stdout contents of output buffer does not contain the string 191 * 192 * @param expectedString String that the buffer should not contain 193 * @throws RuntimeException If the string was found 194 */ 195 public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) { 196 if (stdout.contains(notExpectedString)) { 197 reportDiagnosticSummary(); 198 throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); 199 } 200 return this; 201 } 202 203 /** 204 * Verify that the stderr contents of output buffer does not contain the string 205 * 206 * @param expectedString String that the buffer should not contain 207 * @throws RuntimeException If the string was found 208 */ 209 public OutputAnalyzer stderrShouldNotContain(String notExpectedString) { 210 if (stderr.contains(notExpectedString)) { 211 reportDiagnosticSummary(); 212 throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); 213 } 214 return this; 215 } 216 217 /** 218 * Verify that the stdout and stderr contents of output buffer matches 219 * the pattern 220 * 221 * @param pattern 222 * @throws RuntimeException If the pattern was not found 223 */ 224 public OutputAnalyzer shouldMatch(String pattern) { 225 Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 226 Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 227 if (!stdoutMatcher.find() && !stderrMatcher.find()) { 228 reportDiagnosticSummary(); 229 throw new RuntimeException("'" + pattern 230 + "' missing from stdout/stderr \n"); 231 } 232 return this; 233 } 234 235 /** 236 * Verify that the stdout contents of output buffer matches the 237 * pattern 238 * 239 * @param pattern 240 * @throws RuntimeException If the pattern was not found 241 */ 242 public OutputAnalyzer stdoutShouldMatch(String pattern) { 243 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 244 if (!matcher.find()) { 245 reportDiagnosticSummary(); 246 throw new RuntimeException("'" + pattern 247 + "' missing from stdout \n"); 248 } 249 return this; 250 } 251 252 /** 253 * Verify that the stderr contents of output buffer matches the 254 * pattern 255 * 256 * @param pattern 257 * @throws RuntimeException If the pattern was not found 258 */ 259 public OutputAnalyzer stderrShouldMatch(String pattern) { 260 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 261 if (!matcher.find()) { 262 reportDiagnosticSummary(); 263 throw new RuntimeException("'" + pattern 264 + "' missing from stderr \n"); 265 } 266 return this; 267 } 268 269 /** 270 * Verify that the stdout and stderr contents of output buffer does not 271 * match the pattern 272 * 273 * @param pattern 274 * @throws RuntimeException If the pattern was found 275 */ 276 public OutputAnalyzer shouldNotMatch(String pattern) { 277 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 278 if (matcher.find()) { 279 reportDiagnosticSummary(); 280 throw new RuntimeException("'" + pattern 281 + "' found in stdout: '" + matcher.group() + "' \n"); 282 } 283 matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 284 if (matcher.find()) { 285 reportDiagnosticSummary(); 286 throw new RuntimeException("'" + pattern 287 + "' found in stderr: '" + matcher.group() + "' \n"); 288 } 289 return this; 290 } 291 292 /** 293 * Verify that the stdout contents of output buffer does not match the 294 * pattern 295 * 296 * @param pattern 297 * @throws RuntimeException If the pattern was found 298 */ 299 public OutputAnalyzer stdoutShouldNotMatch(String pattern) { 300 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 301 if (matcher.find()) { 302 reportDiagnosticSummary(); 303 throw new RuntimeException("'" + pattern 304 + "' found in stdout \n"); 305 } 306 return this; 307 } 308 309 /** 310 * Verify that the stderr contents of output buffer does not match the 311 * pattern 312 * 313 * @param pattern 314 * @throws RuntimeException If the pattern was found 315 */ 316 public OutputAnalyzer stderrShouldNotMatch(String pattern) { 317 Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 318 if (matcher.find()) { 319 reportDiagnosticSummary(); 320 throw new RuntimeException("'" + pattern 321 + "' found in stderr \n"); 322 } 323 return this; 324 } 325 326 /** 327 * Get the captured group of the first string matching the pattern. 328 * stderr is searched before stdout. 329 * 330 * @param pattern The multi-line pattern to match 331 * @param group The group to capture 332 * @return The matched string or null if no match was found 333 */ 334 public String firstMatch(String pattern, int group) { 335 Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); 336 Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); 337 if (stderrMatcher.find()) { 338 return stderrMatcher.group(group); 339 } 340 if (stdoutMatcher.find()) { 341 return stdoutMatcher.group(group); 342 } 343 return null; 344 } 345 346 /** 347 * Get the first string matching the pattern. 348 * stderr is searched before stdout. 349 * 350 * @param pattern The multi-line pattern to match 351 * @return The matched string or null if no match was found 352 */ 353 public String firstMatch(String pattern) { 354 return firstMatch(pattern, 0); 355 } 356 357 /** 358 * Verify the exit value of the process 359 * 360 * @param expectedExitValue Expected exit value from process 361 * @throws RuntimeException If the exit value from the process did not match the expected value 362 */ 363 public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) { 364 if (getExitValue() != expectedExitValue) { 365 reportDiagnosticSummary(); 366 throw new RuntimeException("Expected to get exit value of [" 367 + expectedExitValue + "]\n"); 368 } 369 return this; 370 } 371 372 373 /** 374 * Report summary that will help to diagnose the problem 375 * Currently includes: 376 * - standard input produced by the process under test 377 * - standard output 378 * - exit code 379 * Note: the command line is printed by the ProcessTools 380 */ 381 public void reportDiagnosticSummary() { 382 String msg = 383 " stdout: [" + stdout + "];\n" + 384 " stderr: [" + stderr + "]\n" + 385 " exitValue = " + getExitValue() + "\n"; 386 387 System.err.println(msg); 388 } 389 390 391 /** 392 * Get the contents of the output buffer (stdout and stderr) 393 * 394 * @return Content of the output buffer 395 */ 396 public String getOutput() { 397 return stdout + stderr; 398 } 399 400 /** 401 * Get the contents of the stdout buffer 402 * 403 * @return Content of the stdout buffer 404 */ 405 public String getStdout() { 406 return stdout; 407 } 408 409 /** 410 * Get the contents of the stderr buffer 411 * 412 * @return Content of the stderr buffer 413 */ 414 public String getStderr() { 415 return stderr; 416 } 417 418 /** 419 * Get the process exit value 420 * 421 * @return Process exit value 422 */ 423 public int getExitValue() { 424 return exitValue; 425 } 426 427 /** 428 * Get the contents of the output buffer (stdout and stderr) as list of strings. 429 * Output will be split by newlines. 430 * 431 * @return Contents of the output buffer as list of strings 432 */ 433 public List<String> asLines() { 434 return asLines(getOutput()); 435 } 436 437 private List<String> asLines(String buffer) { 438 return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)")); 439 } 440 }