@Override public int join() throws IOException, InterruptedException { return proc.isAlive() ? 0 : -1; }
@Override public void kill() throws IOException, InterruptedException { try { // What we actually do is send a ctrl-c to the current process and then exit the shell. watch.getInput().write(CTRL_C); watch.getInput().write(EXIT.getBytes(StandardCharsets.UTF_8)); watch.getInput().write(NEWLINE.getBytes(StandardCharsets.UTF_8)); watch.getInput().flush(); } catch (IOException e) { LOGGER.log(Level.FINE, "Proc kill failed, ignoring", e); } finally { close(); } }
private ProcReturn execCommand(boolean quiet, String... cmd) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); Launcher launcher = decorator .decorate(new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out))), null); ContainerExecProc proc = (ContainerExecProc) launcher .launch(launcher.new ProcStarter().pwd("/tmp").cmds(cmd).quiet(quiet)); // wait for proc to finish (shouldn't take long) while (proc.isAlive()) { Thread.sleep(100); } assertFalse("proc is alive", proc.isAlive()); int exitCode = proc.joinWithTimeout(10, TimeUnit.SECONDS, StreamTaskListener.fromStderr()); return new ProcReturn(proc, exitCode, out.toString()); }
ContainerExecProc proc = new ContainerExecProc(watch, alive, finished, error); processes.put(pid, proc); closables.add(proc);
@Test public void testCommandExecutionWithEscaping() throws Exception { ProcReturn r = execCommand(false, "sh", "-c", "cd /tmp; false; echo result is $$? > test; cat /tmp/test"); assertTrue("Output should contain result: " + r.output, Pattern.compile("^(result is 1)$", Pattern.MULTILINE).matcher(r.output).find()); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); }
return -1; } finally { close();
@Test public void testCommandExecutionWithNohup() throws Exception { ProcReturn r = execCommand(false, "nohup", "sh", "-c", "sleep 5; cd /tmp; echo pid is $$$$ > test; cat /tmp/test"); assertTrue("Output should contain pid: " + r.output, PID_PATTERN.matcher(r.output).find()); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); }
@Test public void testQuietCommandExecution() throws Exception { ProcReturn r = execCommand(true, "echo", "pid is 9999"); assertFalse("Output should not contain command: " + r.output, PID_PATTERN.matcher(r.output).find()); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); }
/** * Test that multiple command execution in parallel works * @throws Exception */ @Test(timeout = 10000) public void testCommandExecution() throws Exception { Thread[] t = new Thread[10]; List<ProcReturn> results = Collections.synchronizedList(new ArrayList<>(t.length)); for (int i = 0; i < t.length; i++) { t[i] = newThread(i, results); } for (int i = 0; i < t.length; i++) { t[i].start(); } for (int i = 0; i < t.length; i++) { t[i].join(); } assertEquals("Not all threads finished successfully", t.length, results.size()); for (ProcReturn r : results) { assertTrue("Output should contain pid: " + r.output, PID_PATTERN.matcher(r.output).find()); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } }
@Test public void testCommandExecutionFailureHighError() throws Exception { ProcReturn r = execCommand(false, "sh", "-c", "return 127"); assertEquals(127, r.exitCode); assertFalse(r.proc.isAlive()); }
@Test public void testCommandExecutionFailure() throws Exception { ProcReturn r = execCommand(false, "false"); assertEquals(1, r.exitCode); assertFalse(r.proc.isAlive()); }
@Test public void testCommandExecutionWithNohupAndError() throws Exception { ProcReturn r = execCommand(false, "nohup", "sh", "-c", "sleep 5; return 127"); assertEquals(127, r.exitCode); assertFalse(r.proc.isAlive()); }