OutputAnalyzer.java revision 2446:5fb86d73e54d
14Srgrimes/*
24Srgrimes * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
34Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44Srgrimes *
54Srgrimes * This code is free software; you can redistribute it and/or modify it
64Srgrimes * under the terms of the GNU General Public License version 2 only, as
74Srgrimes * published by the Free Software Foundation.
84Srgrimes *
94Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
104Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
114Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
124Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
134Srgrimes * accompanied this code).
144Srgrimes *
154Srgrimes * You should have received a copy of the GNU General Public License version
164Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
174Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
184Srgrimes *
194Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
204Srgrimes * or visit www.oracle.com if you need additional information or have any
214Srgrimes * questions.
224Srgrimes */
234Srgrimes
244Srgrimespackage jdk.test.lib.process;
254Srgrimes
264Srgrimesimport java.io.IOException;
274Srgrimesimport java.util.Arrays;
284Srgrimesimport java.util.List;
294Srgrimesimport java.util.regex.Matcher;
304Srgrimesimport java.util.regex.Pattern;
314Srgrimes
324Srgrimespublic final class OutputAnalyzer {
334Srgrimes
344Srgrimes  private final String stdout;
354Srgrimes  private final String stderr;
364Srgrimes  private final int exitValue;
37471Srgrimes
382056Swollman  /**
394Srgrimes   * Create an OutputAnalyzer, a utility class for verifying output and exit
404Srgrimes   * value from a Process
414Srgrimes   *
421110Salm   * @param process Process to analyze
431110Salm   * @throws IOException If an I/O error occurs.
441110Salm   */
451110Salm  public OutputAnalyzer(Process process) throws IOException {
464Srgrimes    OutputBuffer output = ProcessTools.getOutput(process);
474Srgrimes    exitValue = process.exitValue();
481110Salm    this.stdout = output.getStdout();
491110Salm    this.stderr = output.getStderr();
501110Salm  }
511110Salm
521110Salm  /**
531110Salm   * Create an OutputAnalyzer, a utility class for verifying output
541110Salm   *
551110Salm   * @param buf String buffer to analyze
561110Salm   */
571110Salm  public OutputAnalyzer(String buf) {
581110Salm    this(buf, buf);
591110Salm  }
601110Salm
611110Salm  /**
621110Salm   * Create an OutputAnalyzer, a utility class for verifying output
632056Swollman   *
642056Swollman   * @param stdout stdout buffer to analyze
652056Swollman   * @param stderr stderr buffer to analyze
662056Swollman   */
672056Swollman  public OutputAnalyzer(String stdout, String stderr) {
682056Swollman    this.stdout = stdout;
694Srgrimes    this.stderr = stderr;
701110Salm    exitValue = -1;
711110Salm  }
721110Salm
734Srgrimes  /**
744Srgrimes   * Verify that the stdout contents of output buffer is empty
754Srgrimes   *
764Srgrimes   * @throws RuntimeException
77878Sache   *             If stdout was not empty
78878Sache   */
794Srgrimes  public void stdoutShouldBeEmpty() {
80878Sache    if (!getStdout().isEmpty()) {
81878Sache      reportDiagnosticSummary();
82863Sache      throw new RuntimeException("stdout was not empty");
831110Salm    }
841110Salm  }
851110Salm
861110Salm  /**
871110Salm   * Verify that the stderr contents of output buffer is empty
881110Salm   *
891110Salm   * @throws RuntimeException
901110Salm   *             If stderr was not empty
911110Salm   */
921110Salm  public void stderrShouldBeEmpty() {
931110Salm    if (!getStderr().isEmpty()) {
94863Sache      reportDiagnosticSummary();
951110Salm      throw new RuntimeException("stderr was not empty");
961110Salm    }
971110Salm  }
981110Salm
991110Salm  /**
1001110Salm   * Verify that the stdout contents of output buffer is not empty
101874Sache   *
1021110Salm   * @throws RuntimeException
1034Srgrimes   *             If stdout was empty
1044Srgrimes   */
105890Sache  public void stdoutShouldNotBeEmpty() {
106890Sache    if (getStdout().isEmpty()) {
107890Sache      reportDiagnosticSummary();
108890Sache      throw new RuntimeException("stdout was empty");
109890Sache    }
110890Sache  }
111890Sache
1121233Sache  /**
113874Sache   * Verify that the stderr contents of output buffer is not empty
114890Sache   *
115890Sache   * @throws RuntimeException
116890Sache   *             If stderr was empty
117890Sache   */
118890Sache  public void stderrShouldNotBeEmpty() {
119890Sache    if (getStderr().isEmpty()) {
1204Srgrimes      reportDiagnosticSummary();
1214Srgrimes      throw new RuntimeException("stderr was empty");
1221110Salm    }
1234Srgrimes  }
1244Srgrimes
1254Srgrimes    /**
1261110Salm   * Verify that the stdout and stderr contents of output buffer contains the string
1274Srgrimes   *
1284Srgrimes   * @param expectedString String that buffer should contain
1294Srgrimes   * @throws RuntimeException If the string was not found
1301110Salm   */
1314Srgrimes  public OutputAnalyzer shouldContain(String expectedString) {
1324Srgrimes    if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
1331110Salm        reportDiagnosticSummary();
1344Srgrimes        throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
1354Srgrimes    }
1364Srgrimes    return this;
1374Srgrimes  }
1384Srgrimes
1394Srgrimes  /**
1404Srgrimes   * Verify that the stdout contents of output buffer contains the string
1414Srgrimes   *
1424Srgrimes   * @param expectedString String that buffer should contain
1434Srgrimes   * @throws RuntimeException If the string was not found
1444Srgrimes   */
1454Srgrimes  public OutputAnalyzer stdoutShouldContain(String expectedString) {
1464Srgrimes    if (!stdout.contains(expectedString)) {
1474Srgrimes        reportDiagnosticSummary();
1484Srgrimes        throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
1494Srgrimes    }
1504Srgrimes    return this;
1514Srgrimes  }
1524Srgrimes
1534Srgrimes  /**
1544Srgrimes   * Verify that the stderr contents of output buffer contains the string
1554Srgrimes   *
1561110Salm   * @param expectedString String that buffer should contain
1571110Salm   * @throws RuntimeException If the string was not found
1581110Salm   */
159879Swollman  public OutputAnalyzer stderrShouldContain(String expectedString) {
160879Swollman    if (!stderr.contains(expectedString)) {
1614Srgrimes        reportDiagnosticSummary();
1624Srgrimes        throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
1634Srgrimes    }
1644Srgrimes    return this;
1654Srgrimes  }
1664Srgrimes
1674Srgrimes  /**
1684Srgrimes   * Verify that the stdout and stderr contents of output buffer does not contain the string
1694Srgrimes   *
1704Srgrimes   * @param expectedString String that the buffer should not contain
1714Srgrimes   * @throws RuntimeException If the string was found
1724Srgrimes   */
1734Srgrimes  public OutputAnalyzer shouldNotContain(String notExpectedString) {
1744Srgrimes    if (stdout.contains(notExpectedString)) {
1754Srgrimes        reportDiagnosticSummary();
1764Srgrimes        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
1774Srgrimes    }
1784Srgrimes    if (stderr.contains(notExpectedString)) {
1794Srgrimes        reportDiagnosticSummary();
1804Srgrimes        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
1814Srgrimes    }
1824Srgrimes    return this;
1834Srgrimes  }
1844Srgrimes
1854Srgrimes  /**
1864Srgrimes   * Verify that the stdout and stderr contents of output buffer does not contain the string
1874Srgrimes   *
1884Srgrimes   * @throws RuntimeException If the string was found
1894Srgrimes   */
1904Srgrimes  public OutputAnalyzer shouldBeEmpty() {
1914Srgrimes    if (!stdout.isEmpty()) {
1924Srgrimes        reportDiagnosticSummary();
1934Srgrimes        throw new RuntimeException("stdout was not empty");
1944Srgrimes    }
195798Swollman    if (!stderr.isEmpty()) {
1964Srgrimes        reportDiagnosticSummary();
1974Srgrimes        throw new RuntimeException("stderr was not empty");
198798Swollman    }
1994Srgrimes    return this;
200798Swollman  }
201798Swollman
2021549Srgrimes  /**
2034Srgrimes   * Verify that the stdout contents of output buffer does not contain the string
2044Srgrimes   *
2054Srgrimes   * @param expectedString String that the buffer should not contain
2064Srgrimes   * @throws RuntimeException If the string was found
207798Swollman   */
208798Swollman  public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
2094Srgrimes    if (stdout.contains(notExpectedString)) {
2101110Salm        reportDiagnosticSummary();
2111110Salm        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
2124Srgrimes    }
2134Srgrimes    return this;
2144Srgrimes  }
2154Srgrimes
2164Srgrimes  /**
217798Swollman   * Verify that the stderr contents of output buffer does not contain the string
2184Srgrimes   *
219798Swollman   * @param expectedString String that the buffer should not contain
2204Srgrimes   * @throws RuntimeException If the string was found
2214Srgrimes   */
2224Srgrimes  public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
2234Srgrimes    if (stderr.contains(notExpectedString)) {
2244Srgrimes        reportDiagnosticSummary();
2254Srgrimes        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
2264Srgrimes    }
2274Srgrimes    return this;
2284Srgrimes  }
2294Srgrimes
230826Salm  /**
231826Salm   * Verify that the stdout and stderr contents of output buffer matches
232826Salm   * the pattern
233826Salm   *
234826Salm   * @param pattern
235826Salm   * @throws RuntimeException If the pattern was not found
2364Srgrimes   */
2374Srgrimes  public OutputAnalyzer shouldMatch(String pattern) {
2384Srgrimes      Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
2394Srgrimes      Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
2404Srgrimes      if (!stdoutMatcher.find() && !stderrMatcher.find()) {
2414Srgrimes          reportDiagnosticSummary();
2424Srgrimes          throw new RuntimeException("'" + pattern
2434Srgrimes                + "' missing from stdout/stderr \n");
2444Srgrimes      }
2454Srgrimes      return this;
2464Srgrimes  }
2474Srgrimes
2484Srgrimes  /**
249798Swollman   * Verify that the stdout contents of output buffer matches the
2504Srgrimes   * pattern
251798Swollman   *
2524Srgrimes   * @param pattern
2534Srgrimes   * @throws RuntimeException If the pattern was not found
2544Srgrimes   */
2554Srgrimes  public OutputAnalyzer stdoutShouldMatch(String pattern) {
2564Srgrimes      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
2574Srgrimes      if (!matcher.find()) {
2584Srgrimes          reportDiagnosticSummary();
2594Srgrimes          throw new RuntimeException("'" + pattern
2601110Salm                + "' missing from stdout \n");
2614Srgrimes      }
2624Srgrimes      return this;
2634Srgrimes  }
2644Srgrimes
2654Srgrimes  /**
2664Srgrimes   * Verify that the stderr contents of output buffer matches the
2671110Salm   * pattern
2684Srgrimes   *
2694Srgrimes   * @param pattern
2701110Salm   * @throws RuntimeException If the pattern was not found
2711110Salm   */
2721110Salm  public OutputAnalyzer stderrShouldMatch(String pattern) {
2731110Salm      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
2741110Salm      if (!matcher.find()) {
2751110Salm          reportDiagnosticSummary();
2761110Salm          throw new RuntimeException("'" + pattern
2771110Salm                + "' missing from stderr \n");
2781110Salm      }
2791110Salm      return this;
2801110Salm  }
2811110Salm
2821110Salm  /**
2831110Salm   * Verify that the stdout and stderr contents of output buffer does not
2841110Salm   * match the pattern
2851110Salm   *
2861110Salm   * @param pattern
2874Srgrimes   * @throws RuntimeException If the pattern was found
2881110Salm   */
2891110Salm  public OutputAnalyzer shouldNotMatch(String pattern) {
2901110Salm      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
2911110Salm      if (matcher.find()) {
2921110Salm          reportDiagnosticSummary();
2931231Salm          throw new RuntimeException("'" + pattern
2941110Salm                  + "' found in stdout: '" + matcher.group() + "' \n");
2951110Salm      }
2961110Salm      matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
2971110Salm      if (matcher.find()) {
2981110Salm          reportDiagnosticSummary();
2991110Salm          throw new RuntimeException("'" + pattern
3001231Salm                  + "' found in stderr: '" + matcher.group() + "' \n");
3011231Salm      }
3021110Salm      return this;
3034Srgrimes  }
304464Sjkh
3054Srgrimes  /**
3064Srgrimes   * Verify that the stdout contents of output buffer does not match the
3074Srgrimes   * pattern
3084Srgrimes   *
3094Srgrimes   * @param pattern
3104Srgrimes   * @throws RuntimeException If the pattern was found
3114Srgrimes   */
3124Srgrimes  public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
3134Srgrimes      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
3144Srgrimes      if (matcher.find()) {
3154Srgrimes          reportDiagnosticSummary();
3164Srgrimes          throw new RuntimeException("'" + pattern
3174Srgrimes                  + "' found in stdout \n");
3184Srgrimes      }
3194Srgrimes      return this;
3204Srgrimes  }
3214Srgrimes
3221110Salm  /**
3231110Salm   * Verify that the stderr contents of output buffer does not match the
3241110Salm   * pattern
3251110Salm   *
3264Srgrimes   * @param pattern
3271110Salm   * @throws RuntimeException If the pattern was found
328863Sache   */
3291110Salm  public OutputAnalyzer stderrShouldNotMatch(String pattern) {
3301110Salm      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
331863Sache      if (matcher.find()) {
332863Sache          reportDiagnosticSummary();
3331110Salm          throw new RuntimeException("'" + pattern
3341110Salm                  + "' found in stderr \n");
335863Sache      }
336863Sache      return this;
3371110Salm  }
3381110Salm
339863Sache  /**
340874Sache   * Get the captured group of the first string matching the pattern.
3411110Salm   * stderr is searched before stdout.
3421110Salm   *
343874Sache   * @param pattern The multi-line pattern to match
344863Sache   * @param group The group to capture
3451110Salm   * @return The matched string or null if no match was found
3461110Salm   */
347863Sache  public String firstMatch(String pattern, int group) {
348854Sache    Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
3494Srgrimes    Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
3501549Srgrimes    if (stderrMatcher.find()) {
3514Srgrimes      return stderrMatcher.group(group);
3524Srgrimes    }
3531110Salm    if (stdoutMatcher.find()) {
3544Srgrimes      return stdoutMatcher.group(group);
3554Srgrimes    }
3564Srgrimes    return null;
357798Swollman  }
3584Srgrimes
3594Srgrimes  /**
3604Srgrimes   * Get the first string matching the pattern.
3614Srgrimes   * stderr is searched before stdout.
362798Swollman   *
3634Srgrimes   * @param pattern The multi-line pattern to match
3644Srgrimes   * @return The matched string or null if no match was found
3654Srgrimes   */
3664Srgrimes  public String firstMatch(String pattern) {
3674Srgrimes    return firstMatch(pattern, 0);
3684Srgrimes  }
3694Srgrimes
370798Swollman  /**
3714Srgrimes   * Verify the exit value of the process
3724Srgrimes   *
3734Srgrimes   * @param expectedExitValue Expected exit value from process
3744Srgrimes   * @throws RuntimeException If the exit value from the process did not match the expected value
3754Srgrimes   */
3764Srgrimes  public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
3774Srgrimes      if (getExitValue() != expectedExitValue) {
3784Srgrimes          reportDiagnosticSummary();
3794Srgrimes          throw new RuntimeException("Expected to get exit value of ["
3804Srgrimes                  + expectedExitValue + "]\n");
3814Srgrimes      }
3824Srgrimes      return this;
3834Srgrimes  }
3844Srgrimes
3851110Salm  /**
3861110Salm   * Verify the exit value of the process
3871110Salm   *
3881110Salm   * @param notExpectedExitValue Unexpected exit value from process
3891110Salm   * @throws RuntimeException If the exit value from the process did match the expected value
3901110Salm   */
3911110Salm  public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) {
3921110Salm      if (getExitValue() == notExpectedExitValue) {
3931161Snate          reportDiagnosticSummary();
3944Srgrimes          throw new RuntimeException("Unexpected to get exit value of ["
3954Srgrimes                  + notExpectedExitValue + "]\n");
3964Srgrimes      }
3974Srgrimes      return this;
3984Srgrimes  }
3994Srgrimes
4004Srgrimes
4014Srgrimes  /**
4024Srgrimes   * Report summary that will help to diagnose the problem
4034Srgrimes   * Currently includes:
4044Srgrimes   *  - standard input produced by the process under test
4054Srgrimes   *  - standard output
4064Srgrimes   *  - exit code
4074Srgrimes   *  Note: the command line is printed by the ProcessTools
4084Srgrimes   */
4094Srgrimes  public void reportDiagnosticSummary() {
4104Srgrimes      String msg =
4114Srgrimes          " stdout: [" + stdout + "];\n" +
4124Srgrimes          " stderr: [" + stderr + "]\n" +
4134Srgrimes          " exitValue = " + getExitValue() + "\n";
4144Srgrimes
4154Srgrimes      System.err.println(msg);
4161379Sdg  }
4174Srgrimes
4184Srgrimes
4194Srgrimes  /**
4201549Srgrimes   * Get the contents of the output buffer (stdout and stderr)
4214Srgrimes   *
4224Srgrimes   * @return Content of the output buffer
4234Srgrimes   */
4244Srgrimes  public String getOutput() {
4254Srgrimes    return stdout + stderr;
4264Srgrimes  }
427878Sache
4284Srgrimes  /**
4294Srgrimes   * Get the contents of the stdout buffer
4304Srgrimes   *
4314Srgrimes   * @return Content of the stdout buffer
4324Srgrimes   */
4334Srgrimes  public String getStdout() {
434798Swollman    return stdout;
435464Sjkh  }
436464Sjkh
437464Sjkh  /**
438464Sjkh   * Get the contents of the stderr buffer
4394Srgrimes   *
4404Srgrimes   * @return Content of the stderr buffer
4414Srgrimes   */
4424Srgrimes  public String getStderr() {
4434Srgrimes    return stderr;
4444Srgrimes  }
4454Srgrimes
4464Srgrimes  /**
4474Srgrimes   * Get the process exit value
4484Srgrimes   *
4494Srgrimes   * @return Process exit value
4504Srgrimes   */
4514Srgrimes  public int getExitValue() {
4524Srgrimes    return exitValue;
4534Srgrimes  }
4544Srgrimes
4554Srgrimes  /**
4564Srgrimes   * Get the contents of the output buffer (stdout and stderr) as list of strings.
4574Srgrimes   * Output will be split by newlines.
4584Srgrimes   *
4594Srgrimes   * @return Contents of the output buffer as list of strings
4604Srgrimes   */
4614Srgrimes  public List<String> asLines() {
4624Srgrimes    return asLines(getOutput());
4634Srgrimes  }
4644Srgrimes
465798Swollman  private List<String> asLines(String buffer) {
4661549Srgrimes    return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
4674Srgrimes  }
468798Swollman}
469464Sjkh