Program: 7060
Project: 7060
Buggy source:
@Test public void testWorkflowForkApp() throws Exception {
  String workflowAppWithFork="String_Node_Str";
  String workflowWithFork="String_Node_Str";
  File doneFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  File oneActionFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  File anotherActionFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  HttpResponse response=deploy(WorkflowAppWithFork.class,Constants.Gateway.API_VERSION_3_TOKEN,TEST_NAMESPACE2);
  Assert.assertEquals(200,response.getStatusLine().getStatusCode());
  Id.Program programId=Id.Program.from(TEST_NAMESPACE2,workflowAppWithFork,ProgramType.WORKFLOW,workflowWithFork);
  Map<String,String> runtimeArguments=ImmutableMap.of("String_Node_Str",doneFile.getAbsolutePath(),"String_Node_Str",oneActionFile.getAbsolutePath(),"String_Node_Str",anotherActionFile.getAbsolutePath());
  setAndTestRuntimeArgs(programId,runtimeArguments);
  startProgram(programId,200);
  waitState(programId,"String_Node_Str");
  List<RunRecord> historyRuns=getProgramRuns(programId,"String_Node_Str");
  Assert.assertTrue(historyRuns.size() == 1);
  String runId=historyRuns.get(0).getPid();
  while (!(oneActionFile.exists() && anotherActionFile.exists())) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,2);
  stopProgram(programId,200);
  response=getWorkflowCurrentStatus(programId,runId);
  Assert.assertEquals(404,response.getStatusLine().getStatusCode());
  verifyProgramRuns(programId,"String_Node_Str");
  oneActionFile.delete();
  anotherActionFile.delete();
  startProgram(programId,200);
  waitState(programId,"String_Node_Str");
  historyRuns=getProgramRuns(programId,"String_Node_Str");
  Assert.assertTrue(historyRuns.size() == 1);
  runId=historyRuns.get(0).getPid();
  while (!(oneActionFile.exists() && anotherActionFile.exists())) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,2);
  doneFile.createNewFile();
  verifyProgramRuns(programId,"String_Node_Str");
}

Fixed version (ground truth):
@Test public void testWorkflowForkApp() throws Exception {
  String workflowAppWithFork="String_Node_Str";
  String workflowWithFork="String_Node_Str";
  Map<String,String> runtimeArgs=Maps.newHashMap();
  File firstSimpleActionFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  File firstSimpleActionDoneFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  runtimeArgs.put("String_Node_Str",firstSimpleActionFile.getAbsolutePath());
  runtimeArgs.put("String_Node_Str",firstSimpleActionDoneFile.getAbsolutePath());
  File oneSimpleActionFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  File oneSimpleActionDoneFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  runtimeArgs.put("String_Node_Str",oneSimpleActionFile.getAbsolutePath());
  runtimeArgs.put("String_Node_Str",oneSimpleActionDoneFile.getAbsolutePath());
  File anotherSimpleActionFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  File anotherSimpleActionDoneFile=new File(tmpFolder.newFolder() + "String_Node_Str");
  runtimeArgs.put("String_Node_Str",anotherSimpleActionFile.getAbsolutePath());
  runtimeArgs.put("String_Node_Str",anotherSimpleActionDoneFile.getAbsolutePath());
  HttpResponse response=deploy(WorkflowAppWithFork.class,Constants.Gateway.API_VERSION_3_TOKEN,TEST_NAMESPACE2);
  Assert.assertEquals(200,response.getStatusLine().getStatusCode());
  Id.Program programId=Id.Program.from(TEST_NAMESPACE2,workflowAppWithFork,ProgramType.WORKFLOW,workflowWithFork);
  setAndTestRuntimeArgs(programId,runtimeArgs);
  startProgram(programId,200);
  waitState(programId,"String_Node_Str");
  List<RunRecord> historyRuns=getProgramRuns(programId,"String_Node_Str");
  Assert.assertTrue(historyRuns.size() == 1);
  RunRecord record=historyRuns.get(0);
  String runId=record.getPid();
  while (!firstSimpleActionFile.exists()) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,1);
  stopProgram(programId,200);
  verifyProgramRuns(programId,"String_Node_Str");
  firstSimpleActionFile.delete();
  startProgram(programId,200);
  waitState(programId,"String_Node_Str");
  historyRuns=getProgramRuns(programId,"String_Node_Str");
  Assert.assertTrue(historyRuns.size() == 1);
  record=historyRuns.get(0);
  Assert.assertTrue(!runId.equals(record.getPid()));
  runId=record.getPid();
  while (!firstSimpleActionFile.exists()) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,1);
  firstSimpleActionDoneFile.createNewFile();
  while (!(oneSimpleActionFile.exists() && anotherSimpleActionFile.exists())) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,2);
  stopProgram(programId,200);
  response=getWorkflowCurrentStatus(programId,runId);
  Assert.assertEquals(404,response.getStatusLine().getStatusCode());
  verifyProgramRuns(programId,"String_Node_Str",1);
  firstSimpleActionFile.delete();
  firstSimpleActionDoneFile.delete();
  oneSimpleActionFile.delete();
  anotherSimpleActionFile.delete();
  startProgram(programId,200);
  waitState(programId,"String_Node_Str");
  historyRuns=getProgramRuns(programId,"String_Node_Str");
  Assert.assertTrue(historyRuns.size() == 1);
  runId=historyRuns.get(0).getPid();
  while (!firstSimpleActionFile.exists()) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,1);
  firstSimpleActionDoneFile.createNewFile();
  while (!(oneSimpleActionFile.exists() && anotherSimpleActionFile.exists())) {
    TimeUnit.MILLISECONDS.sleep(50);
  }
  verifyRunningProgramCount(programId,runId,2);
  oneSimpleActionDoneFile.createNewFile();
  anotherSimpleActionDoneFile.createNewFile();
  verifyProgramRuns(programId,"String_Node_Str");
}