public void testManualServiceFailWhileStarting() throws Exception {
   ManualSwitchedService service = new ManualSwitchedService();
   RecordingListener listener = RecordingListener.record(service);
   service.start();
   service.notifyFailed(EXCEPTION);
   assertEquals(ImmutableList.of(State.STARTING, State.FAILED), listener.getStateHistory());
 }
  public void testManualServiceStopWhileStarting() throws Exception {
    ManualSwitchedService service = new ManualSwitchedService();
    RecordingListener listener = RecordingListener.record(service);

    service.start();
    assertEquals(State.STARTING, service.state());
    assertFalse(service.isRunning());
    assertTrue(service.doStartCalled);

    service.stop();
    assertEquals(State.STOPPING, service.state());
    assertFalse(service.isRunning());
    assertFalse(service.doStopCalled);

    service.notifyStarted();
    assertEquals(State.STOPPING, service.state());
    assertFalse(service.isRunning());
    assertTrue(service.doStopCalled);

    service.notifyStopped();
    assertEquals(State.TERMINATED, service.state());
    assertFalse(service.isRunning());
    assertEquals(
        ImmutableList.of(State.STARTING, State.STOPPING, State.TERMINATED),
        listener.getStateHistory());
  }
  public void testThrowingServiceStartAndWait() throws Exception {
    StartThrowingService service = new StartThrowingService();
    RecordingListener listener = RecordingListener.record(service);

    try {
      service.startAndWait();
      fail();
    } catch (UncheckedExecutionException e) {
      assertEquals(service.exception, e.getCause());
    }
    assertEquals(ImmutableList.of(State.STARTING, State.FAILED), listener.getStateHistory());
  }
  public void testStopUnstartedService() throws Exception {
    NoOpService service = new NoOpService();
    RecordingListener listener = RecordingListener.record(service);

    Future<State> stopResult = service.stop();
    assertEquals(State.TERMINATED, service.state());
    assertEquals(State.TERMINATED, stopResult.get());

    Future<State> startResult = service.start();
    assertEquals(State.TERMINATED, service.state());
    assertEquals(State.TERMINATED, startResult.get());
    assertEquals(State.TERMINATED, Iterables.getOnlyElement(listener.getStateHistory()));
  }
  public void testNoOpServiceStartStopIdempotence() throws Exception {
    NoOpService service = new NoOpService();
    RecordingListener listener = RecordingListener.record(service);
    service.start();
    service.start();
    assertEquals(State.RUNNING, service.state());

    service.stop();
    service.stop();
    assertEquals(State.TERMINATED, service.state());
    assertEquals(
        ImmutableList.of(State.STARTING, State.RUNNING, State.STOPPING, State.TERMINATED),
        listener.getStateHistory());
  }
  public void testFailingServiceStopAndWait_runFailinging() throws Exception {
    RunFailingService service = new RunFailingService();
    RecordingListener listener = RecordingListener.record(service);

    service.startAndWait();
    try {
      service.stopAndWait();
      fail();
    } catch (UncheckedExecutionException e) {
      assertEquals(EXCEPTION, e.getCause().getCause());
    }
    assertEquals(
        ImmutableList.of(State.STARTING, State.RUNNING, State.FAILED), listener.getStateHistory());
  }
  public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable {
    ThreadedService service = new ThreadedService();
    RecordingListener listener = RecordingListener.record(service);
    service.start().get();
    assertEquals(State.RUNNING, service.state());

    service.awaitRunChecks();

    service.stopAndWait();
    assertEquals(State.TERMINATED, service.state());

    throwIfSet(thrownByExecutionThread);
    assertEquals(
        ImmutableList.of(State.STARTING, State.RUNNING, State.STOPPING, State.TERMINATED),
        listener.getStateHistory());
  }