summaryrefslogtreecommitdiffstats
path: root/jack-tests/src/com/android/jack/test/util/ExecuteFile.java
diff options
context:
space:
mode:
authorJean-Marie Henaff <jmhenaff@google.com>2014-05-19 17:34:13 +0200
committerJean-Marie Henaff <jmhenaff@google.com>2014-10-14 10:35:18 +0200
commitf265ce821c48ed54ad8d00060664b55a8f8e1bb7 (patch)
tree798f4464e8669ce31fbd5bbe0a2e3404d4e47ff1 /jack-tests/src/com/android/jack/test/util/ExecuteFile.java
parent706b60417fe72a4a70bc61da2f915fe3693dd0c2 (diff)
downloadtoolchain_jack-f265ce821c48ed54ad8d00060664b55a8f8e1bb7.zip
toolchain_jack-f265ce821c48ed54ad8d00060664b55a8f8e1bb7.tar.gz
toolchain_jack-f265ce821c48ed54ad8d00060664b55a8f8e1bb7.tar.bz2
WIP Use JUnit for jack-tests.
(cherry picked from commit 452cbd7d69db557ecdbbd20875a669752cf2d9d7) Change-Id: I96a34b90c9525fa4403f6f940d6fcdf4656722ab
Diffstat (limited to 'jack-tests/src/com/android/jack/test/util/ExecuteFile.java')
-rw-r--r--jack-tests/src/com/android/jack/test/util/ExecuteFile.java292
1 files changed, 292 insertions, 0 deletions
diff --git a/jack-tests/src/com/android/jack/test/util/ExecuteFile.java b/jack-tests/src/com/android/jack/test/util/ExecuteFile.java
new file mode 100644
index 0000000..1f59b63
--- /dev/null
+++ b/jack-tests/src/com/android/jack/test/util/ExecuteFile.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.test.util;
+
+import com.android.sched.util.log.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+/**
+ * Class to handle the execution of an external process
+ */
+public class ExecuteFile {
+ @Nonnull
+ private final String[] cmdLine;
+
+ @Nonnull
+ List<String> env = new ArrayList<String>(0);
+
+ @CheckForNull
+ private File workDir;
+
+ @CheckForNull
+ private InputStream inStream;
+ private boolean inToBeClose;
+
+ @CheckForNull
+ private OutputStream outStream;
+ private boolean outToBeClose;
+
+ @CheckForNull
+ private OutputStream errStream;
+ private boolean errToBeClose;
+ private boolean verbose;
+
+ @Nonnull
+ private final Logger logger;
+
+ public void setErr(@Nonnull File file) throws FileNotFoundException {
+ errStream = new FileOutputStream(file);
+ errToBeClose = true;
+ }
+
+ public void setOut(@Nonnull File file) throws FileNotFoundException {
+ outStream = new FileOutputStream(file);
+ outToBeClose = true;
+ }
+
+ public void setIn(@Nonnull File file) throws FileNotFoundException {
+ inStream = new FileInputStream(file);
+ inToBeClose = true;
+ }
+
+ public void setErr(@Nonnull OutputStream stream) {
+ errStream = stream;
+ }
+
+ public void setOut(@Nonnull OutputStream stream) {
+ outStream = stream;
+ }
+
+ public void setIn(@Nonnull InputStream stream) {
+ inStream = stream;
+ }
+
+ public void setWorkingDir(@Nonnull File dir, boolean create) throws IOException {
+ if (!dir.isDirectory()) {
+ if (create && !dir.exists()) {
+ if (!dir.mkdirs()) {
+ throw new IOException("Directory creation failed");
+ }
+ } else {
+ throw new FileNotFoundException(dir.getPath() + " is not a directory");
+ }
+ }
+
+ workDir = dir;
+ }
+
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ public void addEnvVar(@Nonnull String key, @Nonnull String value) {
+ env.add(key + "=" + value);
+ }
+
+ public ExecuteFile(@Nonnull File exec, @Nonnull String[] args) {
+ cmdLine = new String[args.length + 1];
+ System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+ cmdLine[0] = exec.getAbsolutePath();
+ logger = LoggerFactory.getLogger();
+ }
+
+ public ExecuteFile(@Nonnull String exec, @Nonnull String[] args) {
+ cmdLine = new String[args.length + 1];
+ System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+ cmdLine[0] = exec;
+ logger = LoggerFactory.getLogger();
+ }
+
+ public ExecuteFile(@Nonnull File exec) {
+ cmdLine = new String[1];
+ cmdLine[0] = exec.getAbsolutePath();
+ logger = LoggerFactory.getLogger();
+ }
+
+ public ExecuteFile(@Nonnull String[] cmdLine) {
+ this.cmdLine = cmdLine.clone();
+ logger = LoggerFactory.getLogger();
+ }
+
+ public ExecuteFile(@Nonnull String cmdLine) throws IOException {
+ StringReader reader = new StringReader(cmdLine);
+ StreamTokenizer tokenizer = new StreamTokenizer(reader);
+ tokenizer.resetSyntax();
+ // Only standard spaces are recognized as whitespace chars
+ tokenizer.whitespaceChars(' ', ' ');
+ // Matches alphanumerical and common special symbols like '(' and ')'
+ tokenizer.wordChars('!', 'z');
+ // Quote chars will be ignored when parsing strings
+ tokenizer.quoteChar('\'');
+ tokenizer.quoteChar('\"');
+ ArrayList<String> tokens = new ArrayList<String>();
+ while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+ String token = tokenizer.sval;
+ if (token != null) {
+ tokens.add(token);
+ }
+ }
+ this.cmdLine = tokens.toArray(new String[0]);
+ logger = LoggerFactory.getLogger();
+ }
+
+ public int run() throws ExecFileException {
+ int ret;
+ Process proc = null;
+ Thread suckOut = null;
+ Thread suckErr = null;
+ Thread suckIn = null;
+
+ try {
+ StringBuilder cmdLineBuilder = new StringBuilder();
+ for (String envElt : env) {
+ cmdLineBuilder.append(envElt).append(' ');
+ }
+ for (String arg : cmdLine) {
+ cmdLineBuilder.append(arg).append(' ');
+ }
+ if (verbose) {
+ PrintStream printStream;
+ if (outStream instanceof PrintStream) {
+ printStream = (PrintStream) outStream;
+ } else {
+ printStream = System.out;
+ }
+
+ if (printStream != null) {
+ printStream.println(cmdLineBuilder);
+ }
+ } else {
+ logger.log(Level.INFO, "Execute: {0}", cmdLineBuilder);
+ }
+
+ proc = Runtime.getRuntime().exec(cmdLine, env.toArray(new String[env.size()]), workDir);
+
+ InputStream localInStream = inStream;
+ if (localInStream != null) {
+ suckIn = new Thread(
+ new ThreadBytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose));
+ } else {
+ proc.getOutputStream().close();
+ }
+
+ OutputStream localOutStream = outStream;
+ if (localOutStream != null) {
+ if (localOutStream instanceof PrintStream) {
+ suckOut = new Thread(new ThreadCharactersStreamSucker(proc.getInputStream(),
+ (PrintStream) localOutStream, outToBeClose));
+ } else {
+ suckOut = new Thread(
+ new ThreadBytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose));
+ }
+ }
+
+ OutputStream localErrStream = errStream;
+ if (localErrStream != null) {
+ if (localErrStream instanceof PrintStream) {
+ suckErr = new Thread(new ThreadCharactersStreamSucker(proc.getErrorStream(),
+ (PrintStream) localErrStream, errToBeClose));
+ } else {
+ suckErr = new Thread(
+ new ThreadBytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose));
+ }
+ }
+
+ if (suckIn != null) {
+ suckIn.start();
+ }
+ if (suckOut != null) {
+ suckOut.start();
+ }
+ if (suckErr != null) {
+ suckErr.start();
+ }
+
+ proc.waitFor();
+ if (suckIn != null) {
+ suckIn.join();
+ }
+ if (suckOut != null) {
+ suckOut.join();
+ }
+ if (suckErr != null) {
+ suckErr.join();
+ }
+
+ ret = proc.exitValue();
+ proc.destroy();
+
+ return ret;
+ } catch (Exception e) {
+ throw new ExecFileException(cmdLine, e);
+ }
+ }
+
+ private static class ThreadBytesStreamSucker extends BytesStreamSucker implements Runnable {
+
+ public ThreadBytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os,
+ boolean toBeClose) {
+ super(is, os, toBeClose);
+ }
+
+ @Override
+ public void run() {
+ try {
+ suck();
+ } catch (IOException e) {
+ // Best effort
+ }
+ }
+ }
+
+ private static class ThreadCharactersStreamSucker extends CharactersStreamSucker implements
+ Runnable {
+
+ public ThreadCharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream ps,
+ boolean toBeClose) {
+ super(is, ps, toBeClose);
+ }
+
+ @Override
+ public void run() {
+ try {
+ suck();
+ } catch (IOException e) {
+ // Best effort
+ }
+ }
+ }
+} \ No newline at end of file