• 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 junit.framework.AssertionFailedError;
21 import junit.framework.TestCase;
22 
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.Reader;
28 import java.io.StringWriter;
29 import java.util.Arrays;
30 import java.util.concurrent.Callable;
31 import java.util.concurrent.ExecutorService;
32 import java.util.concurrent.Executors;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.TimeUnit;
35 
36 public class Support_Exec extends TestCase {
37 
38     private static final boolean againstDalvik
39             = System.getProperty("java.vendor").contains("Android");
40 
41     /**
42      * Returns a builder configured with the appropriate VM ("dalvikvm" or
43      * "java") and arguments (as specified by the system property
44      * {@code hy.test.vmargs}).
45      */
javaProcessBuilder()46     public static ProcessBuilder javaProcessBuilder()
47             throws IOException, InterruptedException {
48         ProcessBuilder builder = new ProcessBuilder();
49 
50         // construct the name of executable file
51         builder.command().add(againstDalvik ? "dalvikvm" : "java");
52 
53         // parse hy.test.vmargs if was given
54         String testVMArgs = System.getProperty("hy.test.vmargs");
55         if (testVMArgs != null) {
56             builder.command().addAll(Arrays.asList(testVMArgs.split("\\s+")));
57         }
58 
59         return builder;
60     }
61 
62     /**
63      * Returns a command-line ready path formed by joining the path elements
64      * with the system path separator as a separator.
65      */
createPath(String... elements)66     public static String createPath(String... elements) {
67         StringBuilder result = new StringBuilder();
68         for (String element : elements) {
69             result.append(File.pathSeparator);
70             result.append(element);
71         }
72         return result.toString();
73     }
74 
75     /**
76      * Starts the specified process, collects its output from standard out and
77      * standard err, and returns. If the stream emits anything to standard err,
78      * an AssertionFailedError will be thrown.
79      *
80      * <p>This method assumes the target process will complete within thirty
81      * seconds. If it does not, an AssertionFailedError will be thrown.
82      */
execAndGetOutput(ProcessBuilder builder)83     public static String execAndGetOutput(ProcessBuilder builder) throws IOException {
84         Process process = builder.start();
85         ExecutorService executorService = Executors.newFixedThreadPool(2);
86         try {
87             Future<String> errFuture = executorService.submit(
88                     streamToStringCallable(process.getErrorStream()));
89             Future<String> outFuture = executorService.submit(
90                     streamToStringCallable(process.getInputStream()));
91 
92             Throwable failure;
93             String out = "";
94             try {
95                 out = outFuture.get(30, TimeUnit.SECONDS);
96                 String err = errFuture.get(30, TimeUnit.SECONDS);
97                 failure = err.length() > 0
98                         ? new AssertionFailedError("Unexpected err stream data:\n" + err)
99                         : null;
100             } catch (Exception e) {
101                 failure = e;
102             }
103 
104             if (failure != null) {
105                 AssertionFailedError error = new AssertionFailedError(
106                         "Failed to execute " + builder.command() + "; output was:\n" + out);
107                 error.initCause(failure);
108                 throw error;
109             } else {
110                 return out;
111             }
112         } finally {
113             executorService.shutdown();
114         }
115     }
116 
streamToStringCallable(final InputStream in)117     private static Callable<String> streamToStringCallable(final InputStream in) {
118         return new Callable<String>() {
119             public String call() throws Exception {
120                 StringWriter writer = new StringWriter();
121                 Reader reader = new InputStreamReader(in);
122                 int c;
123                 while ((c = reader.read()) != -1) {
124                     writer.write(c);
125                 }
126                 return writer.toString();
127             }
128         };
129     }
130 }
131