@Test
  public void
      shouldUpdateResultOfStageWhenJobCompletes_irrespectiveOfOtherThreadsPrimingStageCache()
          throws Exception {
    Pipeline assigned = preCondition.createPipelineWithFirstStageAssigned();

    Stage stage = assigned.findStage(preCondition.devStage);
    StageSummaryModel model =
        stageService.findStageSummaryByIdentifier(
            stage.getIdentifier(),
            new Username(new CaseInsensitiveString("foo")),
            new HttpLocalizedOperationResult());

    JobIdentifier identifier = stage.getFirstJob().getIdentifier();
    scheduleService.updateJobStatus(identifier, JobState.Building);
    scheduleService.jobCompleting(identifier, JobResult.Passed, "uuid");

    Stage stageLoadedByOtherFlows = stageDao.stageById(stage.getId()); // priming the cache

    scheduleService.updateJobStatus(stage.getFirstJob().getIdentifier(), JobState.Completed);

    StageSummaryModel reloadedModel =
        stageService.findStageSummaryByIdentifier(
            stage.getIdentifier(),
            new Username(new CaseInsensitiveString("foo")),
            new HttpLocalizedOperationResult());
    Stage reloadedStage = reloadedModel.getStage();
    assertThat(reloadedStage.getFirstJob().getState(), is(JobState.Completed));
    assertThat(
        reloadedStage.getCompletedByTransitionId(),
        is(reloadedStage.getFirstJob().getTransitions().byState(JobState.Completed).getId()));
    assertThat(reloadedStage.getResult(), is(StageResult.Passed));
    assertThat(reloadedStage.getState(), is(StageState.Passed));
  }
  @Test
  public void shouldUpdateResultOfStageWhenJobCompletes() throws Exception {
    //        ScheduleService service = new ScheduleService(goConfigService, pipelineService,
    // stageService, currentActivityService, schedulingChecker, pipelineScheduledTopic, pipelineDao,
    //                stageDao, stageOrderService, securityService, pipelineScheduleQueue,
    // jobInstanceService, jobInstanceDao, agentAssignment, environmentConfigService,
    //                pipelineLockService, serverHealthService, transactionTemplate, agentService);

    Pipeline assigned = preCondition.createPipelineWithFirstStageAssigned();

    Stage stage = assigned.findStage(preCondition.devStage);
    StageSummaryModel model =
        stageService.findStageSummaryByIdentifier(
            stage.getIdentifier(),
            new Username(new CaseInsensitiveString("foo")),
            new HttpLocalizedOperationResult());
    assertThat(model.getStage().getFirstJob().getState(), is(JobState.Assigned));
    scheduleService.updateJobStatus(stage.getFirstJob().getIdentifier(), JobState.Building);
    StageSummaryModel reloadedModel =
        stageService.findStageSummaryByIdentifier(
            stage.getIdentifier(),
            new Username(new CaseInsensitiveString("foo")),
            new HttpLocalizedOperationResult());
    assertThat(reloadedModel.getStage().getFirstJob().getState(), is(JobState.Building));
  }
  @Test
  public void shouldUpdateResultOfStageWhenJobCompletesOnTransactionCommitOnly() throws Exception {
    StageService stageService = mock(StageService.class);
    StageDao stageDao = mock(StageDao.class);
    SchedulingPerformanceLogger schedulingPerformanceLogger =
        mock(SchedulingPerformanceLogger.class);

    ScheduleService service =
        new ScheduleService(
            goConfigService,
            pipelineService,
            stageService,
            schedulingChecker,
            pipelineScheduledTopic,
            pipelineDao,
            stageDao,
            stageOrderService,
            securityService,
            pipelineScheduleQueue,
            jobInstanceService,
            jobInstanceDao,
            agentAssignment,
            environmentConfigService,
            pipelineLockService,
            serverHealthService,
            transactionTemplate,
            agentService,
            synchronizationManager,
            null,
            null,
            null,
            null,
            schedulingPerformanceLogger);

    Pipeline assigned = preCondition.createPipelineWithFirstStageAssigned();

    Stage stage = assigned.findStage(preCondition.devStage);

    when(stageService.stageById(stage.getId())).thenThrow(new RuntimeException("find fails"));

    try {
      service.updateJobStatus(stage.getFirstJob().getIdentifier(), JobState.Completed);
      fail("should have failed because stage lookup bombed");
    } catch (Exception e) {
      // ignore
    }
    verify(stageDao, never())
        .clearCachedAllStages(
            stage.getIdentifier().getPipelineName(),
            stage.getIdentifier().getPipelineCounter(),
            stage.getName());
  }
 private long rerunJob(
     String jobName,
     PipelineConfig pipelineConfig,
     Pipeline previousSuccessfulBuildWithOlderPackageConfig) {
   Stage stage =
       instanceFactory.createStageForRerunOfJobs(
           previousSuccessfulBuildWithOlderPackageConfig.getFirstStage(),
           asList(jobName),
           new DefaultSchedulingContext(),
           pipelineConfig.getFirstStageConfig(),
           new TimeProvider(),
           configHelper.getGoConfigDao().md5OfConfigFile());
   stage = stageService.save(previousSuccessfulBuildWithOlderPackageConfig, stage);
   return stage.getFirstJob().getId();
 }