changeset 50394:d7fe9d3e7bf3

8196540: [Testbug] java/security/AccessController/DoPrivAccompliceTest.java doesn't handle unrelated warnings Reviewed-by: mullan Contributed-by: bhanu.prakash.gopularam@oracle.com
author vtewari
date Wed, 25 Apr 2018 12:39:05 +0530
parents a02abc7e5536
children 03d263a61656
files test/jdk/java/security/AccessController/DoPrivAccompliceTest.java test/lib/jdk/test/lib/process/OutputAnalyzer.java
diffstat 2 files changed, 475 insertions(+), 461 deletions(-) [+]
line wrap: on
line diff
--- a/test/jdk/java/security/AccessController/DoPrivAccompliceTest.java	Wed Apr 25 12:29:48 2018 +0530
+++ b/test/jdk/java/security/AccessController/DoPrivAccompliceTest.java	Wed Apr 25 12:39:05 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,7 +104,7 @@
         ProcessTools.executeTestJava(commands)
                     .shouldHaveExitValue(0)
                     .shouldContain(userName)
-                    .stderrShouldBeEmpty();
+                    .stderrShouldBeEmptyIgnoreVMWarnings();
 
         createPolicyFile(jarFile2, policy);
         System.out.println("Created policy for " + jarFile2);
--- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java	Wed Apr 25 12:29:48 2018 +0530
+++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java	Wed Apr 25 12:39:05 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,511 +33,525 @@
 
 public final class OutputAnalyzer {
 
-  private final String stdout;
-  private final String stderr;
-  private final int exitValue;
-
-  /**
-   * Create an OutputAnalyzer, a utility class for verifying output and exit
-   * value from a Process
-   *
-   * @param process Process to analyze
-   * @throws IOException If an I/O error occurs.
-   */
-  public OutputAnalyzer(Process process) throws IOException {
-    OutputBuffer output = ProcessTools.getOutput(process);
-    exitValue = process.exitValue();
-    this.stdout = output.getStdout();
-    this.stderr = output.getStderr();
-  }
-
-  /**
-   * Create an OutputAnalyzer, a utility class for verifying output
-   *
-   * @param buf String buffer to analyze
-   */
-  public OutputAnalyzer(String buf) {
-    this(buf, buf);
-  }
-
-  /**
-   * Create an OutputAnalyzer, a utility class for verifying output
-   *
-   * @param stdout stdout buffer to analyze
-   * @param stderr stderr buffer to analyze
-   */
-  public OutputAnalyzer(String stdout, String stderr) {
-    this.stdout = stdout;
-    this.stderr = stderr;
-    exitValue = -1;
-  }
-
-  /**
-   * Verify that the stdout contents of output buffer is empty
-   *
-   * @throws RuntimeException
-   *             If stdout was not empty
-   */
-  public void stdoutShouldBeEmpty() {
-    if (!getStdout().isEmpty()) {
-      reportDiagnosticSummary();
-      throw new RuntimeException("stdout was not empty");
-    }
-  }
-
-  /**
-   * Verify that the stderr contents of output buffer is empty
-   *
-   * @throws RuntimeException
-   *             If stderr was not empty
-   */
-  public void stderrShouldBeEmpty() {
-    if (!getStderr().isEmpty()) {
-      reportDiagnosticSummary();
-      throw new RuntimeException("stderr was not empty");
-    }
-  }
-
-  /**
-   * Verify that the stdout contents of output buffer is not empty
-   *
-   * @throws RuntimeException
-   *             If stdout was empty
-   */
-  public void stdoutShouldNotBeEmpty() {
-    if (getStdout().isEmpty()) {
-      reportDiagnosticSummary();
-      throw new RuntimeException("stdout was empty");
-    }
-  }
-
-  /**
-   * Verify that the stderr contents of output buffer is not empty
-   *
-   * @throws RuntimeException
-   *             If stderr was empty
-   */
-  public void stderrShouldNotBeEmpty() {
-    if (getStderr().isEmpty()) {
-      reportDiagnosticSummary();
-      throw new RuntimeException("stderr was empty");
-    }
-  }
+    private final String stdout;
+    private final String stderr;
+    private final int exitValue;
 
     /**
-   * Verify that the stdout and stderr contents of output buffer contains the string
-   *
-   * @param expectedString String that buffer should contain
-   * @throws RuntimeException If the string was not found
-   */
-  public OutputAnalyzer shouldContain(String expectedString) {
-    if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
+     * Create an OutputAnalyzer, a utility class for verifying output and exit
+     * value from a Process
+     *
+     * @param process Process to analyze
+     * @throws IOException If an I/O error occurs.
+     */
+    public OutputAnalyzer(Process process) throws IOException {
+        OutputBuffer output = ProcessTools.getOutput(process);
+        exitValue = process.exitValue();
+        this.stdout = output.getStdout();
+        this.stderr = output.getStderr();
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stdout contents of output buffer contains the string
-   *
-   * @param expectedString String that buffer should contain
-   * @throws RuntimeException If the string was not found
-   */
-  public OutputAnalyzer stdoutShouldContain(String expectedString) {
-    if (!stdout.contains(expectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output
+     *
+     * @param buf String buffer to analyze
+     */
+    public OutputAnalyzer(String buf) {
+        this(buf, buf);
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stderr contents of output buffer contains the string
-   *
-   * @param expectedString String that buffer should contain
-   * @throws RuntimeException If the string was not found
-   */
-  public OutputAnalyzer stderrShouldContain(String expectedString) {
-    if (!stderr.contains(expectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output
+     *
+     * @param stdout stdout buffer to analyze
+     * @param stderr stderr buffer to analyze
+     */
+    public OutputAnalyzer(String stdout, String stderr) {
+        this.stdout = stdout;
+        this.stderr = stderr;
+        exitValue = -1;
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stdout and stderr contents of output buffer does not contain the string
-   *
-   * @param expectedString String that the buffer should not contain
-   * @throws RuntimeException If the string was found
-   */
-  public OutputAnalyzer shouldNotContain(String notExpectedString) {
-    if (stdout.contains(notExpectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
+    /**
+     * Verify that the stdout contents of output buffer is empty
+     *
+     * @throws RuntimeException
+     *             If stdout was not empty
+     */
+    public void stdoutShouldBeEmpty() {
+        if (!getStdout().isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stdout was not empty");
+        }
     }
-    if (stderr.contains(notExpectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
+
+    /**
+     * Verify that the stderr contents of output buffer is empty
+     *
+     * @throws RuntimeException
+     *             If stderr was not empty
+     */
+    public void stderrShouldBeEmpty() {
+        if (!getStderr().isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stderr was not empty");
+        }
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stdout and stderr contents of output buffer are empty
-   *
-   * @throws RuntimeException If the stdout and stderr are not empty
-   */
-  public OutputAnalyzer shouldBeEmpty() {
-    if (!stdout.isEmpty()) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("stdout was not empty");
+    /**
+     * Verify that the stderr contents of output buffer is empty,
+     * after filtering out the Hotspot warning messages
+     *
+     * @throws RuntimeException
+     *             If stderr was not empty
+     */
+    public void stderrShouldBeEmptyIgnoreVMWarnings() {
+        if (!getStderr().replaceAll(jvmwarningmsg + "\\R", "").isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stderr was not empty");
+        }
     }
-    if (!stderr.isEmpty()) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("stderr was not empty");
+
+    /**
+     * Verify that the stdout contents of output buffer is not empty
+     *
+     * @throws RuntimeException
+     *             If stdout was empty
+     */
+    public void stdoutShouldNotBeEmpty() {
+        if (getStdout().isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stdout was empty");
+        }
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stdout contents of output buffer does not contain the string
-   *
-   * @param expectedString String that the buffer should not contain
-   * @throws RuntimeException If the string was found
-   */
-  public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
-    if (stdout.contains(notExpectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
+    /**
+     * Verify that the stderr contents of output buffer is not empty
+     *
+     * @throws RuntimeException
+     *             If stderr was empty
+     */
+    public void stderrShouldNotBeEmpty() {
+        if (getStderr().isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stderr was empty");
+        }
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stderr contents of output buffer does not contain the string
-   *
-   * @param expectedString String that the buffer should not contain
-   * @throws RuntimeException If the string was found
-   */
-  public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
-    if (stderr.contains(notExpectedString)) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
+    /**
+     * Verify that the stdout and stderr contents of output buffer contains the string
+     *
+     * @param expectedString String that buffer should contain
+     * @throws RuntimeException If the string was not found
+     */
+    public OutputAnalyzer shouldContain(String expectedString) {
+        if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
+        }
+        return this;
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stdout and stderr contents of output buffer matches
-   * the pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was not found
-   */
-  public OutputAnalyzer shouldMatch(String pattern) {
-      Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-      Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-      if (!stdoutMatcher.find() && !stderrMatcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                + "' missing from stdout/stderr \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stdout contents of output buffer contains the string
+     *
+     * @param expectedString String that buffer should contain
+     * @throws RuntimeException If the string was not found
+     */
+    public OutputAnalyzer stdoutShouldContain(String expectedString) {
+        if (!stdout.contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify that the stdout contents of output buffer matches the
-   * pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was not found
-   */
-  public OutputAnalyzer stdoutShouldMatch(String pattern) {
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-      if (!matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                + "' missing from stdout \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stderr contents of output buffer contains the string
+     *
+     * @param expectedString String that buffer should contain
+     * @throws RuntimeException If the string was not found
+     */
+    public OutputAnalyzer stderrShouldContain(String expectedString) {
+        if (!stderr.contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify that the stderr contents of output buffer matches the
-   * pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was not found
-   */
-  public OutputAnalyzer stderrShouldMatch(String pattern) {
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not contain the string
+     *
+     * @param expectedString String that the buffer should not contain
+     * @throws RuntimeException If the string was found
+     */
+    public OutputAnalyzer shouldNotContain(String notExpectedString) {
+        if (stdout.contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
+        }
+        if (stderr.contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
+        }
+        return this;
+    }
 
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-      if (!matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                + "' missing from stderr \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stdout and stderr contents of output buffer are empty
+     *
+     * @throws RuntimeException If the stdout and stderr are not empty
+     */
+    public OutputAnalyzer shouldBeEmpty() {
+        if (!stdout.isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stdout was not empty");
+        }
+        if (!stderr.isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stderr was not empty");
+        }
+        return this;
+    }
 
-  /**
-   * Verify that the stdout and stderr contents of output buffer does not
-   * match the pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was found
-   */
-  public OutputAnalyzer shouldNotMatch(String pattern) {
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-      if (matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                  + "' found in stdout: '" + matcher.group() + "' \n");
-      }
-      matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-      if (matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                  + "' found in stderr: '" + matcher.group() + "' \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stdout contents of output buffer does not contain the string
+     *
+     * @param expectedString String that the buffer should not contain
+     * @throws RuntimeException If the string was found
+     */
+    public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
+        if (stdout.contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify that the stdout contents of output buffer does not match the
-   * pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was found
-   */
-  public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-      if (matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                  + "' found in stdout \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stderr contents of output buffer does not contain the string
+     *
+     * @param expectedString String that the buffer should not contain
+     * @throws RuntimeException If the string was found
+     */
+    public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
+        if (stderr.contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify that the stderr contents of output buffer does not match the
-   * pattern
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was found
-   */
-  public OutputAnalyzer stderrShouldNotMatch(String pattern) {
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-      if (matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                  + "' found in stderr \n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stdout and stderr contents of output buffer matches
+     * the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public OutputAnalyzer shouldMatch(String pattern) {
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                  + "' missing from stdout/stderr \n");
+        }
+        return this;
+    }
 
-  /**
-   * Get the captured group of the first string matching the pattern.
-   * stderr is searched before stdout.
-   *
-   * @param pattern The multi-line pattern to match
-   * @param group The group to capture
-   * @return The matched string or null if no match was found
-   */
-  public String firstMatch(String pattern, int group) {
-    Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-    Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-    if (stderrMatcher.find()) {
-      return stderrMatcher.group(group);
+    /**
+     * Verify that the stdout contents of output buffer matches the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public OutputAnalyzer stdoutShouldMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (!matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                  + "' missing from stdout \n");
+        }
+        return this;
     }
-    if (stdoutMatcher.find()) {
-      return stdoutMatcher.group(group);
+
+    /**
+     * Verify that the stderr contents of output buffer matches the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public OutputAnalyzer stderrShouldMatch(String pattern) {
+
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (!matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                  + "' missing from stderr \n");
+        }
+        return this;
     }
-    return null;
-  }
 
-  /**
-   * Get the first string matching the pattern.
-   * stderr is searched before stdout.
-   *
-   * @param pattern The multi-line pattern to match
-   * @return The matched string or null if no match was found
-   */
-  public String firstMatch(String pattern) {
-    return firstMatch(pattern, 0);
-  }
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not
+     * match the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public OutputAnalyzer shouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' found in stdout: '" + matcher.group() + "' \n");
+        }
+        matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' found in stderr: '" + matcher.group() + "' \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify the exit value of the process
-   *
-   * @param expectedExitValue Expected exit value from process
-   * @throws RuntimeException If the exit value from the process did not match the expected value
-   */
-  public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
-      if (getExitValue() != expectedExitValue) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("Expected to get exit value of ["
-                  + expectedExitValue + "]\n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stdout contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' found in stdout \n");
+        }
+        return this;
+    }
 
-  /**
-   * Verify the exit value of the process
-   *
-   * @param notExpectedExitValue Unexpected exit value from process
-   * @throws RuntimeException If the exit value from the process did match the expected value
-   */
-  public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) {
-      if (getExitValue() == notExpectedExitValue) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("Unexpected to get exit value of ["
-                  + notExpectedExitValue + "]\n");
-      }
-      return this;
-  }
+    /**
+     * Verify that the stderr contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public OutputAnalyzer stderrShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' found in stderr \n");
+        }
+        return this;
+    }
 
+    /**
+     * Get the captured group of the first string matching the pattern.
+     * stderr is searched before stdout.
+     *
+     * @param pattern The multi-line pattern to match
+     * @param group The group to capture
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern, int group) {
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (stderrMatcher.find()) {
+            return stderrMatcher.group(group);
+        }
+        if (stdoutMatcher.find()) {
+            return stdoutMatcher.group(group);
+        }
+        return null;
+    }
 
-  /**
-   * Report summary that will help to diagnose the problem
-   * Currently includes:
-   *  - standard input produced by the process under test
-   *  - standard output
-   *  - exit code
-   *  Note: the command line is printed by the ProcessTools
-   */
-  public void reportDiagnosticSummary() {
-      String msg =
-          " stdout: [" + stdout + "];\n" +
-          " stderr: [" + stderr + "]\n" +
-          " exitValue = " + getExitValue() + "\n";
+    /**
+     * Get the first string matching the pattern.
+     * stderr is searched before stdout.
+     *
+     * @param pattern The multi-line pattern to match
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern) {
+        return firstMatch(pattern, 0);
+    }
 
-      System.err.println(msg);
-  }
+    /**
+     * Verify the exit value of the process
+     *
+     * @param expectedExitValue Expected exit value from process
+     * @throws RuntimeException If the exit value from the process did not match the expected value
+     */
+    public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
+        if (getExitValue() != expectedExitValue) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("Expected to get exit value of ["
+                    + expectedExitValue + "]\n");
+        }
+        return this;
+    }
 
-  /**
-   * Print the stdout buffer to the given {@code PrintStream}.
-   *
-   * @return this OutputAnalyzer
-   */
-  public OutputAnalyzer outputTo(PrintStream out) {
-      out.println(getStdout());
-      return this;
-  }
+    /**
+     * Verify the exit value of the process
+     *
+     * @param notExpectedExitValue Unexpected exit value from process
+     * @throws RuntimeException If the exit value from the process did match the expected value
+     */
+    public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) {
+        if (getExitValue() == notExpectedExitValue) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("Unexpected to get exit value of ["
+                    + notExpectedExitValue + "]\n");
+        }
+        return this;
+    }
 
-  /**
-   * Print the stderr buffer to the given {@code PrintStream}.
-   *
-   * @return this OutputAnalyzer
-   */
-  public OutputAnalyzer errorTo(PrintStream out) {
-      out.println(getStderr());
-      return this;
-  }
 
-  /**
-   * Get the contents of the output buffer (stdout and stderr)
-   *
-   * @return Content of the output buffer
-   */
-  public String getOutput() {
-    return stdout + stderr;
-  }
+    /**
+     * Report summary that will help to diagnose the problem
+     * Currently includes:
+     *  - standard input produced by the process under test
+     *  - standard output
+     *  - exit code
+     *  Note: the command line is printed by the ProcessTools
+     */
+    public void reportDiagnosticSummary() {
+        String msg =
+            " stdout: [" + stdout + "];\n" +
+            " stderr: [" + stderr + "]\n" +
+            " exitValue = " + getExitValue() + "\n";
 
-  /**
-   * Get the contents of the stdout buffer
-   *
-   * @return Content of the stdout buffer
-   */
-  public String getStdout() {
-    return stdout;
-  }
+        System.err.println(msg);
+    }
 
-  /**
-   * Get the contents of the stderr buffer
-   *
-   * @return Content of the stderr buffer
-   */
-  public String getStderr() {
-    return stderr;
-  }
+    /**
+     * Print the stdout buffer to the given {@code PrintStream}.
+     *
+     * @return this OutputAnalyzer
+     */
+    public OutputAnalyzer outputTo(PrintStream out) {
+        out.println(getStdout());
+        return this;
+    }
 
-  /**
-   * Get the process exit value
-   *
-   * @return Process exit value
-   */
-  public int getExitValue() {
-    return exitValue;
-  }
+    /**
+     * Print the stderr buffer to the given {@code PrintStream}.
+     *
+     * @return this OutputAnalyzer
+     */
+    public OutputAnalyzer errorTo(PrintStream out) {
+        out.println(getStderr());
+        return this;
+    }
 
-  /**
-   * Get the contents of the output buffer (stdout and stderr) as list of strings.
-   * Output will be split by newlines.
-   *
-   * @return Contents of the output buffer as list of strings
-   */
-  public List<String> asLines() {
-    return asLines(getOutput());
-  }
+    /**
+     * Get the contents of the output buffer (stdout and stderr)
+     *
+     * @return Content of the output buffer
+     */
+    public String getOutput() {
+        return stdout + stderr;
+    }
 
-  private List<String> asLines(String buffer) {
-    return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
-  }
+    /**
+     * Get the contents of the stdout buffer
+     *
+     * @return Content of the stdout buffer
+     */
+    public String getStdout() {
+        return stdout;
+    }
 
+    /**
+     * Get the contents of the stderr buffer
+     *
+     * @return Content of the stderr buffer
+     */
+    public String getStderr() {
+        return stderr;
+    }
 
-  private static final String jvmwarningmsg = ".* VM warning:.*";
+    /**
+     * Get the process exit value
+     *
+     * @return Process exit value
+     */
+    public int getExitValue() {
+        return exitValue;
+    }
 
-  /**
-   * Verifies that the stdout and stderr contents of output buffer are empty, after
-   * filtering out the HotSpot warning messages.
-   *
-   * @throws RuntimeException If the stdout and stderr are not empty
-   */
-  public OutputAnalyzer shouldBeEmptyIgnoreVMWarnings() {
-    if (!stdout.isEmpty()) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("stdout was not empty");
+    /**
+     * Get the contents of the output buffer (stdout and stderr) as list of strings.
+     * Output will be split by newlines.
+     *
+     * @return Contents of the output buffer as list of strings
+     */
+    public List<String> asLines() {
+        return asLines(getOutput());
     }
-    if (!stderr.replaceAll(jvmwarningmsg + "\\R", "").isEmpty()) {
-        reportDiagnosticSummary();
-        throw new RuntimeException("stderr was not empty");
+
+    private List<String> asLines(String buffer) {
+        return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
     }
-    return this;
-  }
 
-  /**
-   * Verify that the stderr contents of output buffer matches the pattern,
-   * after filtering out the Hotespot warning messages
-   *
-   * @param pattern
-   * @throws RuntimeException If the pattern was not found
-   */
-  public OutputAnalyzer stderrShouldMatchIgnoreVMWarnings(String pattern) {
-      String stderr = this.stderr.replaceAll(jvmwarningmsg + "\\R", "");
-      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
-      if (!matcher.find()) {
-          reportDiagnosticSummary();
-          throw new RuntimeException("'" + pattern
-                + "' missing from stderr \n");
-      }
-      return this;
-  }
 
-  /**
-   * Returns the contents of the output buffer (stdout and stderr), without those
-   * JVM warning msgs, as list of strings. Output is split by newlines.
-   *
-   * @return Contents of the output buffer as list of strings
-   */
-  public List<String> asLinesWithoutVMWarnings() {
-      return Arrays.asList(getOutput().split("\\R"))
-              .stream()
-              .filter(Pattern.compile(jvmwarningmsg).asPredicate().negate())
-              .collect(Collectors.toList());
-  }
+    private static final String jvmwarningmsg = ".* VM warning:.*";
+
+    /**
+     * Verifies that the stdout and stderr contents of output buffer are empty, after
+     * filtering out the HotSpot warning messages.
+     *
+     * @throws RuntimeException If the stdout and stderr are not empty
+     */
+    public OutputAnalyzer shouldBeEmptyIgnoreVMWarnings() {
+        if (!stdout.isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stdout was not empty");
+        }
+        if (!stderr.replaceAll(jvmwarningmsg + "\\R", "").isEmpty()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("stderr was not empty");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer matches the pattern,
+     * after filtering out the Hotespot warning messages
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public OutputAnalyzer stderrShouldMatchIgnoreVMWarnings(String pattern) {
+        String stderr = this.stderr.replaceAll(jvmwarningmsg + "\\R", "");
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (!matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                  + "' missing from stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Returns the contents of the output buffer (stdout and stderr), without those
+     * JVM warning msgs, as list of strings. Output is split by newlines.
+     *
+     * @return Contents of the output buffer as list of strings
+     */
+    public List<String> asLinesWithoutVMWarnings() {
+        return Arrays.asList(getOutput().split("\\R"))
+                .stream()
+                .filter(Pattern.compile(jvmwarningmsg).asPredicate().negate())
+                .collect(Collectors.toList());
+    }
 
 }