@Test
  public void shouldScheduleIfAgentMatchingResources() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-resource"));

    buildAssignmentService.onTimer();
    Work work = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(work, is(not((Work) BuildAssignmentService.NO_WORK)));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    JobPlan loadedPlan = jobInstanceDao.loadPlan(job.getId());
    assertThat(loadedPlan.getResources(), is((List<Resource>) plan.resources()));

    assertThat(job.getState(), is(JobState.Assigned));
    assertThat(job.getAgentUuid(), is(agentConfig.getUuid()));
  }
 public Stage saveBuildingStage(String pipelineName, String stageName) throws SQLException {
   Pipeline pipeline = saveTestPipeline(pipelineName, stageName);
   Stage stage = saveBuildingStage(pipeline.getStages().byName(stageName));
   for (JobInstance job : stage.getJobInstances()) {
     job.setIdentifier(new JobIdentifier(pipeline, stage, job));
   }
   return stage;
 }
 public Stage saveBuildingStage(Stage stage) {
   for (JobInstance jobInstance : stage.getJobInstances()) {
     JobInstanceMother.setBuildingState(jobInstance);
     jobInstance.setAgentUuid(AGENT_UUID);
     jobInstanceDao.updateAssignedInfo(jobInstance);
   }
   return stage;
 }
 public void buildingBuildInstance(Stage stage) {
   if (!stage.getJobInstances().isEmpty()) {
     JobInstance jobInstance = stage.getJobInstances().get(0);
     jobInstance.setAgentUuid(AGENT_UUID);
     jobInstance.changeState(JobState.Building);
     jobInstanceDao.updateAssignedInfo(jobInstance);
   }
 }
 public void cancelStage(Stage stage) {
   for (JobInstance job : stage.getJobInstances()) {
     job.cancel();
     jobInstanceDao.updateStateAndResult(job);
   }
   stage.calculateResult();
   updateResultInTransaction(stage, StageResult.Cancelled);
 }
 private void verifyMingleScheduledWithModifications() {
   Pipeline scheduledPipeline =
       pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(mingleConfig.name()));
   BuildCause buildCause = scheduledPipeline.getBuildCause();
   assertThat(buildCause.getMaterialRevisions().totalNumberOfModifications(), is(3));
   JobInstance instance = scheduledPipeline.getFirstStage().getJobInstances().first();
   assertThat(instance.getState(), is(JobState.Scheduled));
 }
 public void failStage(Stage stage, Date completionDate) {
   for (JobInstance job : stage.getJobInstances()) {
     job.completing(Failed, completionDate);
     job.completed(completionDate);
     jobInstanceDao.updateStateAndResult(job);
   }
   stage.calculateResult();
   updateResultInTransaction(stage, StageResult.Failed);
 }
Beispiel #8
0
 private void logIfJobIsCompleted(JobInstance jobInstance) {
   JobState currentState = getCurrentState(jobInstance.getId());
   if (currentState.isCompleted()) {
     String message =
         String.format(
             "State change for a completed Job is not allowed. Job %s is currently State=%s, Result=%s",
             jobInstance.getIdentifier(), jobInstance.getState(), jobInstance.getResult());
     LOG.warn(message, new Exception().fillInStackTrace());
   }
 }
Beispiel #9
0
 private JobInstance job(long buildId, String queryName) {
   JobInstance instance =
       (JobInstance) getSqlMapClientTemplate().queryForObject(queryName, buildId);
   if (instance == null) {
     throw new DataRetrievalFailureException("Could not load build with id " + buildId);
   }
   if (instance.getIdentifier() == null) {
     throw new RuntimeException("Identifier must not be null!");
   }
   return instance;
 }
Beispiel #10
0
  public JobInstance save(long stageId, JobInstance jobInstance) {
    jobInstance.setStageId(stageId);
    getSqlMapClientTemplate().insert("insertBuild", jobInstance);
    updateStateAndResult(jobInstance);

    JobPlan plan = jobInstance.getPlan();
    if (plan != null) {
      save(jobInstance.getId(), plan);
    }
    return jobInstance;
  }
