blob: b2d763527a80cb7e4b53013d1bdabd5e2e2069ff [file] [log] [blame]
Thomas Vachuskaf9c84362015-04-15 11:20:45 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onlab.stc;
17
18import java.io.BufferedReader;
19import java.io.File;
20import java.io.IOException;
21import java.io.InputStream;
22import java.io.InputStreamReader;
23import java.io.PrintWriter;
24
25import static org.onlab.stc.Coordinator.print;
26
27/**
28 * Manages execution of the specified step or a group.
29 */
30class StepProcessor implements Runnable {
31
32 private static final int FAIL = -1;
33
34 static String launcher = "stc-launcher ";
35
36 private final Step step;
37 private final boolean skip;
38 private final File logDir;
39
40 private Process process;
41 private StepProcessListener delegate;
42
43 /**
44 * Creates a process monitor.
45 *
46 * @param step step or group to be executed
47 * @param skip indicates the process should not actually execute
48 * @param logDir directory where step process log should be stored
49 * @param delegate process lifecycle listener
50 */
51 StepProcessor(Step step, boolean skip, File logDir, StepProcessListener delegate) {
52 this.step = step;
53 this.skip = skip;
54 this.logDir = logDir;
55 this.delegate = delegate;
56 }
57
58 @Override
59 public void run() {
60 int code = FAIL;
61 delegate.onStart(step);
62 if (!skip) {
63 code = execute();
64 }
65 delegate.onCompletion(step, code);
66 }
67
68 /**
69 * Executes the step process.
70 *
71 * @return exit code
72 */
73 private int execute() {
74 try (PrintWriter pw = new PrintWriter(logFile(step))) {
75 process = Runtime.getRuntime().exec(launcher + step.command());
76 processOutput(pw);
77
78 // Wait for the process to complete and get its exit code.
79 if (process.isAlive()) {
80 process.waitFor();
81 }
82 return process.exitValue();
83
84 } catch (IOException e) {
85 print("Unable to run step %s using command %s", step.name(), step.command());
86 } catch (InterruptedException e) {
87 print("Step %s interrupted", step.name());
88 }
89 return FAIL;
90 }
91
92 /**
93 * Captures output of the step process.
94 *
95 * @param pw print writer to send output to
96 * @throws IOException if unable to read output or write logs
97 */
98 private void processOutput(PrintWriter pw) throws IOException {
99 InputStream out = process.getInputStream();
100 BufferedReader br = new BufferedReader(new InputStreamReader(out));
101
102 // Slurp its combined stderr/stdout
103 String line;
104 while ((line = br.readLine()) != null) {
105 pw.println(line);
106 delegate.onOutput(step, line);
107 }
108 }
109
110 /**
111 * Returns the log file for the specified step.
112 *
113 * @param step test step
114 * @return log file
115 */
116 private File logFile(Step step) {
117 return new File(logDir, step.name() + ".log");
118 }
119
120}