public static PipelineTemplateConfig createTemplateWithParams(String templateName, String... paramNameAndValue) { PipelineTemplateConfig template = createTemplate(templateName); for (String nameAndValue : paramNameAndValue) { template.get(0).getJobs().get(0).addVariable(String.format("name-%s", nameAndValue), String.format("value-#{%s}", nameAndValue)); } return template; } }
@Test public void shouldAddJobsGivenInTheAttributesMapAfterClearingExistingJobs() throws Exception{ JobConfigs jobs = new JobConfigs(); jobs.add(new JobConfig("quux")); jobs.setConfigAttributes(a(m(JobConfig.NAME, "foo"), m(JobConfig.NAME, "bar"))); assertThat(jobs.get(0).name(), is(new CaseInsensitiveString("foo"))); assertThat(jobs.get(1).name(), is(new CaseInsensitiveString("bar"))); assertThat(jobs.size(), is(2)); }
@Test public void shouldValidateWorkingDirectory() { ExecTask task = new ExecTask("ls", "-l", "../../../assertTaskInvalid"); CruiseConfig config = GoConfigMother.configWithPipelines("pipeline"); PipelineConfig pipeline = config.pipelineConfigByName(new CaseInsensitiveString("pipeline")); StageConfig stage = pipeline.get(0); JobConfig job = stage.getJobs().get(0); job.addTask(task); List<ConfigErrors> errors = config.validateAfterPreprocess(); assertThat(errors.size(), is(1)); String message = "The path of the working directory for the custom command in job 'job' in stage 'stage' of pipeline 'pipeline' is outside the agent sandbox."; assertThat(errors.get(0).firstError(), is(message)); assertThat(task.errors().on(ExecTask.WORKING_DIR), is(message)); }
@Test public void shouldPickupJobConfigDetailsFromAttributeMap() throws Exception{ StageConfig config = new StageConfig(); Map stageAttrs = m(StageConfig.JOBS, a(m(JobConfig.NAME, "con-job"), m(JobConfig.NAME, "boring-job"))); config.setConfigAttributes(stageAttrs); assertThat(config.getJobs().get(0).name(), is(new CaseInsensitiveString("con-job"))); assertThat(config.getJobs().get(1).name(), is(new CaseInsensitiveString("boring-job"))); }
private StageConfig stageWithJobResource(String resourceName) { StageConfig stage = StageConfigMother.custom("stage", "job"); JobConfigs configs = stage.allBuildPlans(); ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.setName(resourceName); configs.get(0).resourceConfigs().add(resourceConfig); return stage; } }
@Test public void shouldErrorOutIfWorkingDirectoryIsOutsideTheCurrentWorkingDirectoryForTemplates() { CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-blah"); BuildTask task = new AntTask(); task.setWorkingDirectory("/blah"); StageConfig stageConfig = StageConfigMother.manualStage("manualStage"); stageConfig.getJobs().get(0).addTask(task); PipelineTemplateConfig template = new PipelineTemplateConfig(new CaseInsensitiveString("some-template"), stageConfig); config.addTemplate(template); List<ConfigErrors> errors = config.validateAfterPreprocess(); assertThat(errors.size(), is(1)); String message = "Task of job 'default' in stage 'manualStage' of template 'some-template' has path '/blah' which is outside the working directory."; assertThat(task.errors().on(BuildTask.WORKING_DIRECTORY), is(message)); } }
private void validateAndAssertIncorrectPath(String source, boolean isSourceDir, String destination, String propertyName) { StageConfig stage = upstream.getFirstStageConfig(); JobConfig job = stage.getJobs().get(0); FetchTask task = new FetchTask(upstream.name(), stage.name(), job.name(), null, destination); if (isSourceDir) { task.setSrcdir(source); } else { task.setSrcfile(source); } task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), upstream, stage, job)); assertThat(task.errors().isEmpty(), is(false)); String path = propertyName.equals(FetchTask.SRC) ? source : destination; String message = String.format("Task of job '%s' in stage '%s' of pipeline '%s' has %s path '%s' which is outside the working directory.", job.name(), stage.name(), upstream.name(), propertyName, path); assertThat(task.errors().on(propertyName), is(message)); }
@Test public void shouldPassValidationWhenSrcAndDestDirectoryAreInsideAgentSandbox() { StageConfig stage = upstream.getFirstStageConfig(); JobConfig job = stage.getJobs().get(0); FetchTask task = new FetchTask(upstream.name(), stage.name(), job.name(), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(upstream, stage, job)); assertThat(task.errors().isEmpty(), is(true)); }
@Test public void shouldAllowEditingOfJobNameWhenItIsNotUsedAsFetchArtifact() throws Exception { PipelineTemplateConfig template = new PipelineTemplateConfig(new CaseInsensitiveString("template"), StageConfigMother.oneBuildPlanWithResourcesAndMaterials("stage", "job2")); BasicCruiseConfig cruiseConfig = GoConfigMother.defaultCruiseConfig(); cruiseConfig.addTemplate(template); template.getStages().get(0).getJobs().get(0).setName(new CaseInsensitiveString("updatedJobName")); template.validateTree(ConfigSaveValidationContext.forChain(cruiseConfig), cruiseConfig, false); assertThat(template.errors().isEmpty(), is(true)); }
@Test public void shouldPassValidationWhenFetchingFromAnInstanceOfRunOnAllJob() { StageConfig stage = upstream.getFirstStageConfig(); JobConfig job = stage.getJobs().get(0); job.setRunOnAllAgents(true); FetchTask task = new FetchTask(upstream.name(), stage.name(), new CaseInsensitiveString(job.name() + "-runOnAll-1"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), upstream, stage, job)); assertThat(task.errors().on(FetchTask.JOB), is(Matchers.nullValue())); }
@Test public void validate_withinTemplates_shouldPopulateErrorOnSrcFileOrSrcDirOrDestIfIsNotAValidFilePathPattern() { String dest = ".."; String src = ".."; PipelineTemplateConfig template = PipelineTemplateConfigMother.createTemplate("template-1"); StageConfig stage = template.get(0); JobConfig job = stage.getJobs().get(0); FetchTask task = new FetchTask(template.name(), stage.name(), job.name(), src, dest); ValidationContext context = ConfigSaveValidationContext.forChain(config, template, stage, job); task.validate(context); assertThat(task.errors().isEmpty(), is(false)); String messageForSrc = String.format("Task of job '%s' in stage '%s' of template '%s' has src path '%s' which is outside the working directory.", job.name(), stage.name(), template.name(), src); assertThat(task.errors().on(FetchTask.SRC), is(messageForSrc)); String messageForDest = String.format("Task of job '%s' in stage '%s' of template '%s' has dest path '%s' which is outside the working directory.", job.name(), stage.name(), template.name(), dest); assertThat(task.errors().on(FetchTask.DEST), is(messageForDest)); }
@Test public void should_NOT_BeValidWhen_NO_pathFromAncestorIsGiven_butAncestorPipelineIsBeingFetchedFrom() { FetchTask task = new FetchTask(null, new CaseInsensitiveString("uppest-stage3"), new CaseInsensitiveString("uppest-job3"), "src", "dest"); StageConfig stage = downstream.getStage(new CaseInsensitiveString("stage")); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, stage, stage.getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.STAGE), is("\"downstream :: stage :: job\" tries to fetch artifact from stage \"downstream :: uppest-stage3\" which does not exist.")); }
@Test public void should_NOT_BeValidWhen_NO_pathFromAncestorIsGiven_butAncestorPipelineIsBeingFetchedFrom() { FetchPluggableArtifactTask task = new FetchPluggableArtifactTask(null, new CaseInsensitiveString("uppest-stage3"), new CaseInsensitiveString("uppest-job3"), "s3"); StageConfig stage = downstream.getStage(new CaseInsensitiveString("stage")); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, stage, stage.getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.STAGE), is("\"downstream :: stage :: job\" tries to fetch artifact from stage \"downstream :: uppest-stage3\" which does not exist.")); }
@Test public void shouldReturnDuplicateWithPipelineNameEmptyIfFetchArtifactTaskIsFetchingFromSamePipeline() { PipelineConfig pipelineConfig = PipelineConfigMother.createPipelineConfig("somePipeline", "stage", "job"); StageConfig stageConfig = pipelineConfig.get(0); JobConfig jobConfig = stageConfig.getJobs().get(0); Tasks originalTasks = jobConfig.getTasks(); originalTasks.add(new FetchTask(pipelineConfig.name(), stageConfig.name(), jobConfig.name(), "src", "dest")); originalTasks.add(new FetchTask(new CaseInsensitiveString("some_other_pipeline"), stageConfig.name(), jobConfig.name(), "src", "dest")); PipelineConfig clone = pipelineConfig.duplicate(); Tasks clonedTasks = clone.get(0).getJobs().get(0).getTasks(); assertThat(((FetchTask) clonedTasks.get(0)).getTargetPipelineName(), is(new CaseInsensitiveString(""))); assertThat(((FetchTask) clonedTasks.get(1)).getTargetPipelineName(), is(new CaseInsensitiveString("some_other_pipeline"))); assertThat(((FetchTask) originalTasks.get(0)).getTargetPipelineName(), is(pipelineConfig.name())); }
@Test public void validate_shouldPopulateErrorOnSrcFileOrSrcDirOrDestIfIsNotAValidFilePathPattern() { FetchTask task = new FetchTask(new CaseInsensitiveString(""), new CaseInsensitiveString(""), new CaseInsensitiveString(""), "", ""); task.validateAttributes(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")), downstream.getStage( new CaseInsensitiveString("stage")).getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.SRC), is("Should provide either srcdir or srcfile")); }
@Test public void shouldPopulateErrorIfFetchArtifactFromDependentPipelineButStageDoesNotExist() { FetchPluggableArtifactTask task = new FetchPluggableArtifactTask(new CaseInsensitiveString("upstream"), new CaseInsensitiveString("stage-does-not-exist"), new CaseInsensitiveString("job"), "s3"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")), downstream.getStage( new CaseInsensitiveString("stage")), downstream.getStage(new CaseInsensitiveString("stage")).getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.STAGE), is("\"downstream :: stage :: job\" tries to fetch artifact from stage " + "\"upstream :: stage-does-not-exist\" which does not exist.")); }
@Test public void shouldPopulateErrorIfFetchArtifactFromDependentPipelineButStageDoesNotExist() { FetchTask task = new FetchTask(new CaseInsensitiveString("upstream"), new CaseInsensitiveString("stage-does-not-exist"), new CaseInsensitiveString("job"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")), downstream.getStage( new CaseInsensitiveString("stage")), downstream.getStage(new CaseInsensitiveString("stage")).getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.STAGE), is("\"downstream :: stage :: job\" tries to fetch artifact from stage " + "\"upstream :: stage-does-not-exist\" which does not exist.")); }
@Test public void should_NOT_BeValidWhen_ImmediateParentDeclaredInPathFromAncestor_isNotAParentPipeline_PipelineConfigValidationContext() { PipelineConfig upstreamsPeer = config.pipelineConfigByName(new CaseInsensitiveString("upstreams_peer")); upstreamsPeer.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("uppest_stream", "uppest-stage1"))); upstreamsPeer.add(StageConfigMother.stageConfig("peer-stage", new JobConfigs(new JobConfig("peer-job")))); downstream = config.pipelineConfigByName(new CaseInsensitiveString("downstream")); downstream.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("upstream", "up-stage1"), MaterialConfigsMother.dependencyMaterialConfig("upstreams_peer", "peer-stage"))); FetchPluggableArtifactTask task = new FetchPluggableArtifactTask(new CaseInsensitiveString("upstream/uppest_stream"), new CaseInsensitiveString("up-stage1"), new CaseInsensitiveString("up-job1"), "s3"); StageConfig stage = downstream.getStage(new CaseInsensitiveString("stage")); task.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", config, downstream, stage, stage.getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.PIPELINE_NAME), is("Pipeline named 'uppest_stream' exists, but is not an ancestor of 'downstream' as declared in 'upstream/uppest_stream'.")); }
@Test public void should_NOT_BeValidWhen_ImmediateParentDeclaredInPathFromAncestor_isNotAParentPipeline_PipelineConfigValidationContext() { PipelineConfig upstreamsPeer = config.pipelineConfigByName(new CaseInsensitiveString("upstreams_peer")); upstreamsPeer.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("uppest_stream", "uppest-stage1"))); upstreamsPeer.add(StageConfigMother.stageConfig("peer-stage", new JobConfigs(new JobConfig("peer-job")))); downstream = config.pipelineConfigByName(new CaseInsensitiveString("downstream")); downstream.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("upstream", "up-stage1"), MaterialConfigsMother.dependencyMaterialConfig("upstreams_peer", "peer-stage"))); FetchTask task = new FetchTask(new CaseInsensitiveString("upstream/uppest_stream"), new CaseInsensitiveString("up-stage1"), new CaseInsensitiveString("up-job1"), "src", "dest"); StageConfig stage = downstream.getStage(new CaseInsensitiveString("stage")); task.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", config, downstream, stage, stage.getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.PIPELINE_NAME), is("Pipeline named 'uppest_stream' exists, but is not an ancestor of 'downstream' as declared in 'upstream/uppest_stream'.")); }
@Test public void should_NOT_BeValidWhen_ImmediateParentDeclaredInPathFromAncestor_isNotAParentPipeline() { PipelineConfig upstreamsPeer = config.pipelineConfigByName(new CaseInsensitiveString("upstreams_peer")); upstreamsPeer.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("uppest_stream", "uppest-stage1"))); upstreamsPeer.add(StageConfigMother.stageConfig("peer-stage", new JobConfigs(new JobConfig("peer-job")))); downstream = config.pipelineConfigByName(new CaseInsensitiveString("downstream")); downstream.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.dependencyMaterialConfig("upstream", "up-stage1"), MaterialConfigsMother.dependencyMaterialConfig("upstreams_peer", "peer-stage"))); FetchTask task = new FetchTask(new CaseInsensitiveString("upstream/uppest_stream"), new CaseInsensitiveString("up-stage1"), new CaseInsensitiveString("up-job1"), "src", "dest"); StageConfig stage = downstream.getStage(new CaseInsensitiveString("stage")); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, stage, stage.getJobs().get(0))); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.PIPELINE_NAME), is("Pipeline named 'uppest_stream' exists, but is not an ancestor of 'downstream' as declared in 'upstream/uppest_stream'.")); }