Beispiel #11
0
 private void saveTransitions(JobInstance jobInstance) {
   for (JobStateTransition transition : jobInstance.getTransitions()) {
     if (!transition.hasId()) {
       saveTransition(jobInstance, transition);
     }
   }
   if (jobInstance.getIdentifier() != null) {
     String pipelineName = jobInstance.getIdentifier().getPipelineName();
     String stageName = jobInstance.getIdentifier().getStageName();
     cache.flushEntry(jobInstance.getBuildDurationKey(pipelineName, stageName));
   }
 }
  private void assertPipelinesScheduled() {
    Pipeline minglePipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(mingleConfig.name()));
    Stage mingleStage = minglePipeline.getFirstStage();
    assertThat(mingleStage.getName(), is(STAGE_NAME));
    assertThat(mingleStage.getJobInstances().size(), is(2));
    JobInstance mingleJob = mingleStage.getJobInstances().first();
    assertThat(mingleJob.getState(), is(JobState.Scheduled));

    assertPipelineScheduled(evolveConfig);
    assertPipelineScheduled(goConfig);
  }
  @Test
  public void shouldCancelOutOfDateBuilds() throws Exception {
    fixture.createPipelineWithFirstStageScheduled();
    buildAssignmentService.onTimer();
    configHelper.removeStage(fixture.pipelineName, fixture.devStage);

    buildAssignmentService.onConfigChange(goConfigService.getCurrentConfig());

    Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName);
    JobInstance job = pipeline.getFirstStage().getJobInstances().first();
    assertThat(job.getState(), is(JobState.Completed));
    assertThat(job.getResult(), is(JobResult.Cancelled));
  }
  private Pipeline scheduleJobInstancesAndSavePipeline(Pipeline pipeline) {
    assertNotInserted(pipeline.getId());
    for (Stage stage : pipeline.getStages()) {
      for (JobInstance jobInstance : stage.getJobInstances()) {
        jobInstance.schedule();
      }
    }
    this.savePipelineWithStagesAndMaterials(pipeline);

    long pipelineId = pipeline.getId();
    assertIsInserted(pipelineId);
    return pipeline;
  }
 @Before
 public void setUp() {
   MaterialRevisions materialRevisions = multipleModifications();
   stage =
       StageMother.withOneScheduledBuild("stage", "job-that-will-fail", "job-that-will-pass", 1);
   modifications = BuildCause.createWithModifications(materialRevisions, "");
   pipeline = new Pipeline("pipeline", PipelineLabel.COUNT_TEMPLATE, modifications, stage);
   stage.setIdentifier(new StageIdentifier(pipeline, stage));
   for (JobInstance job : stage.getJobInstances()) {
     job.setIdentifier(new JobIdentifier(pipeline, stage, job));
   }
   pipeline.setId(PIPELINE_ID);
   pipeline.updateCounter(9);
 }
  @Test
  public void shouldCancelBuildBelongingToNonExistentPipelineWhenCreatingWork() throws Exception {
    fixture.createPipelineWithFirstStageScheduled();
    Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName);

    ScheduledPipelineLoader scheduledPipelineLoader = mock(ScheduledPipelineLoader.class);
    when(scheduledPipelineLoader.pipelineWithPasswordAwareBuildCauseByBuildId(
            pipeline.getFirstStage().getJobInstances().first().getId()))
        .thenThrow(new PipelineNotFoundException("thrown by mockPipelineService"));

    GoConfigService mockGoConfigService = mock(GoConfigService.class);
    CruiseConfig config = configHelper.currentConfig();
    configHelper.removePipeline(fixture.pipelineName, config);
    when(mockGoConfigService.getCurrentConfig()).thenReturn(config);

    buildAssignmentService =
        new BuildAssignmentService(
            mockGoConfigService,
            jobInstanceService,
            scheduleService,
            agentService,
            environmentConfigService,
            timeProvider,
            transactionTemplate,
            scheduledPipelineLoader,
            pipelineService,
            builderFactory,
            agentRemoteHandler);
    buildAssignmentService.onTimer();

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-other-resource"));

    try {
      buildAssignmentService.assignWorkToAgent(agent(agentConfig));
      fail("should have thrown PipelineNotFoundException");
    } catch (PipelineNotFoundException e) {
      // ok
    }

    pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName);

    JobInstance job = pipeline.getFirstStage().getJobInstances().first();
    assertThat(job.getState(), is(JobState.Completed));
    assertThat(job.getResult(), is(JobResult.Cancelled));
    Stage stage = stageDao.findStageWithIdentifier(job.getIdentifier().getStageIdentifier());
    assertThat(stage.getState(), is(StageState.Cancelled));
    assertThat(stage.getResult(), is(StageResult.Cancelled));
  }
  @Test
  public void buildByIdWithTransitions_shouldCacheWhenQueriedFor() {
    jobInstanceDao.setSqlMapClientTemplate(mockTemplate);

    JobInstance job = JobInstanceMother.assigned("job");
    job.setId(1L);
    when(mockTemplate.queryForObject("buildByIdWithTransitions", 1L)).thenReturn(job);

    JobInstance actual = jobInstanceDao.buildByIdWithTransitions(1L);
    assertThat(actual, is(job));
    assertThat(actual == job, is(false));

    jobInstanceDao.buildByIdWithTransitions(1L);
    verify(mockTemplate, times(1)).queryForObject("buildByIdWithTransitions", 1L);
  }
  @Test
  public void shouldSaveBuildStateCorrectly() throws Exception {
    PipelineConfig cruisePlan = configHelper.addPipeline("cruise", "dev", repository);
    goConfigService.forceNotifyListeners();

    autoSchedulePipelines("mingle", "evolve", "cruise");

    Stage cruise =
        stageDao.mostRecentWithBuilds(
            CaseInsensitiveString.str(cruisePlan.name()),
            cruisePlan.findBy(new CaseInsensitiveString("dev")));
    System.out.println("cruise = " + cruise);
    JobInstance instance = cruise.getJobInstances().first();
    System.out.println("instance = " + instance);
    assertThat(instance.getState(), is(JobState.Scheduled));
  }
 @Test
 public void shouldEncodeBuildLocator() throws Exception {
   JobInstance job = JobInstanceMother.assigned("job-%");
   Stage stage1 =
       new Stage(
           "stage-c%d",
           new JobInstances(job), GoConstants.DEFAULT_APPROVED_BY, "manual", new TimeProvider());
   stage1.setIdentifier(new StageIdentifier("pipeline-a%b", 1, "label-1", "stage-c%d", "1"));
   job.setIdentifier(
       new JobIdentifier("pipeline-a%b", 1, "label-1", "stage-c%d", "1", "job-%", 0L));
   StageJsonPresentationModel presenter =
       new StageJsonPresentationModel(pipeline, stage1, null, new Agents());
   Map json = presenter.toJson();
   assertThat(
       JsonUtils.from(json).getString("builds", 0, "buildLocator"),
       is("pipeline-a%25b/1/stage-c%25d/1/job-%25"));
 }
  @Test
  public void buildByIdWithTransitions_shouldClearFromCacheOnUpdateStatusOfJob() {
    jobInstanceDao.setSqlMapClientTemplate(mockTemplate);

    JobInstance job = JobInstanceMother.assigned("job");
    job.setId(1L);
    when(mockTemplate.queryForObject("buildByIdWithTransitions", 1L)).thenReturn(job);

    JobInstance actual = jobInstanceDao.buildByIdWithTransitions(1L);
    assertThat(actual, is(job));
    assertThat(actual == job, is(false));

    jobInstanceDao.updateStateAndResult(job); // Must clear cahced job instance

    jobInstanceDao.buildByIdWithTransitions(1L);
    verify(mockTemplate, times(2)).queryForObject("buildByIdWithTransitions", 1L);
  }
  @Test
  public void shouldNotAssignCancelledJob() throws Exception {
    AgentIdentifier instance = agent(AgentMother.localAgent());
    Pipeline pipeline =
        instanceFactory.createPipelineInstance(
            evolveConfig,
            modifyNoFiles(evolveConfig),
            new DefaultSchedulingContext(DEFAULT_APPROVED_BY),
            md5,
            new TimeProvider());
    dbHelper.savePipelineWithStagesAndMaterials(pipeline);
    buildAssignmentService.onConfigChange(goConfigService.getCurrentConfig());
    JobInstance job = buildOf(pipeline);
    job.cancel();
    jobInstanceDao.updateStateAndResult(job);

    assertThat(
        buildAssignmentService.assignWorkToAgent(instance),
        is((Work) BuildAssignmentService.NO_WORK));
  }
  @Test
  public void shouldNotScheduleIfAgentDoesNotHaveResources() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    Work work = buildAssignmentService.assignWorkToAgent(agent(AgentMother.localAgent()));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    assertThat(work, is((Work) BuildAssignmentService.NO_WORK));
    assertThat(job.getState(), is(JobState.Scheduled));
    assertThat(job.getAgentUuid(), is(nullValue()));
  }
  @Test
  public void shouldCancelBuildBelongingToNonExistentPipeline() throws Exception {
    fixture.createPipelineWithFirstStageScheduled();
    buildAssignmentService.onTimer();

    configHelper.removePipeline(fixture.pipelineName);

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-other-resource"));

    assertThat(
        (NoWork) buildAssignmentService.assignWorkToAgent(agent(agentConfig)),
        Matchers.is(BuildAssignmentService.NO_WORK));
    Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName);
    JobInstance job = pipeline.getFirstStage().getJobInstances().first();
    assertThat(job.getState(), is(JobState.Completed));
    assertThat(job.getResult(), is(JobResult.Cancelled));
    Stage stage = stageDao.findStageWithIdentifier(job.getIdentifier().getStageIdentifier());
    assertThat(stage.getState(), is(StageState.Cancelled));
    assertThat(stage.getResult(), is(StageResult.Cancelled));
  }
  @Test
  public void shouldCancelBuildsForDeletedJobsWhenPipelineConfigChanges() throws Exception {
    fixture = new PipelineWithTwoStages(materialRepository, transactionTemplate).usingTwoJobs();
    fixture.usingConfigHelper(configHelper).usingDbHelper(dbHelper).onSetUp();
    fixture.createPipelineWithFirstStageScheduled();

    buildAssignmentService.onTimer();
    configHelper.removeJob(fixture.pipelineName, fixture.devStage, fixture.JOB_FOR_DEV_STAGE);

    buildAssignmentService.onPipelineConfigChange(
        goConfigService
            .getCurrentConfig()
            .getPipelineConfigByName(new CaseInsensitiveString(fixture.pipelineName)),
        "g1");

    Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName);
    JobInstance deletedJob =
        pipeline.getFirstStage().getJobInstances().getByName(fixture.JOB_FOR_DEV_STAGE);
    assertThat(deletedJob.getState(), is(JobState.Completed));
    assertThat(deletedJob.getResult(), is(JobResult.Cancelled));
    JobInstance retainedJob =
        pipeline.getFirstStage().getJobInstances().getByName(fixture.DEV_STAGE_SECOND_JOB);
    assertThat(retainedJob.getState(), is(JobState.Scheduled));
    assertThat(retainedJob.getResult(), is(JobResult.Unknown));
  }
 public StageResult completeAllJobs(Stage stage, JobResult jobResult) {
   for (JobInstance job : stage.getJobInstances()) {
     JobInstanceMother.setBuildingState(job);
     job.setAgentUuid(AGENT_UUID);
     job.completing(jobResult);
     job.completed(new DateTime().plusMinutes(5).toDate());
     jobInstanceDao.updateAssignedInfo(job);
   }
   StageResult stageResult;
   switch (jobResult) {
     case Failed:
       stageResult = StageResult.Failed;
       break;
     case Cancelled:
       stageResult = StageResult.Cancelled;
       break;
     default:
       stageResult = StageResult.Passed;
   }
   stage.calculateResult();
   return stageResult;
 }
  @Test
  public void shouldRescheduleAbandonedBuild() throws SQLException {
    AgentIdentifier instance = agent(AgentMother.localAgent());
    Pipeline pipeline =
        instanceFactory.createPipelineInstance(
            evolveConfig,
            modifyNoFiles(evolveConfig),
            new DefaultSchedulingContext(DEFAULT_APPROVED_BY),
            md5,
            new TimeProvider());
    dbHelper.savePipelineWithStagesAndMaterials(pipeline);
    buildAssignmentService.onConfigChange(goConfigService.getCurrentConfig());
    buildAssignmentService.onTimer();
    buildAssignmentService.assignWorkToAgent(instance);
    long firstAssignedBuildId = buildOf(pipeline).getId();

    // somehow agent abandoned its original build...

    buildAssignmentService.assignWorkToAgent(instance);
    JobInstance reloaded = jobInstanceDao.buildByIdWithTransitions(firstAssignedBuildId);
    assertThat(reloaded.getState(), is(JobState.Rescheduled));
    assertThat(reloaded.isIgnored(), is(true));
  }
 public void onefailAndOnePassedBuildInstances(Stage instance) {
   final JobInstance first = instance.getJobInstances().get(0);
   final JobInstance second = instance.getJobInstances().get(1);
   first.completing(Failed);
   second.completing(Failed);
   first.completed(new Date());
   second.completed(new Date());
   jobInstanceDao.updateStateAndResult(first);
   jobInstanceDao.updateStateAndResult(second);
 }
 public void buildInstanceWithDiscontinuedState(Stage instance) {
   final JobInstance first = instance.getJobInstances().get(0);
   final JobInstance second = instance.getJobInstances().get(1);
   first.completing(JobResult.Passed);
   second.changeState(JobState.Discontinued);
   second.setResult(JobResult.Passed);
   first.completed(new Date());
   jobInstanceDao.updateStateAndResult(first);
   jobInstanceDao.updateStateAndResult(second);
   updateResultInTransaction(instance, StageResult.Passed);
 }
  @Test
  public void shouldReScheduleToCorrectAgent() throws Exception {
    JobConfig plan =
        evolveConfig
            .findBy(new CaseInsensitiveString(STAGE_NAME))
            .jobConfigByInstanceName("unit", true);
    plan.addResource("some-resource");

    scheduleHelper.schedule(evolveConfig, modifySomeFiles(evolveConfig), DEFAULT_APPROVED_BY);

    buildAssignmentService.onTimer();

    AgentConfig agentConfig = AgentMother.localAgent();
    agentConfig.addResource(new Resource("some-resource"));
    Work work = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(work, is(not((Work) BuildAssignmentService.NO_WORK)));

    Pipeline pipeline =
        pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance job = pipeline.findStage(STAGE_NAME).findJob("unit");

    JobInstance runningJob = jobInstanceDao.buildByIdWithTransitions(job.getId());

    scheduleService.rescheduleJob(runningJob);

    pipeline = pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(evolveConfig.name()));
    JobInstance rescheduledJob = pipeline.findStage(STAGE_NAME).findJob("unit");

    assertThat(rescheduledJob.getId(), not(runningJob.getId()));

    buildAssignmentService.onTimer();
    Work noResourcesWork =
        buildAssignmentService.assignWorkToAgent(
            agent(AgentMother.localAgentWithResources("WITHOUT_RESOURCES")));
    assertThat(noResourcesWork, is((Work) BuildAssignmentService.NO_WORK));

    buildAssignmentService.onTimer();
    Work correctAgentWork = buildAssignmentService.assignWorkToAgent(agent(agentConfig));
    assertThat(correctAgentWork, is(not((Work) BuildAssignmentService.NO_WORK)));
  }
 public void assignToAgent(JobInstance jobInstance, String agentId) {
   jobInstance.setAgentUuid(agentId);
   jobInstance.changeState(JobState.Assigned);
   jobInstanceDao.updateAssignedInfo(jobInstance);
 }