/**
   * Executes batch but finalizer is failed.
   *
   * @throws Exception if failed
   */
  @Test
  public void executeBatch_failed_finalize() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    prf.setTracker(FinalizerFailed.class);
    ExecutionTask task = prf.task();
    try {
      task.executeBatch("batch");
      fail();
    } catch (IOException e) {
      // ok.
    }

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    verifyPhaseOrder(results);

    assertThat(phase(results, "testing", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.INITIALIZE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.IMPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.PROLOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.MAIN).size(), is(4));
    assertThat(phase(results, "testing", ExecutionPhase.EPILOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.EXPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.FINALIZE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.CLEANUP).size(), is(0));

    assertThat(flow(results, "left").size(), is(0));
    assertThat(flow(results, "right").size(), is(0));
    assertThat(flow(results, "last").size(), is(0));
  }
 @Override
 public synchronized void add(Id id, Record record) throws IOException, InterruptedException {
   if (record.context.getPhase() == ExecutionPhase.CLEANUP
       && record.handler.getHandlerId().equals("hadoop")) {
     throw new IOException();
   }
   super.add(id, record);
 }
 @Override
 public synchronized void add(Id id, Record record) throws IOException, InterruptedException {
   if (record.context.getPhase() == ExecutionPhase.FINALIZE
       && profile(record).equals("testing1")) {
     throw new IOException();
   }
   super.add(id, record);
 }
  /**
   * Executes flow but is skipped.
   *
   * @throws Exception if failed
   */
  @Test
  public void executeFlow_skip() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    ExecutionTask task = prf.task();
    task.getSkipFlows().add("testing");
    task.executeFlow("batch", "testing", "flow");

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    assertThat(results, is(Collections.<Record>emptyList()));
  }
  /**
   * Executes batch.
   *
   * @throws Exception if failed
   */
  @Test
  public void executeBatch() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    ExecutionTask task = prf.task();
    task.executeBatch("batch");

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    checkFlowHappensBefore(results, "testing", "left");
    checkFlowHappensBefore(results, "testing", "right");
    checkFlowHappensBefore(results, "left", "last");
    checkFlowHappensBefore(results, "right", "last");
    verifyPhaseOrder(results);

    assertThat(phase(results, "testing", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.INITIALIZE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.IMPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.PROLOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.MAIN).size(), is(4));
    assertThat(phase(results, "testing", ExecutionPhase.EPILOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.EXPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.FINALIZE).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.CLEANUP).size(), is(2));

    assertThat(phase(results, "left", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "left", ExecutionPhase.INITIALIZE).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.IMPORT).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.PROLOGUE).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.MAIN).size(), is(1));
    assertThat(phase(results, "left", ExecutionPhase.EPILOGUE).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.EXPORT).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.FINALIZE).size(), is(0));
    assertThat(phase(results, "left", ExecutionPhase.CLEANUP).size(), is(2));

    assertThat(phase(results, "right", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "right", ExecutionPhase.INITIALIZE).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.IMPORT).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.PROLOGUE).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.MAIN).size(), is(1));
    assertThat(phase(results, "right", ExecutionPhase.EPILOGUE).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.EXPORT).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.FINALIZE).size(), is(0));
    assertThat(phase(results, "right", ExecutionPhase.CLEANUP).size(), is(2));

    assertThat(phase(results, "last", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "last", ExecutionPhase.INITIALIZE).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.IMPORT).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.PROLOGUE).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.MAIN).size(), is(1));
    assertThat(phase(results, "last", ExecutionPhase.EPILOGUE).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.EXPORT).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.FINALIZE).size(), is(0));
    assertThat(phase(results, "last", ExecutionPhase.CLEANUP).size(), is(2));
  }
  /**
   * Execute setup phase.
   *
   * @throws Exception if failed
   */
  @Test
  public void phase_setup() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    ExecutionTask task = prf.task();
    task.executePhase("batch", "testing", "f-setup", ExecutionPhase.SETUP);

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    verifyPhaseOrder(results);

    assertThat(results.size(), is(2));
    List<Record> records = phase(results, "testing", ExecutionPhase.SETUP);
    assertThat(records, is(results));
  }
 ProfileBuilder(File working) {
   this.asakusaHome = new File(working, "asakusa");
   this.lockDir = new File(working, "lock");
   this.trackingId = ExecutionTracker.Id.get("testing");
   this.replacement = new HashMap<String, String>();
   this.replacement.put("home", asakusaHome.getAbsolutePath());
   this.replacement.put("scope", ExecutionLock.Scope.WORLD.getSymbol());
   this.replacement.put("locker", BasicLockProvider.class.getName());
   this.replacement.put("monitor", BasicMonitorProvider.class.getName());
   this.replacement.put("lock", lockDir.getAbsolutePath());
   this.replacement.put("tracker", SerialExecutionTracker.class.getName());
   this.replacement.put("id", "testing");
   this.override = new Properties();
   SerialExecutionTracker.clear();
 }
  /**
   * Executes batch but some flows are skipped.
   *
   * @throws Exception if failed
   */
  @Test
  public void executeBatch_seriaize() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    prf.setTracker(FlowSerialized.class);
    ExecutionTask task = prf.task();
    task.setSerializeFlows(true);
    task.executeBatch("batch");

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    checkFlowHappensBefore(results, "testing", "left");
    checkFlowHappensBefore(results, "testing", "right");
    checkFlowHappensBefore(results, "left", "last");
    checkFlowHappensBefore(results, "right", "last");
    verifyPhaseOrder(results);
  }
 @Override
 public synchronized void add(Id id, Record record) throws IOException, InterruptedException {
   switch (record.context.getPhase()) {
     case SETUP:
       assertThat(flowId, is(nullValue()));
       flowId = record.context.getFlowId();
       break;
     case CLEANUP:
       assertThat(flowId, is(record.context.getFlowId()));
       flowId = null;
       break;
     default:
       Thread.sleep(100);
       assertThat(flowId, is(record.context.getFlowId()));
       break;
   }
   super.add(id, record);
 }
  /**
   * Execute main phase.
   *
   * @throws Exception if failed
   */
  @Test
  public void phase_main() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    ExecutionTask task = prf.task();
    task.executePhase("batch", "testing", "f1", ExecutionPhase.MAIN);

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    verifyPhaseOrder(results);

    assertThat(results.size(), is(4));
    assertThat(id(results), is(set("a", "b", "c", "d")));
    checkScriptHappensBefore(results, "a", "b");
    checkScriptHappensBefore(results, "a", "c");
    checkScriptHappensBefore(results, "b", "d");
    checkScriptHappensBefore(results, "c", "d");

    List<Record> records = phase(results, "testing", ExecutionPhase.MAIN);
    assertThat(records, is(results));
  }
  /**
   * Executes flow but cleanup is failed.
   *
   * @throws Exception if failed
   */
  @Test
  public void executeFlow_failed_cleanup() throws Exception {
    ProfileBuilder prf = new ProfileBuilder(folder.getRoot());
    prf.setTracker(CleanerFailed.class);
    ExecutionTask task = prf.task();
    task.executeFlow("batch", "testing", "flow");

    List<Record> results = SerialExecutionTracker.get(prf.trackingId);
    verifyPhaseOrder(results);

    assertThat(phase(results, "testing", ExecutionPhase.SETUP).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.INITIALIZE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.IMPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.PROLOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.MAIN).size(), is(4));
    assertThat(phase(results, "testing", ExecutionPhase.EPILOGUE).size(), is(1));
    assertThat(phase(results, "testing", ExecutionPhase.EXPORT).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.FINALIZE).size(), is(2));
    assertThat(phase(results, "testing", ExecutionPhase.CLEANUP).size(), is(1));
  }
 /**
  * Cleans up the test.
  *
  * @throws Exception if some errors were occurred
  */
 @After
 public void tearDown() throws Exception {
   SerialExecutionTracker.clear();
 }
 /**
  * Initializes the test.
  *
  * @throws Exception if some errors were occurred
  */
 @Before
 public void setUp() throws Exception {
   SerialExecutionTracker.clear();
 }