1 /* |
1 /* |
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
23 |
23 |
24 package jdk.test.lib.process; |
24 package jdk.test.lib.process; |
25 |
25 |
26 import java.io.ByteArrayOutputStream; |
26 import java.io.ByteArrayOutputStream; |
27 import java.io.InputStream; |
27 import java.io.InputStream; |
|
28 import java.nio.charset.Charset; |
|
29 import java.time.Instant; |
28 import java.util.concurrent.CancellationException; |
30 import java.util.concurrent.CancellationException; |
29 import java.util.concurrent.ExecutionException; |
31 import java.util.concurrent.ExecutionException; |
30 import java.util.concurrent.Future; |
32 import java.util.concurrent.Future; |
31 |
33 |
32 public interface OutputBuffer { |
34 public interface OutputBuffer { |
50 * @return stderr result |
52 * @return stderr result |
51 */ |
53 */ |
52 public String getStderr(); |
54 public String getStderr(); |
53 public int getExitValue(); |
55 public int getExitValue(); |
54 |
56 |
|
57 public static OutputBuffer of(Process p, Charset cs) { |
|
58 return new LazyOutputBuffer(p, cs); |
|
59 } |
|
60 |
55 public static OutputBuffer of(Process p) { |
61 public static OutputBuffer of(Process p) { |
56 return new LazyOutputBuffer(p); |
62 return new LazyOutputBuffer(p, null); |
57 } |
63 } |
58 |
64 |
59 public static OutputBuffer of(String stdout, String stderr, int exitValue) { |
65 public static OutputBuffer of(String stdout, String stderr, int exitValue) { |
60 return new EagerOutputBuffer(stdout, stderr, exitValue); |
66 return new EagerOutputBuffer(stdout, stderr, exitValue); |
61 } |
67 } |
66 |
72 |
67 class LazyOutputBuffer implements OutputBuffer { |
73 class LazyOutputBuffer implements OutputBuffer { |
68 private static class StreamTask { |
74 private static class StreamTask { |
69 private final ByteArrayOutputStream buffer; |
75 private final ByteArrayOutputStream buffer; |
70 private final Future<Void> future; |
76 private final Future<Void> future; |
|
77 private final Charset cs; |
71 |
78 |
72 private StreamTask(InputStream stream) { |
79 private StreamTask(InputStream stream, Charset cs) { |
73 this.buffer = new ByteArrayOutputStream(); |
80 this.buffer = new ByteArrayOutputStream(); |
|
81 this.cs = cs; |
74 this.future = new StreamPumper(stream, buffer).process(); |
82 this.future = new StreamPumper(stream, buffer).process(); |
75 } |
83 } |
76 |
84 |
77 public String get() { |
85 public String get() { |
78 try { |
86 try { |
79 future.get(); |
87 future.get(); |
80 return buffer.toString(); |
88 return cs == null ? buffer.toString() : buffer.toString(cs); |
81 } catch (InterruptedException e) { |
89 } catch (InterruptedException e) { |
82 Thread.currentThread().interrupt(); |
90 Thread.currentThread().interrupt(); |
83 throw new OutputBufferException(e); |
91 throw new OutputBufferException(e); |
84 } catch (ExecutionException | CancellationException e) { |
92 } catch (ExecutionException | CancellationException e) { |
85 throw new OutputBufferException(e); |
93 throw new OutputBufferException(e); |
89 |
97 |
90 private final StreamTask outTask; |
98 private final StreamTask outTask; |
91 private final StreamTask errTask; |
99 private final StreamTask errTask; |
92 private final Process p; |
100 private final Process p; |
93 |
101 |
94 private LazyOutputBuffer(Process p) { |
102 private final void logProgress(String state) { |
|
103 System.out.println("[" + Instant.now().toString() + "] " + state |
|
104 + " for process " + p.pid()); |
|
105 System.out.flush(); |
|
106 } |
|
107 |
|
108 private LazyOutputBuffer(Process p, Charset cs) { |
95 this.p = p; |
109 this.p = p; |
96 outTask = new StreamTask(p.getInputStream()); |
110 logProgress("Gathering output"); |
97 errTask = new StreamTask(p.getErrorStream()); |
111 outTask = new StreamTask(p.getInputStream(), cs); |
|
112 errTask = new StreamTask(p.getErrorStream(), cs); |
98 } |
113 } |
99 |
114 |
100 @Override |
115 @Override |
101 public String getStdout() { |
116 public String getStdout() { |
102 return outTask.get(); |
117 return outTask.get(); |
108 } |
123 } |
109 |
124 |
110 @Override |
125 @Override |
111 public int getExitValue() { |
126 public int getExitValue() { |
112 try { |
127 try { |
113 return p.waitFor(); |
128 logProgress("Waiting for completion"); |
|
129 boolean aborted = true; |
|
130 try { |
|
131 int result = p.waitFor(); |
|
132 logProgress("Waiting for completion finished"); |
|
133 aborted = false; |
|
134 return result; |
|
135 } finally { |
|
136 if (aborted) { |
|
137 logProgress("Waiting for completion FAILED"); |
|
138 } |
|
139 } |
114 } catch (InterruptedException e) { |
140 } catch (InterruptedException e) { |
115 Thread.currentThread().interrupt(); |
141 Thread.currentThread().interrupt(); |
116 throw new OutputBufferException(e); |
142 throw new OutputBufferException(e); |
117 } |
143 } |
118 } |
144 } |