1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.aludratest.service.cmdline.impl;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.aludratest.exception.AutomationException;
27 import org.aludratest.exception.FunctionalFailure;
28 import org.aludratest.exception.TechnicalException;
29 import org.aludratest.service.Action;
30 import org.aludratest.service.SystemConnector;
31 import org.aludratest.service.cmdline.CommandLineCondition;
32 import org.aludratest.service.cmdline.CommandLineInteraction;
33 import org.aludratest.service.cmdline.CommandLineService;
34 import org.aludratest.service.cmdline.CommandLineVerification;
35 import org.aludratest.testcase.event.attachment.Attachment;
36 import org.databene.commons.IOUtil;
37 import org.databene.commons.Validator;
38
39
40
41 public class CommandLineActionImpl implements CommandLineInteraction, CommandLineVerification, CommandLineCondition {
42
43 private CommandLineServiceConfiguration configuration;
44
45 private int lastProcessId;
46 private Map<Integer, ProcessWrapper> processes;
47
48
49
50
51
52 CommandLineActionImpl(CommandLineServiceConfiguration configuration) {
53 this.configuration = configuration;
54 this.lastProcessId = 0;
55 this.processes = new HashMap<Integer, ProcessWrapper>();
56 }
57
58 @Override
59 public void setSystemConnector(SystemConnector systemConnector) {
60
61 }
62
63
64
65 @Override
66 public int create(String processType, String processName, int processTimeout, int responseTimeout, String... command) {
67 int processId = ++lastProcessId;
68 ProcessWrapper process = new ProcessWrapper(processId, processTimeout, responseTimeout, command);
69 processes.put(processId, process);
70 return processId;
71 }
72
73 @Override
74 public void start(String processType, String processName, int processId) {
75 ProcessWrapper process = getProcess(processId);
76 try {
77 process.start();
78 }
79 catch (IOException e) {
80 throw new AutomationException("Error executing command: " + process, e);
81 }
82 }
83
84 @Override
85 public void assertNextLineOfStdOutMatches(String processType, String processName, int processId, Validator<String> validator) {
86 String line = readLineOfStdOut(processType, processName, processId);
87 if (!validator.valid(line)) {
88 ProcessWrapper process = getProcess(processId);
89 throw new FunctionalFailure("Standard output of process " + process + " is not accepted by " + validator + ": "
90 + line);
91 }
92 }
93
94 @Override
95 public void assertEmptyStdOut(String processType, String processName, int processId) {
96 ProcessWrapper process = getProcess(processId);
97 if (process.getStdOut().availableWithinTimeout()) {
98 throw new FunctionalFailure("Unexpected output of process " + process + ": " + readLineOfStdOut(process));
99 }
100 }
101
102 @Override
103 public String readLineOfStdOut(String processType, String processName, int processId) {
104 ProcessWrapper process = getProcess(processId);
105 return readLineOfStdOut(process);
106 }
107
108 @Override
109 public void assertNextLineOfErrOutMatches(String processType, String processName, int processId, Validator<String> validator) {
110 String line = readLineOfErrOut(processType, processName, processId);
111 if (!validator.valid(line)) {
112 ProcessWrapper process = getProcess(processId);
113 throw new FunctionalFailure("Error output of process " + process + " is not accepted by " + validator + ": " + line);
114 }
115 }
116
117 @Override
118 public void assertEmptyErrOut(String processType, String processName, int processId) {
119 ProcessWrapper process = getProcess(processId);
120 if (process.getErrOut().availableWithinTimeout()) {
121 throw new FunctionalFailure("Unexpected error output of process " + process + ": " + readLineOfErrOut(process));
122 }
123 }
124
125 @Override
126 public void assertExitCodeEquals(String processType, String processName, int processId, int expectedValue) {
127 ProcessWrapper process = getProcess(processId);
128 int actualValue = process.waitUntilFinished();
129 if (actualValue != expectedValue) {
130 throw new FunctionalFailure("Unexpected exit value. Expected " + expectedValue + ", but encountered " + actualValue);
131 }
132 }
133
134 @Override
135 public void setRelativeWorkingDirectory(String processType, String processName, int processId, String relativeWorkingDirectory) {
136 try {
137 File workingDirectory = new File(configuration.getBaseDirectory(), relativeWorkingDirectory);
138 workingDirectory = workingDirectory.getCanonicalFile();
139 getProcess(processId).setWorkingDirectory(workingDirectory);
140 }
141 catch (IOException e) {
142 throw new AutomationException("Error setting working directory", e);
143 }
144 }
145
146 @Override
147 public void setEnvironmentVariable(String processType, String processName, int processId, String key, String value) {
148 getProcess(processId).setEnvironmentVariable(key, value);
149 }
150
151 @Override
152 public void redirectStdOutTo(String processType, String processName, int processId, OutputStream out) {
153 redirect(getProcess(processId).getStdOut(), out);
154 }
155
156 @Override
157 public void redirectErrOutTo(String processType, String processName, int processId, OutputStream out) {
158 redirect(getProcess(processId).getErrOut(), out);
159 }
160
161 @Override
162 public void redirectStdInFrom(String processType, String processName, int processId, InputStream in) {
163 try {
164 ProcessWrapper process = getProcess(processId);
165 OutputStream stdIn = process.getStdIn();
166 IOUtil.transfer(in, stdIn);
167 stdIn.flush();
168 }
169 catch (IOException e) {
170 throw new TechnicalException("Error redirecting stdout", e);
171 }
172 }
173
174 @Override
175 public void skipStdOutUntilLineMatches(String processType, String processName, int processId, Validator<String> validator) {
176 ProcessWrapper process = getProcess(processId);
177 skipUntilOutputMatches(validator, process, process.getStdOut());
178 }
179
180 @Override
181 public String readLineOfErrOut(String processType, String processName, int processId) {
182 ProcessWrapper process = getProcess(processId);
183 return readLineOfErrOut(process);
184 }
185
186 @Override
187 public void skipErrOutUntilLineMatches(String processType, String processName, int processId, Validator<String> validator) {
188 ProcessWrapper process = getProcess(processId);
189 skipUntilOutputMatches(validator, process, process.getErrOut());
190 }
191
192 @Override
193 public void enter(String processType, String processName, int processId, String text) {
194 getProcess(processId).enter(text);
195 }
196
197 @Override
198 public int waitUntilFinished(String processType, String processName, int processId) {
199 return getProcess(processId).waitUntilFinished();
200 }
201
202 @Override
203 public void destroy(String processType, String processName, int processId) {
204 getProcess(processId).destroy();
205 }
206
207
208
209 @Override
210 public List<Attachment> createDebugAttachments() {
211
212 return null;
213 }
214
215 @Override
216 public List<Attachment> createAttachments(Object object, String title) {
217
218 return null;
219 }
220
221
222
223 private ProcessWrapper getProcess(int processId) {
224 ProcessWrapper process = processes.get(processId);
225 if (process == null) {
226 throw new AutomationException("Invalid process id: " + processId);
227 }
228 return process;
229 }
230
231 private String readLineOfStdOut(ProcessWrapper process) {
232 ProcessOutputReader reader = process.getStdOut();
233 try {
234 return reader.readLine();
235 }
236 catch (IOException e) {
237 throw new TechnicalException("Error reading stdout of process: " + process, e);
238 }
239 }
240
241 private String readLineOfErrOut(ProcessWrapper process) {
242 try {
243 return process.getErrOut().readLine();
244 }
245 catch (IOException e) {
246 throw new TechnicalException("Error reading errout of process " + process, e);
247 }
248 }
249
250 private void skipUntilOutputMatches(Validator<String> validator, ProcessWrapper process, ProcessOutputReader reader) {
251 String line;
252 do {
253 try {
254 if (reader.availableWithinTimeout()) {
255 line = reader.readLine();
256 }
257 else {
258
259 throw new FunctionalFailure("Process '" + process + "' did not provide an output on " + reader
260 + " that is accepted by " + validator);
261 }
262 }
263 catch (IOException e) {
264 throw new TechnicalException("Error reading " + reader + " of process " + process, e);
265 }
266 }
267 while (!validator.valid(line));
268 reader.pushBackLine(line);
269 }
270
271 private void redirect(ProcessOutputReader reader, OutputStream out) {
272 try {
273 reader.redirectTo(out);
274 }
275 catch (IOException e) {
276 throw new TechnicalException("Error redirecting " + reader, e);
277 }
278 }
279
280 }