/** * Set a suspend handler, this handler is called when the command is suspended, for instance user * press <code>Ctrl-Z</code>. * @param handler the interrupt handler * @return this command */ public io.vertx.rxjava.ext.shell.command.CommandProcess suspendHandler(Handler<Void> handler) { delegate.suspendHandler(handler); return this; }
/** * Set a suspend handler, this handler is called when the command is suspended, for instance user * press <code>Ctrl-Z</code>. * @param handler the interrupt handler * @return this command */ public io.vertx.rxjava.ext.shell.command.CommandProcess suspendHandler(Handler<Void> handler) { delegate.suspendHandler(handler); return this; }
private void scheduleSleep(CommandProcess process, long millis) { Vertx vertx = process.vertx(); if (millis > 0) { long now = System.currentTimeMillis(); AtomicLong remaining = new AtomicLong(-1); long id = process.vertx().setTimer(millis, v -> { process.end(); }); process.suspendHandler(v -> { vertx.cancelTimer(id); remaining.set(millis - (System.currentTimeMillis() - now)); }); process.resumeHandler(v -> { scheduleSleep(process, remaining.get()); }); process.interruptHandler(v -> { process.end(); }); process.endHandler(v -> { vertx.cancelTimer(id); }); } else { process.end(); } } }
Job job = shell.jobController().getJob(1); context.assertTrue(process.isForeground()); process.suspendHandler(v -> { context.assertFalse(process.isForeground()); context.assertEquals(0L, latch1.getCount());
cmdProcess.set(process); cmdContext.set(Vertx.currentContext()); process.suspendHandler(v -> fooSusp.complete()); process.resumeHandler(v -> fooResumed.complete()); process.endHandler(v -> {
@Test public void testSendEvent(TestContext context) { CountDownLatch latch = new CountDownLatch(1); commands.add(CommandBuilder.command("foo").processHandler(process -> { process.suspendHandler(v -> { process.end(0); }); latch.countDown(); })); Shell shell = server.createShell(); Job job = shell.createJob("foo"); Async async = context.async(); Pty pty = Pty.create(); job.setTty(pty.slave()).statusUpdateHandler(CommandProcessTest.terminateHandler(status -> { async.complete(); })).run(); try { latch.await(10, TimeUnit.SECONDS); } catch (InterruptedException e) { context.fail(e); } job.suspend(); }
@Test public void testSuspendRunningProcess(TestContext context) throws Exception { CommandBuilder builder = CommandBuilder.command("hello"); AtomicInteger status = new AtomicInteger(); Async suspendedLatch = context.async(2); Async runningLatch = context.async(); builder.processHandler(process -> { context.assertEquals(0, status.getAndIncrement()); process.suspendHandler(v -> suspendedLatch.complete()); runningLatch.complete(); }); Context ctx = vertx.getOrCreateContext(); Process process = createProcessInContext(ctx, builder.build(vertx)); process.run(); runningLatch.awaitSuccess(10000); process.suspend(v -> { context.assertEquals(ctx, Vertx.currentContext()); context.assertEquals(1, status.getAndIncrement()); suspendedLatch.countDown(); }); }
@Test public void testResumeSuspendedProcess(TestContext context) throws Exception { CommandBuilder builder = CommandBuilder.command("hello"); AtomicInteger status = new AtomicInteger(); Async runningLatch = context.async(); Async suspendedLatch = context.async(); Async resumedLatch = context.async(2); builder.processHandler(process -> { process.suspendHandler(v -> { suspendedLatch.complete(); }); process.resumeHandler(v -> { context.assertEquals(0, status.getAndIncrement()); resumedLatch.countDown(); }); runningLatch.complete(); }); Context ctx = vertx.getOrCreateContext(); Process process = createProcessInContext(ctx, builder.build(vertx)); process.run(); runningLatch.awaitSuccess(10000); process.suspend(); suspendedLatch.awaitSuccess(10000); process.resume(v -> { context.assertEquals(ctx, Vertx.currentContext()); context.assertEquals(1, status.getAndIncrement()); resumedLatch.countDown(); }); }
Async terminatedLatch = context.async(); builder.processHandler(process -> { process.suspendHandler(v -> suspendedLatch.complete()); process.endHandler(v -> { context.assertEquals(0, status.getAndIncrement());
@Test public void testSuspendSuspendedProcess(TestContext context) { CommandBuilder builder = CommandBuilder.command("hello"); Async suspendedLatch = context.async(); Async runningLatch = context.async(); builder.processHandler(process -> { process.suspendHandler(v -> suspendedLatch.complete()); runningLatch.complete(); }); Process process = builder.build(vertx).createProcess().setSession(Session.create()).setTty(Pty.create().slave()); process.run(); runningLatch.awaitSuccess(10000); process.suspend(); suspendedLatch.awaitSuccess(10000); try { process.suspend(); context.fail(); } catch (Exception ignore) { } }
@Test public void testRunSuspendedProcess(TestContext context) { CommandBuilder builder = CommandBuilder.command("hello"); Async suspendedLatch = context.async(); Async runningLatch = context.async(); builder.processHandler(process -> { process.suspendHandler(v -> suspendedLatch.complete()); runningLatch.complete(); }); Process process = builder.build(vertx).createProcess().setSession(Session.create()).setTty(Pty.create().slave()); process.run(); runningLatch.awaitSuccess(10000); process.suspend(); suspendedLatch.awaitSuccess(10000); try { process.run(); context.fail(); } catch (IllegalStateException ignore) { } }
@Test public void testEndSuspendedProcess(TestContext context) throws Exception { CommandBuilder builder = CommandBuilder.command("hello"); Async runningLatch = context.async(); Async endedHandler = context.async(); builder.processHandler(process -> { process.suspendHandler(v -> { process.end(0); }); process.endHandler(v -> endedHandler.complete()); runningLatch.complete(); }); Context ctx = vertx.getOrCreateContext(); Process process = createProcessInContext(ctx, builder.build(vertx)); Async terminatedHandler = context.async(); process.terminatedHandler(exitCode -> { context.assertEquals(ctx, Vertx.currentContext()); terminatedHandler.complete(); }); process.run(); runningLatch.awaitSuccess(10000); process.suspend(); }
@Test public void testSuspendProcess(TestContext context) throws Exception { TestTtyConnection conn = new TestTtyConnection(vertx); ShellImpl shell = createShell(conn); shell.init().readline(); Async done = context.async(); Async latch2 = context.async(); commands.add(CommandBuilder.command("foo").processHandler(process -> { Job job = shell.jobController().getJob(1); process.suspendHandler(v -> { context.assertEquals(ExecStatus.STOPPED, job.status()); context.assertNull(shell.jobController().foregroundJob()); done.complete(); }); latch2.complete(); })); conn.read("foo\r"); latch2.awaitSuccess(10000); conn.sendEvent(TtyEvent.SUSP); }
context.fail("Should not process line " + line); }); process.suspendHandler(v -> { try { process.write(""); process.suspendHandler(v -> { process.end(0); });
@Test public void testInterruptSuspendedProcess(TestContext context) { CommandBuilder builder = CommandBuilder.command("hello"); Async runningLatch = context.async(); Async suspendedLatch = context.async(); Async interruptedLatch = context.async(3); builder.processHandler(process -> { process.interruptHandler(v -> interruptedLatch.countDown()); process.suspendHandler(v -> suspendedLatch.complete()); runningLatch.complete(); }); Process process = builder.build(vertx).createProcess().setSession(Session.create()).setTty(Pty.create().slave()); process.run(); runningLatch.awaitSuccess(10000); process.suspend(); suspendedLatch.awaitSuccess(10000); process.interrupt(); process.interrupt(); process.interrupt(); }
@Test public void testSetStdinOnResumeToForeground(TestContext context) throws Exception { Async fooRunning = context.async(); Async fooSusp = context.async(); Async fooResumed = context.async(); Async readLatch = context.async(); commands.add( CommandBuilder.command("foo").processHandler(process -> { process.suspendHandler(v -> fooSusp.complete()); process.resumeHandler(v -> fooResumed.complete()); process.stdinHandler(line -> { context.assertEquals("foo_msg", line); readLatch.complete(); }); fooRunning.complete(); })); TestTtyConnection conn = new TestTtyConnection(vertx); ShellImpl shell = createShell(conn); shell.init().readline(); conn.read("foo\r"); fooRunning.awaitSuccess(2000); conn.sendEvent(TtyEvent.SUSP); fooSusp.awaitSuccess(2000); conn.read("fg\r"); fooResumed.awaitSuccess(2000); conn.read("foo_msg"); }
commands.add( CommandBuilder.command("foo").processHandler(process -> { process.suspendHandler(v -> fooSusp.complete()); process.resumeHandler(v -> fooResumed.complete()); process.foregroundHandler(v -> fooToForeground.complete());
Job job = shell.jobController().getJob(1); context.assertTrue(process.isForeground()); process.suspendHandler(v -> { context.assertFalse(process.isForeground()); context.assertEquals(0, latch1.count());
process.write("pong"); }); process.suspendHandler(event -> { testContext.assertTrue(commandCtx == Vertx.currentContext()); process.end(0);
Async async = context.async(); commands.add(CommandBuilder.command("foo").processHandler(process -> { process.suspendHandler(v -> { context.assertFalse(process.isForeground()); context.assertEquals(1, latch2.count());