test/lib/jdk/test/lib/process/OutputBuffer.java
changeset 51675 b487c1e914d0
parent 40614 b5d80754b40e
child 55133 3f2f89737be5
child 58678 9cf78a70fa4f
--- a/test/lib/jdk/test/lib/process/OutputBuffer.java	Fri Sep 07 15:18:14 2018 -0400
+++ b/test/lib/jdk/test/lib/process/OutputBuffer.java	Fri Sep 07 14:01:52 2018 -0700
@@ -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
@@ -23,20 +23,19 @@
 
 package jdk.test.lib.process;
 
-public class OutputBuffer {
-  private final String stdout;
-  private final String stderr;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 
-  /**
-   * Create an OutputBuffer, a class for storing and managing stdout and stderr
-   * results separately
-   *
-   * @param stdout stdout result
-   * @param stderr stderr result
-   */
-  public OutputBuffer(String stdout, String stderr) {
-    this.stdout = stdout;
-    this.stderr = stderr;
+public interface OutputBuffer {
+  public static class OutputBufferException extends RuntimeException {
+    private static final long serialVersionUID = 8528687792643129571L;
+
+    public OutputBufferException(Throwable cause) {
+      super(cause);
+    }
   }
 
   /**
@@ -44,16 +43,105 @@
    *
    * @return stdout result
    */
-  public String getStdout() {
-    return stdout;
-  }
-
+  public String getStdout();
   /**
    * Returns the stderr result
    *
    * @return stderr result
    */
-  public String getStderr() {
-    return stderr;
+  public String getStderr();
+  public int getExitValue();
+
+  public static OutputBuffer of(Process p) {
+    return new LazyOutputBuffer(p);
+  }
+
+  public static OutputBuffer of(String stdout, String stderr, int exitValue) {
+    return new EagerOutputBuffer(stdout, stderr, exitValue);
+  }
+
+  public static OutputBuffer of(String stdout, String stderr) {
+    return of(stdout, stderr, -1);
+  }
+
+  class LazyOutputBuffer implements OutputBuffer {
+    private static class StreamTask {
+      private final ByteArrayOutputStream buffer;
+      private final Future<Void> future;
+
+      private StreamTask(InputStream stream) {
+        this.buffer = new ByteArrayOutputStream();
+        this.future = new StreamPumper(stream, buffer).process();
+      }
+
+      public String get() {
+        try {
+          future.get();
+          return buffer.toString();
+        } catch (InterruptedException e) {
+          Thread.currentThread().interrupt();
+          throw new OutputBufferException(e);
+        } catch (ExecutionException | CancellationException e) {
+          throw new OutputBufferException(e);
+        }
+      }
+    }
+
+    private final StreamTask outTask;
+    private final StreamTask errTask;
+    private final Process p;
+
+    private LazyOutputBuffer(Process p) {
+      this.p = p;
+      outTask = new StreamTask(p.getInputStream());
+      errTask = new StreamTask(p.getErrorStream());
+    }
+
+    @Override
+    public String getStdout() {
+      return outTask.get();
+    }
+
+    @Override
+    public String getStderr() {
+      return errTask.get();
+    }
+
+    @Override
+    public int getExitValue() {
+      try {
+        return p.waitFor();
+      } catch (InterruptedException e) {
+        Thread.currentThread().interrupt();
+        throw new OutputBufferException(e);
+      }
+    }
+  }
+
+  class EagerOutputBuffer implements OutputBuffer {
+    private final String stdout;
+    private final String stderr;
+    private final int exitValue;
+
+    private EagerOutputBuffer(String stdout, String stderr, int exitValue) {
+      this.stdout = stdout;
+      this.stderr = stderr;
+      this.exitValue = exitValue;
+    }
+
+    @Override
+    public String getStdout() {
+      return stdout;
+    }
+
+    @Override
+    public String getStderr() {
+      return stderr;
+    }
+
+    @Override
+    public int getExitValue() {
+      return exitValue;
+    }
   }
 }