/**
   * Tests that the sucker keeps sucking while ops are available and the sink doesn't need to flush.
   */
  public void testSucksWhileNoFlushNeeded() {
    // Set expectations.
    WaveletOperation[] ops = makeOps(3);
    for (int i = 0; i < 3; ++i) {
      WaveletOperation op = ops[0];
      channel.expectPeek(op);
      sink.expectFlush(op, true);
      // The sucker peeks again after flush in case the op has changed.
      channel.expectPeek(op);
      channel.expectReceive(op);
      sink.expectConsume(op, null);
    }
    channel.expectPeek(null);

    // Go!
    sucker.onOperationReceived();
  }
  /**
   * Tests that the sucker stops sucking if a flush is required, and resumes when the flush is done.
   */
  public void testFlushPausesSucking() {
    // Set expectations.
    WaveletOperation op = makeOp();
    channel.expectPeek(op);
    sink.expectFlush(op, false);

    // Go!
    sucker.onOperationReceived();

    channel.checkExpectationsSatisfied();
    sink.checkExpectationsSatisfied();
    Runnable resume = sink.getLastResumeCommand();
    assertNotNull(resume);

    // Another op received should not cause any action
    sucker.onOperationReceived();
    channel.checkExpectationsSatisfied();
    sink.checkExpectationsSatisfied();

    // Set expectations for the resume command.
    channel.expectPeek(op);
    sink.expectFlush(op, true);
    channel.expectPeek(op);
    channel.expectReceive(op);
    sink.expectConsume(op, null);

    channel.expectPeek(null);

    // Go!
    resume.run();
  }
  /**
   * Tests that the sucker doesn't touch the operation channel after being shut down while consuming
   * ops.
   */
  public void testStopsSuckingAfterShutdown() {
    // Set expectations.
    WaveletOperation op = makeOp();
    channel.expectPeek(op);
    sink.expectFlush(op, true);

    channel.expectPeek(op);
    channel.expectReceive(op);
    // Shut down the sucker when consuming the op.
    sink.expectConsume(
        op,
        new Runnable() {
          @Override
          public void run() {
            sucker.shutdown();
          }
        });
    // No more expectations of peek() or receive().

    sucker.onOperationReceived();
  }
 @Override
 protected void tearDown() throws Exception {
   channel.checkExpectationsSatisfied();
   sink.checkExpectationsSatisfied();
   super.tearDown();
 }