@Test
  public void testSanity() throws Exception {
    final AtomicLong numJobsComplete = new AtomicLong(0);

    /** ** Setup mockFlow1 *** */
    final Capture<FlowCallback> flow1Callback = new Capture<FlowCallback>();
    mockFlow1.execute(EasyMock.eq(props), EasyMock.capture(flow1Callback));
    EasyMock.expectLastCall()
        .andAnswer(
            new IAnswer<Void>() {
              @Override
              public Void answer() throws Throwable {
                Assert.assertEquals(Status.RUNNING, flow.getStatus());
                Assert.assertEquals(1, numJobsComplete.incrementAndGet());

                flow1Callback.getValue().completed(Status.SUCCEEDED);

                Assert.assertEquals(Status.RUNNING, flow.getStatus());

                return null;
              }
            })
        .once();

    Props mockFlow1Props = new Props();
    mockFlow1Props.put("1", "1");
    mockFlow1Props.put("2", "1");

    EasyMock.expect(mockFlow1.getStatus()).andReturn(Status.SUCCEEDED).times(2);
    EasyMock.expect(mockFlow1.getReturnProps()).andReturn(mockFlow1Props).once();

    /** ** Setup mockFlow2 *** */
    final Capture<FlowCallback> flow2Callback = new Capture<FlowCallback>();
    mockFlow2.execute(EasyMock.eq(props), EasyMock.capture(flow2Callback));
    EasyMock.expectLastCall()
        .andAnswer(
            new IAnswer<Void>() {
              @Override
              public Void answer() throws Throwable {
                Assert.assertEquals(Status.RUNNING, flow.getStatus());
                Assert.assertEquals(2, numJobsComplete.incrementAndGet());

                flow2Callback.getValue().completed(Status.SUCCEEDED);

                Assert.assertEquals(Status.SUCCEEDED, flow.getStatus());

                return null;
              }
            })
        .once();

    EasyMock.expect(mockFlow2.getStatus())
        .andAnswer(
            new IAnswer<Status>() {
              private volatile AtomicInteger count = new AtomicInteger(0);

              @Override
              public Status answer() throws Throwable {
                switch (count.getAndIncrement()) {
                  case 0:
                    return Status.READY;
                  case 1:
                    return Status.SUCCEEDED;
                  default:
                    Assert.fail("mockFlow2.getStatus() should only be called 2 times.");
                }
                return null;
              }
            })
        .times(2);

    Props mockFlow2Props = new Props();
    mockFlow2Props.put("2", "2");
    mockFlow2Props.put("3", "2");
    EasyMock.expect(mockFlow2.getReturnProps()).andReturn(mockFlow2Props).once();

    EasyMock.expect(props.equalsProps(props)).andReturn(true).once();

    EasyMock.replay(mockFlow1, mockFlow2, props);

    /** ** Start the test *** */
    AtomicBoolean callbackRan = new AtomicBoolean(false);
    flow.execute(
        props,
        new OneCallFlowCallback(callbackRan) {
          @Override
          public void theCallback(Status status) {
            Assert.assertEquals(Status.SUCCEEDED, status);
            Assert.assertEquals(2, numJobsComplete.get());
          }
        });

    Assert.assertTrue("Callback wasn't run.", callbackRan.get());
    Assert.assertEquals(Status.SUCCEEDED, flow.getStatus());
    Assert.assertEquals(emptyExceptions, flow.getExceptions());
    Assert.assertEquals(props, flow.getParentProps());

    callbackRan = new AtomicBoolean(false);
    flow.execute(
        props,
        new OneCallFlowCallback(callbackRan) {
          @Override
          protected void theCallback(Status status) {
            Assert.assertEquals(Status.SUCCEEDED, status);
            Assert.assertEquals(2, numJobsComplete.get());
          }
        });

    Assert.assertTrue("Callback wasn't run.", callbackRan.get());
    Assert.assertEquals(Status.SUCCEEDED, flow.getStatus());
    Assert.assertEquals(emptyExceptions, flow.getExceptions());

    Props retProps = flow.getReturnProps();
    Assert.assertEquals(3, retProps.size());
    Assert.assertEquals("1", retProps.get("1"));
    Assert.assertEquals("2", retProps.get("2"));
    Assert.assertEquals("2", retProps.get("3"));

    EasyMock.verify(props);
    EasyMock.reset(props);

    EasyMock.expect(props.equalsProps(props)).andReturn(false).once();

    EasyMock.replay(props);

    boolean exceptionThrown = false;
    try {
      flow.execute(
          props,
          new FlowCallback() {
            @Override
            public void progressMade() {}

            @Override
            public void completed(Status status) {}
          });
    } catch (IllegalArgumentException e) {
      exceptionThrown = true;
    }

    Assert.assertTrue(
        "Expected an IllegalArgumentException to be thrown because props weren't the same.",
        exceptionThrown);
  }