• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package tests.support;
19 
20 import java.io.ByteArrayOutputStream;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.PrintStream;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.StringTokenizer;
28 
29 import junit.framework.TestCase;
30 
31 public class Support_Exec extends TestCase {
32 
33     /**
34      * Exec java returns the exitCode, and stdOut and stdErr as strings
35      */
runJava(List<String> args, String[] envp, boolean displayOutput)36     public static Object[] runJava(List<String> args, String[] envp,
37             boolean displayOutput)
38             throws IOException, InterruptedException {
39         String executable = System.getProperty("java.home");
40         if (!executable.endsWith(File.separator)) {
41             executable += File.separator;
42         }
43         executable += "bin" + File.separator + "java";
44 
45         // parse hy.test.vmargs if was given
46         String testVMArgs = System.getProperty("hy.test.vmargs");
47         if (testVMArgs != null) {
48             StringTokenizer st = new StringTokenizer(testVMArgs, " ");
49             int i = 0; // add at the beginning but maintain order
50             while (st.hasMoreTokens()) {
51                 args.add(i++, st.nextToken());
52             }
53         }
54 
55         return run(executable, args, envp, displayOutput);
56     }
57 
58     /**
59      * Exec command returns the exitCode, and stdOut and stdErr as strings
60      */
run(String command, List<String> args, String[] envp, boolean displayOutput)61     public static Object[] run(String command, List<String> args, String[] envp,
62             boolean displayOutput)
63             throws IOException, InterruptedException {
64         Object[] arr = exec(command, args, envp, displayOutput);
65 
66         Process proc = (Process) arr[0];
67         StringBuilder output = new StringBuilder();
68         InputStream in = proc.getInputStream();
69         int result;
70         byte[] bytes = new byte[1024];
71 
72         while ((result = in.read(bytes)) != -1) {
73             output.append(new String(bytes, 0, result));
74             if (displayOutput) {
75                 System.out.write(bytes, 0, result);
76             }
77         }
78 
79         in.close();
80         proc.waitFor();
81         int exitCode = proc.exitValue();
82         proc.destroy();
83         return new Object[] {
84                 Integer.valueOf(exitCode),
85                 output.toString(),
86                 ((StringBuilder) arr[1]).toString()
87         };
88     }
89 
90     /**
91      * This function returns the output of the process as a string
92      */
execJava(String[] args, String[] classpath, boolean displayOutput)93     public static String execJava(String[] args, String[] classpath,
94             boolean displayOutput)
95             throws IOException, InterruptedException {
96         Object[] arr =
97                 execJavaCommon(args, classpath, null, displayOutput, true);
98 
99         return getProcessOutput(arr, displayOutput, true);
100     }
101 
102     /**
103      * This function returns the output of the process as a string
104      */
execJava(String[] args, String[] classpath, String[] envp, boolean displayOutput)105     public static String execJava(String[] args, String[] classpath,
106             String[] envp, boolean displayOutput)
107             throws IOException, InterruptedException {
108         Object[] arr =
109                 execJavaCommon(args, classpath, envp, displayOutput, false);
110 
111         return getProcessOutput(arr, displayOutput, true);
112     }
113 
getProcessOutput(Object[] arr, boolean displayOutput, boolean checkStderr)114     private static String getProcessOutput(Object[] arr, boolean displayOutput,
115             boolean checkStderr)
116             throws IOException, InterruptedException {
117         Process proc = (Process) arr[0];
118         StringBuilder output = new StringBuilder();
119         InputStream in = proc.getInputStream();
120         int result;
121         byte[] bytes = new byte[1024];
122 
123         while ((result = in.read(bytes)) != -1) {
124             output.append(new String(bytes, 0, result));
125             if (displayOutput) {
126                 System.out.write(bytes, 0, result);
127             }
128         }
129 
130         in.close();
131         proc.waitFor();
132         if (checkStderr) {
133             checkStderr(arr);
134         }
135         proc.destroy();
136 
137         return output.toString();
138     }
139 
checkStderr(Object[] execArgs)140     public static void checkStderr(Object[] execArgs) {
141         StringBuilder errBuf = (StringBuilder) execArgs[1];
142 
143         synchronized (errBuf) {
144             if (errBuf.length() > 0) {
145                 fail(errBuf.toString());
146             }
147         }
148     }
149 
execJava2(String[] args, String[] classpath, boolean displayOutput)150     public static Object[] execJava2(String[] args, String[] classpath,
151             boolean displayOutput)
152             throws IOException, InterruptedException {
153         return execJavaCommon(args, classpath, null, displayOutput, true);
154     }
155 
execJavaCommon(String[] args, String[] classpath, String[] envp, boolean displayOutput, boolean appendToSystemClassPath)156     private static Object[] execJavaCommon(String[] args, String[] classpath,
157             String[] envp,
158             boolean displayOutput,
159             boolean appendToSystemClassPath)
160             throws IOException, InterruptedException {
161         // this function returns the resulting process from the exec
162         ArrayList<String> execArgs = null;
163         StringBuilder classPathString = new StringBuilder();
164         StringBuilder command;
165 
166         execArgs = new ArrayList<String>(3 + args.length);
167 
168         // construct the name of executable file
169         String executable = System.getProperty("java.home");
170         if (!executable.endsWith(File.separator)) {
171             executable += File.separator;
172         }
173         executable += "bin" + File.separator + "java";
174 
175         // add classpath string
176         if (classpath != null) {
177             for (String element : classpath) {
178                 classPathString.append(File.pathSeparator);
179                 classPathString.append(element);
180             }
181         }
182         if (appendToSystemClassPath) {
183             execArgs.add("-cp");
184             execArgs.add(System.getProperty("java.class.path") +
185                     classPathString);
186         } else {
187             if (classpath != null) {
188                 execArgs.add("-cp");
189                 execArgs.add(classPathString.toString());
190             }
191         }
192 
193         // parse hy.test.vmargs if was given
194         String testVMArgs = System.getProperty("hy.test.vmargs");
195         if (testVMArgs != null) {
196             StringTokenizer st = new StringTokenizer(testVMArgs, " ");
197 
198             while (st.hasMoreTokens()) {
199                 execArgs.add(st.nextToken());
200             }
201         }
202 
203         // add custom args given as parameter
204         for (String arg : args) {
205             execArgs.add(arg);
206         }
207         return exec(executable, execArgs, envp, displayOutput);
208     }
209 
exec(String command, List<String> args, String[] envp, boolean displayOutput)210     private static Object[] exec(String command, List<String> args,
211             String[] envp,
212             boolean displayOutput)
213             throws IOException, InterruptedException {
214         // this function returns the resulting process from the exec
215         args.add(0, command);
216 
217         if (displayOutput) {
218             StringBuilder commandLine;
219             // construct command line string and print it to stdout
220             commandLine = new StringBuilder(args.get(0));
221             for (int i = 1; i < args.size(); i++) {
222                 commandLine.append(" ");
223                 commandLine.append(args.get(i));
224             }
225             System.out.println("Exec: " + commandLine.toString());
226             System.out.println();
227         }
228 
229         // execute java process
230         final Process proc =
231                 Runtime.getRuntime().exec(args.toArray(new String[args.size()]),
232                         envp);
233 
234         final StringBuilder errBuf = new StringBuilder();
235         Thread errThread = new Thread(new Runnable() {
236             public void run() {
237                 synchronized (errBuf) {
238                     InputStream err;
239                     int result;
240                     byte[] bytes = new byte[1024];
241 
242                     synchronized (proc) {
243                         proc.notifyAll();
244                     }
245 
246                     err = proc.getErrorStream();
247                     try {
248                         while ((result = err.read(bytes)) != -1) {
249                             System.err.write(bytes, 0, result);
250                             errBuf.append(new String(bytes));
251                         }
252                         err.close();
253                     } catch (IOException e) {
254                         ByteArrayOutputStream out =
255                                 new ByteArrayOutputStream();
256                         PrintStream printer = new PrintStream(out);
257 
258                         e.printStackTrace();
259                         e.printStackTrace(printer);
260                         printer.close();
261                         errBuf.append(new String(out.toByteArray()));
262                     }
263                 }
264             }
265         });
266 
267         synchronized (proc) {
268             errThread.start();
269             // wait for errThread to start
270             int count = 0;
271             boolean isFinished = false;
272             while (!isFinished) {
273                 try {
274                     proc.wait();
275                     isFinished = true;
276                 } catch (InterruptedException e) {
277                     if (++count == 2) {
278                         throw e;
279                     }
280                 }
281             }
282             if (count > 0) {
283                 Thread.currentThread().interrupt();
284             }
285         }
286         return new Object[] { proc, errBuf };
287     }
288 }
289