### Question:
Run implements Runnable { public Run(final Ripener.Configuration configuration, final Map<String, String> systemVariables, final Consumer<Runnable> waitOnExit) { this.configuration = configuration; this.systemVariables = systemVariables; this.waitOnExit = waitOnExit; } Run(final Ripener.Configuration configuration,
               final Map<String, String> systemVariables,
               final Consumer<Runnable> waitOnExit); Ripener getFramework(); @Override void run();  }### Answer:
@Test void run() throws InterruptedException { final InputStream in = System.in; final ControlledStream controlledStream = new ControlledStream(); System.setIn(controlledStream); final CountDownLatch started = new CountDownLatch(1); final CountDownLatch stopped = new CountDownLatch(1); try { final String systemProp = getClass().getName() + ".run"; final Run run = new Run(new Ripener.Configuration(), singletonMap(systemProp, "set"), null) { @Override protected void onStop() { stopped.countDown(); } @Override protected void onStart() { started.countDown(); } }; new Thread(run).start(); started.await(); assertEquals("set", System.getProperty(systemProp)); assertNotNull(run.getFramework()); controlledStream.done(); stopped.await(); assertNull(System.getProperty(systemProp)); assertNull(run.getFramework()); } finally { System.setIn(in); } }