STC work in progress
Change-Id: Ie5e444e3b560b605b066899289cdee7a5fe8338c
diff --git a/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java b/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
new file mode 100644
index 0000000..b2d7635
--- /dev/null
+++ b/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onlab.stc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+
+import static org.onlab.stc.Coordinator.print;
+
+/**
+ * Manages execution of the specified step or a group.
+ */
+class StepProcessor implements Runnable {
+
+ private static final int FAIL = -1;
+
+ static String launcher = "stc-launcher ";
+
+ private final Step step;
+ private final boolean skip;
+ private final File logDir;
+
+ private Process process;
+ private StepProcessListener delegate;
+
+ /**
+ * Creates a process monitor.
+ *
+ * @param step step or group to be executed
+ * @param skip indicates the process should not actually execute
+ * @param logDir directory where step process log should be stored
+ * @param delegate process lifecycle listener
+ */
+ StepProcessor(Step step, boolean skip, File logDir, StepProcessListener delegate) {
+ this.step = step;
+ this.skip = skip;
+ this.logDir = logDir;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void run() {
+ int code = FAIL;
+ delegate.onStart(step);
+ if (!skip) {
+ code = execute();
+ }
+ delegate.onCompletion(step, code);
+ }
+
+ /**
+ * Executes the step process.
+ *
+ * @return exit code
+ */
+ private int execute() {
+ try (PrintWriter pw = new PrintWriter(logFile(step))) {
+ process = Runtime.getRuntime().exec(launcher + step.command());
+ processOutput(pw);
+
+ // Wait for the process to complete and get its exit code.
+ if (process.isAlive()) {
+ process.waitFor();
+ }
+ return process.exitValue();
+
+ } catch (IOException e) {
+ print("Unable to run step %s using command %s", step.name(), step.command());
+ } catch (InterruptedException e) {
+ print("Step %s interrupted", step.name());
+ }
+ return FAIL;
+ }
+
+ /**
+ * Captures output of the step process.
+ *
+ * @param pw print writer to send output to
+ * @throws IOException if unable to read output or write logs
+ */
+ private void processOutput(PrintWriter pw) throws IOException {
+ InputStream out = process.getInputStream();
+ BufferedReader br = new BufferedReader(new InputStreamReader(out));
+
+ // Slurp its combined stderr/stdout
+ String line;
+ while ((line = br.readLine()) != null) {
+ pw.println(line);
+ delegate.onOutput(step, line);
+ }
+ }
+
+ /**
+ * Returns the log file for the specified step.
+ *
+ * @param step test step
+ * @return log file
+ */
+ private File logFile(Step step) {
+ return new File(logDir, step.name() + ".log");
+ }
+
+}