public Stage createStageInstance(PipelineConfig pipelineConfig, CaseInsensitiveString stageName, SchedulingContext context, String md5, Clock clock) { StageConfig stageConfig = pipelineConfig.findBy(stageName); if (stageConfig == null) { throw new StageNotFoundException(pipelineConfig.name(), stageName); } return createStageInstance(stageConfig, context, md5, clock); }
private static Pipeline createPipelineInstance(PipelineConfig pipelineConfig, BuildCause cause, String approvedBy) { return new InstanceFactory().createPipelineInstance(pipelineConfig, cause, new DefaultSchedulingContext(approvedBy), "md5-test", new TimeProvider()); }
@Test public void shouldFailWhenDoesNotFindAnyMatchingAgents() throws Exception { JobConfig jobConfig = new JobConfig("foo"); jobConfig.setRunOnAllAgents(true); SchedulingContext context = mock(SchedulingContext.class); when(context.getApprovedBy()).thenReturn("chris"); when(context.findAgentsMatching(new ResourceConfigs())).thenReturn(new ArrayList<>()); when(context.getEnvironmentVariablesConfig()).thenReturn(new EnvironmentVariablesConfig()); when(context.overrideEnvironmentVariables(any(EnvironmentVariablesConfig.class))).thenReturn(context); try { RunOnAllAgents.CounterBasedJobNameGenerator jobNameGenerator = new RunOnAllAgents.CounterBasedJobNameGenerator(CaseInsensitiveString.str(jobConfig.name())); instanceFactory.createJobInstance(new CaseInsensitiveString("myStage"), jobConfig, new DefaultSchedulingContext(), new TimeProvider(), jobNameGenerator); fail("should have failed as no agents matched"); } catch (Exception e) { assertThat(e.getMessage(), is("Could not find matching agents to run job [foo] of stage [myStage].")); } }
private static Stage scheduleInstance(StageConfig stageConfig) { Stage stageInstance = new InstanceFactory().createStageInstance(stageConfig, new DefaultSchedulingContext(DEFAULT_APPROVED_BY), "md5-test", new TimeProvider()); stageInstance.building(); return stageInstance; }
@Test public void shouldNotRerun_WhenJobConfigIsChangedToRunMultipleInstance_ForSingleJobInstance() { Date old = new DateTime().minusDays(2).toDate(); StageConfig stageConfig = StageConfigMother.custom("dev", "rails", "java"); JobConfig railsConfig = stageConfig.getJobs().getJob(new CaseInsensitiveString("rails")); DefaultSchedulingContext schedulingContext = new DefaultSchedulingContext("loser", new Agents()); JobInstances jobs = instanceFactory.createJobInstance(new CaseInsensitiveString("dev"), railsConfig, schedulingContext, new TimeProvider(), null); Stage stage = createStageInstance(old, jobs); Stage newStage = null; railsConfig.setRunInstanceCount(10); CannotRerunJobException exception = null; try { newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails"), schedulingContext, stageConfig, new TimeProvider(), "md5"); fail("should not schedule since job config changed to run multiple instance"); } catch (CannotRerunJobException e) { exception = e; } assertThat(exception.getJobName(), is("rails")); assertThat(exception.getInformation(), is("Run configuration for job has been changed to 'run multiple instance'.")); assertThat(newStage, is(nullValue())); }
public Pipeline createPipeline(final BuildCause buildCause, final PipelineConfig pipelineConfig, final SchedulingContext context, final String md5, final Clock clock) { return (Pipeline) transactionTemplate.execute((TransactionCallback) status -> { Pipeline pipeline = null; if (shouldCancel(buildCause, pipelineConfig.name())) { LOGGER.debug("[Pipeline Schedule] Cancelling scheduling as build cause {} is the same as the most recent schedule", buildCause); cancelSchedule(pipelineConfig.name()); } else { try { Pipeline newPipeline = instanceFactory.createPipelineInstance(pipelineConfig, buildCause, context, md5, clock); pipeline = pipelineService.save(newPipeline); finishSchedule(pipelineConfig.name(), buildCause, pipeline.getBuildCause()); LOGGER.debug("[Pipeline Schedule] Successfully scheduled pipeline {}, buildCause:{}, configOrigin: {}", pipelineConfig.name(), buildCause, pipelineConfig.getOrigin()); } catch (BuildCauseOutOfDateException e) { cancelSchedule(pipelineConfig.name()); LOGGER.info("[Pipeline Schedule] Build cause {} is out of date. Scheduling is cancelled. Go will reschedule this pipeline. configOrigin: {}", buildCause, pipelineConfig.getOrigin()); } } return pipeline; }); }
String latestMd5 = goConfigService.getCurrentConfig().getMd5(); try { return instanceFactory.createStageForRerunOfJobs(stage, jobNames, context, stageConfig, timeProvider, latestMd5); } catch (CannotRerunJobException e) { result.notFound(e.getMessage(), e.getMessage(), healthStateForStage);
public void reallyCreateJobInstance(JobConfig config, JobInstances jobs, String uuid, String jobName, boolean runOnAllAgents, boolean runMultipleInstance, SchedulingContext context, final Clock clock) { JobInstance instance = new JobInstance(jobName, clock); instance.setPlan(createJobPlan(config, context)); instance.setAgentUuid(uuid); instance.setRunOnAllAgents(runOnAllAgents); instance.setRunMultipleInstance(runMultipleInstance); jobs.add(instance); }
@Before public void setUp() throws Exception { instanceFactory = new InstanceFactory(); this.clock = mock(Clock.class); }
public Stage createStageInstance(StageConfig stageConfig, SchedulingContext context, String md5, Clock clock) { return new Stage(CaseInsensitiveString.str(stageConfig.name()), createJobInstances(stageConfig, context, clock), context.getApprovedBy(), null, stageConfig.approvalType(), stageConfig.isFetchMaterials(), stageConfig.isCleanWorkingDir(), md5, clock); }
@Test public void shouldNotRerun_WhenJobConfigDoesNotExistAnymore_ForRunMultipleInstance() { Date old = new DateTime().minusDays(2).toDate(); StageConfig stageConfig = StageConfigMother.custom("dev", "rails", "java"); JobConfig railsConfig = stageConfig.getJobs().getJob(new CaseInsensitiveString("rails")); railsConfig.setRunInstanceCount(3); DefaultSchedulingContext schedulingContext = new DefaultSchedulingContext("loser", new Agents()); RunMultipleInstance.CounterBasedJobNameGenerator jobNameGenerator = new RunMultipleInstance.CounterBasedJobNameGenerator(CaseInsensitiveString.str(railsConfig.name())); JobInstances jobs = instanceFactory.createJobInstance(new CaseInsensitiveString("dev"), railsConfig, schedulingContext, new TimeProvider(), jobNameGenerator); Stage stage = createStageInstance(old, jobs); Stage newStage = null; CannotRerunJobException exception = null; try { newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails-runInstance-1"), schedulingContext, StageConfigMother.custom("dev", "java"), new TimeProvider(), "md5"); fail("should not schedule when job config does not exist anymore"); } catch (CannotRerunJobException e) { exception = e; } assertThat(exception.getJobName(), is("rails")); assertThat(exception.getInformation(), is("Configuration for job doesn't exist.")); assertThat(newStage, is(nullValue())); }
public static StageInstanceModels stageHistory(PipelineConfig pipelineConfig, Date modificationDate) { StageInstanceModels history = new StageInstanceModels(); for (StageConfig stageConfig : pipelineConfig) { StageInstanceModel item = new StageInstanceModel(CaseInsensitiveString.str(stageConfig.name()), "1", buildHistory(stageConfig, modificationDate)); item.setCounter("1"); item.setApprovalType(new InstanceFactory().createStageInstance(stageConfig, new DefaultSchedulingContext("anyone"), md5, new TimeProvider()).getApprovalType()); if (stageConfig.requiresApproval()) { item.setApprovedBy(APPROVED_BY); } else { item.setApprovedBy(GoConstants.DEFAULT_APPROVED_BY); } history.add(item); } return history; }
@Test public void shouldSchedulePipelineWithFirstStage() { StageConfig stageOneConfig = StageConfigMother.stageConfig("dev", BuildPlanMother.withBuildPlans("functional", "unit")); StageConfig stageTwoConfig = StageConfigMother.stageConfig("qa", BuildPlanMother.withBuildPlans("suiteOne", "suiteTwo")); MaterialConfigs materialConfigs = MaterialConfigsMother.defaultMaterialConfigs(); PipelineConfig pipelineConfig = new PipelineConfig(new CaseInsensitiveString("mingle"), materialConfigs, stageOneConfig, stageTwoConfig); BuildCause buildCause = BuildCause.createManualForced(modifyOneFile(pipelineConfig), Username.ANONYMOUS); Pipeline pipeline = instanceFactory.createPipelineInstance(pipelineConfig, buildCause, new DefaultSchedulingContext("test"), "some-md5", new TimeProvider()); assertThat(pipeline.getName(), is("mingle")); assertThat(pipeline.getStages().size(), is(1)); assertThat(pipeline.getStages().get(0).getName(), is("dev")); assertThat(pipeline.getStages().get(0).getJobInstances().get(0).getName(), is("functional")); }
@Test public void shouldClearAgentAssignment_ForSingleInstanceJobType() { Date old = new DateTime().minusDays(2).toDate(); JobInstance rails = jobInstance(old, "rails", 7, 10); JobInstance java = jobInstance(old, "java", 12, 22); Stage stage = stage(9, rails, java); Stage newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails"), new DefaultSchedulingContext("loser", new Agents()), StageConfigMother.custom("dev", "rails", "java"), new TimeProvider(), "md5"); assertThat(newStage.getJobInstances().getByName("rails").getAgentUuid(), is(nullValue())); assertThat(newStage.getJobInstances().getByName("java").getAgentUuid(), is(not(nullValue()))); }
@Test public void shouldAddEnvironmentVariablesToJobPlan() { EnvironmentVariablesConfig variablesConfig = new EnvironmentVariablesConfig(); variablesConfig.add("blahVar", "blahVal"); JobConfig jobConfig = new JobConfig("foo"); jobConfig.setVariables(variablesConfig); SchedulingContext context = new DefaultSchedulingContext(); JobPlan plan = instanceFactory.createJobPlan(jobConfig, context); assertThat(plan.getVariables(), hasItem(new EnvironmentVariable("blahVar", "blahVal"))); }
public Stage scheduleStage(String pipelineName, String stageName, SchedulingContext context) { PipelineConfig pipelineConfig = getCurrentConfig().pipelineConfigByName(new CaseInsensitiveString(pipelineName)); return instanceFactory.createStageInstance(pipelineConfig, new CaseInsensitiveString(stageName), context, getCurrentConfig().getMd5(), clock); }
JobInstances jobs = instanceFactory.createJobInstance(new CaseInsensitiveString("dev"), railsConfig, schedulingContext, new TimeProvider(), jobNameGenerator); newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails-runInstance-1"), schedulingContext, stageConfig, new TimeProvider(), "md5"); fail("should not schedule since job config changed to run multiple instance"); } catch (CannotRerunJobException e) { newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails-runInstance-1"), schedulingContext, stageConfig, new TimeProvider(), "md5"); fail("should not schedule since job config changed to run multiple instance"); } catch (CannotRerunJobException e) {
@Test public void shouldCreateASingleJobIfRunOnAllAgentsIsFalse() throws Exception { JobConfig jobConfig = new JobConfig("foo"); SchedulingContext context = mock(SchedulingContext.class); when(context.getEnvironmentVariablesConfig()).thenReturn(new EnvironmentVariablesConfig()); when(context.overrideEnvironmentVariables(any(EnvironmentVariablesConfig.class))).thenReturn(context); RunOnAllAgents.CounterBasedJobNameGenerator jobNameGenerator = new RunOnAllAgents.CounterBasedJobNameGenerator(CaseInsensitiveString.str(jobConfig.name())); JobInstances jobs = instanceFactory.createJobInstance(new CaseInsensitiveString("someStage"), jobConfig, new DefaultSchedulingContext(), new TimeProvider(), jobNameGenerator); assertThat(jobs.toArray(), hasItemInArray(hasProperty("name", is("foo")))); assertThat(jobs.toArray(), hasItemInArray(hasProperty("agentUuid", nullValue()))); assertThat(jobs.toArray(), hasItemInArray(hasProperty("runOnAllAgents", is(false)))); assertThat(jobs.size(), is(1)); }
@Test public void shouldCreatePipelineInstanceWithEnvironmentVariablesOverriddenAccordingToScope() { StageConfig stageConfig = StageConfigMother.custom("stage", "foo", "bar"); JobConfig fooConfig = stageConfig.jobConfigByConfigName(new CaseInsensitiveString("foo")); fooConfig.addVariable("foo", "foo"); JobConfig barConfig = stageConfig.jobConfigByConfigName(new CaseInsensitiveString("bar")); barConfig.addVariable("foo", "bar"); MaterialConfigs materialConfigs = MaterialConfigsMother.defaultMaterialConfigs(); PipelineConfig pipelineConfig = new PipelineConfig(new CaseInsensitiveString("pipeline"), materialConfigs, stageConfig); DefaultSchedulingContext context = new DefaultSchedulingContext("anonymous"); Pipeline instance = instanceFactory.createPipelineInstance(pipelineConfig, ModificationsMother.forceBuild(pipelineConfig), context, "some-md5", new TimeProvider()); assertThat(instance.findStage("stage").findJob("foo").getPlan().getVariables(), is(new EnvironmentVariables(Arrays.asList(new EnvironmentVariable("foo", "foo"))))); assertThat(instance.findStage("stage").findJob("bar").getPlan().getVariables(), is(new EnvironmentVariables(Arrays.asList(new EnvironmentVariable("foo", "bar"))))); }
@Test public void shouldNotRerun_WhenJobConfigDoesNotExistAnymore_ForSingleInstanceJob() { Date old = new DateTime().minusDays(2).toDate(); JobInstance rails = jobInstance(old, "rails", 7, 10); JobInstance java = jobInstance(old, "java", 12, 22); Stage stage = stage(9, rails, java); Stage newStage = null; CannotRerunJobException exception = null; try { newStage = instanceFactory.createStageForRerunOfJobs(stage, a("rails"), new DefaultSchedulingContext("loser", new Agents()), StageConfigMother.custom("dev", "java"), new TimeProvider(), "md5"); fail("should not schedule when job config does not exist anymore"); } catch (CannotRerunJobException e) { exception = e; } assertThat(exception.getJobName(), is("rails")); assertThat(newStage, is(nullValue())); }