@Test public void shouldNotScheduleAnyNewPipelineWhenErrorHappens() throws Exception { String stageName = "invalidStageName"; PipelineConfig invalidPipeline = configHelper.addPipelineWithInvalidMaterial("invalidPipeline", stageName); int beforeScheduling = pipelineDao.count(CaseInsensitiveString.str(invalidPipeline.name())); autoSchedulePipelines(); int afterScheduling = pipelineDao.count(CaseInsensitiveString.str(invalidPipeline.name())); assertThat(beforeScheduling, is(afterScheduling)); }
@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 shouldForceStagePlanWithModificationsSinceLast() throws Exception { Pipeline completedMingle = scheduleAndCompleteInitialPipelines(); pipelineDao.loadPipeline(completedMingle.getId()); TestingMaterial testingMaterial = new TestingMaterial(); mingleConfig.setMaterialConfigs(new MaterialConfigs(testingMaterial.config())); MaterialRevisions revisions = new MaterialRevisions(); revisions.addRevision( testingMaterial, testingMaterial.modificationsSince(null, null, subprocessExecutionContext)); BuildCause buildCause = BuildCause.createManualForced(revisions, Username.ANONYMOUS); dbHelper.saveMaterials(buildCause.getMaterialRevisions()); Pipeline forcedPipeline = instanceFactory.createPipelineInstance( mingleConfig, buildCause, new DefaultSchedulingContext(DEFAULT_APPROVED_BY), md5, new TimeProvider()); pipelineService.save(forcedPipeline); verifyMingleScheduledWithModifications(); }
@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)); }
@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())); }
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)); }
@Before public void setup() throws Exception { diskSpaceSimulator = new DiskSpaceSimulator(); new HgTestRepo("testHgRepo"); svnRepository = new SvnTestRepo("testSvnRepo"); dbHelper.onSetUp(); configHelper.onSetUp(); configHelper.usingCruiseConfigDao(goConfigDao).initializeConfigFile(); repository = new SvnCommand(null, svnRepository.projectRepositoryUrl()); goParentPipelineConfig = configHelper.addPipeline( GO_PIPELINE_UPSTREAM, STAGE_NAME, new MaterialConfigs(new GitMaterialConfig("foo-bar")), "unit"); goPipelineConfig = configHelper.addPipeline(GO_PIPELINE_NAME, STAGE_NAME, repository, "unit"); svnMaterialRevs = new MaterialRevisions(); SvnMaterial svnMaterial = SvnMaterial.createSvnMaterialWithMock(repository); svnMaterialRevs.addRevision( svnMaterial, svnMaterial.latestModification( null, new ServerSubprocessExecutionContext(goConfigService, new SystemEnvironment()))); final MaterialRevisions materialRevisions = new MaterialRevisions(); SvnMaterial anotherSvnMaterial = SvnMaterial.createSvnMaterialWithMock(repository); materialRevisions.addRevision( anotherSvnMaterial, anotherSvnMaterial.latestModification(null, subprocessExecutionContext)); transactionTemplate.execute( new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { materialRepository.save(svnMaterialRevs); } }); BuildCause buildCause = BuildCause.createWithModifications(svnMaterialRevs, ""); mingleConfig = configHelper.addPipeline( MINGLE_PIPELINE_NAME, STAGE_NAME, repository, new Filter(new IgnoredFiles("**/*.doc")), "unit", "functional"); latestPipeline = PipelineMother.schedule(this.mingleConfig, buildCause); latestPipeline = pipelineDao.saveWithStages(latestPipeline); dbHelper.passStage(latestPipeline.getStages().first()); pipelineScheduleQueue.clear(); }
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); }
private Pipeline passFirstStage(PipelineConfig pipelineConfig) { Stage completedMingleStage = stageDao.mostRecentWithBuilds( CaseInsensitiveString.str(pipelineConfig.name()), pipelineConfig.findBy(new CaseInsensitiveString("dev"))); dbHelper.passStage(completedMingleStage); dbHelper.passStage(completedMingleStage); assertThat(completedMingleStage.getJobInstances().first().getState(), is(JobState.Completed)); Pipeline pipeline = pipelineDao.mostRecentPipeline(CaseInsensitiveString.str(pipelineConfig.name())); return dbHelper.passPipeline(pipeline); }
@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))); }
@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)); }
@Test public void shouldLockPipelineWhenSchedulingStage() throws Exception { scheduleAndCompleteInitialPipelines(); Pipeline pipeline = pipelineDao.mostRecentPipeline("mingle"); configHelper.lockPipeline("mingle"); assertThat(pipelineLockService.isLocked("mingle"), is(false)); scheduleService.scheduleStage( pipeline, STAGE_NAME, "anonymous", new ScheduleService.NewStageInstanceCreator(goConfigService), new ScheduleService.ExceptioningErrorHandler()); assertThat(pipelineLockService.isLocked("mingle"), is(true)); }
@Test public void should_NOT_schedulePipeline_whenOneOfTheMaterialsHasNoModificationsPresent() throws Exception { Pipeline latestGoInstance = PipelineMother.schedule( goPipelineConfig, BuildCause.createManualForced( svnMaterialRevs, new Username(new CaseInsensitiveString("loser")))); latestGoInstance = pipelineDao.saveWithStages(latestGoInstance); dbHelper.passStage(latestGoInstance.getStages().first()); configHelper.addMaterialToPipeline( GO_PIPELINE_NAME, new DependencyMaterialConfig( new CaseInsensitiveString(GO_PIPELINE_UPSTREAM), new CaseInsensitiveString(STAGE_NAME))); svnRepository.checkInOneFile("a.java"); scheduleHelper.autoSchedulePipelinesWithRealMaterials(GO_PIPELINE_NAME); assertThat(pipelineScheduleQueue.toBeScheduled().keySet(), not(hasItem(GO_PIPELINE_NAME))); }
@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 shouldPassEnvironmentLevelEnvironmentVariablesToJobsForNewlyScheduledStage() throws Exception { scheduleAndCompleteInitialPipelines(); Pipeline pipeline = pipelineDao.mostRecentPipeline("go"); Stage stage = scheduleService.scheduleStage( pipeline, "ft", "anonymous", new ScheduleService.NewStageInstanceCreator(goConfigService), new ScheduleService.ExceptioningErrorHandler()); EnvironmentVariablesConfig jobVariables = stage.getJobInstances().first().getPlan().getVariables(); assertThat( jobVariables.size(), is(3)); // pipeline, stage, job, env is applied while creating work assertThat( jobVariables, hasItem(new EnvironmentVariableConfig("PIPELINE_LVL", "pipeline value"))); assertThat(jobVariables, hasItem(new EnvironmentVariableConfig("STAGE_LVL", "stage value"))); assertThat(jobVariables, hasItem(new EnvironmentVariableConfig("JOB_LVL", "job value"))); }
private void runAndPass(MaterialRevisions mingleRev) { BuildCause buildCause = BuildCause.createWithModifications(mingleRev, "boozer"); latestPipeline = PipelineMother.schedule(mingleConfig, buildCause); latestPipeline = pipelineDao.saveWithStages(latestPipeline); dbHelper.passStage(latestPipeline.getStages().first()); }
@Test public void shouldNotReloadScheduledJobPlansWhenAgentWorkAssignmentIsInProgress() throws Exception { fixture.createPipelineWithFirstStageScheduled(); Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName); JobInstance job = pipeline.getFirstStage().getJobInstances().first(); final JobInstanceService mockJobInstanceService = mock(JobInstanceService.class); final Pipeline pipeline1 = pipeline; final Semaphore sem = new Semaphore(1); sem.acquire(); when(mockJobInstanceService.orderedScheduledBuilds()) .thenReturn(jobInstanceService.orderedScheduledBuilds()); when(mockJobInstanceService.buildByIdWithTransitions(job.getId())) .thenReturn(jobInstanceService.buildByIdWithTransitions(job.getId())); ScheduledPipelineLoader scheduledPipelineLoader = new ScheduledPipelineLoader(null, null, null, null, null, null, null, null) { @Override public Pipeline pipelineWithPasswordAwareBuildCauseByBuildId(long buildId) { sem.release(); sleepQuietly(1000); verify(mockJobInstanceService, times(1)).orderedScheduledBuilds(); return pipeline1; } }; final BuildAssignmentService buildAssignmentServiceUnderTest = new BuildAssignmentService( goConfigService, mockJobInstanceService, scheduleService, agentService, environmentConfigService, timeProvider, transactionTemplate, scheduledPipelineLoader, pipelineService, builderFactory, agentRemoteHandler); final Throwable[] fromThread = new Throwable[1]; buildAssignmentServiceUnderTest.onTimer(); Thread assigner = new Thread( new Runnable() { public void run() { try { final AgentConfig agentConfig = AgentMother.localAgentWithResources("some-other-resource"); buildAssignmentServiceUnderTest.assignWorkToAgent(agent(agentConfig)); } catch (Throwable e) { e.printStackTrace(); fromThread[0] = e; } finally { } } }, "assignmentThread"); assigner.start(); sem.acquire(); buildAssignmentServiceUnderTest.onTimer(); assigner.join(); assertThat(fromThread[0], is(nullValue())); }