private void addToErrorsBaseOnMaterialsIfDoesNotExist(String errorMessage, MaterialConfigs materialConfigs, List<PipelineConfig> pipelineConfigs) { for (PipelineConfig config : pipelineConfigs) { if (config.materialConfigs().errors().getAll().contains(errorMessage)) { return; } } materialConfigs.addError("base", errorMessage); }
public boolean validateTree(PipelineConfigSaveValidationContext validationContext) { if (isEmpty()) { errors().add("materials", "A pipeline must have at least one material"); } validate(validationContext); boolean isValid = errors().isEmpty(); for (MaterialConfig materialConfig : this) { isValid = materialConfig.validateTree(validationContext) && isValid; } return isValid; }
@Test public void shouldFailValidationInNoMaterialPresent(){ MaterialConfigs materialConfigs = new MaterialConfigs(); assertThat(materialConfigs.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", new PipelineConfig())), is(false)); assertThat(materialConfigs.errors().firstError(), is("A pipeline must have at least one material")); }
@Test public void shouldErrorOutWhenTwoPipelinesDependsOnEachOther() throws Exception { CruiseConfig cruiseConfig = createCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); goConfigMother.setDependencyOn(cruiseConfig, pipeline1, "pipeline2", "stage"); cruiseConfig.validate(null); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(false)); assertThat(pipeline2.materialConfigs().errors().isEmpty(), is(false)); }
@Test public void shouldReturnValidWhenThereIsNoCycle() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); pipeline1.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig)); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(true)); pipeline2.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig)); assertThat(pipeline2.materialConfigs().errors().isEmpty(), is(true)); } @Test
@Test public void shouldErrorOutWhenDependsOnItself() throws Exception { CruiseConfig cruiseConfig = createCruiseConfig(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); goConfigMother.addStageToPipeline(cruiseConfig, "pipeline1", "ft", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipelineConfig, "pipeline1", "ft"); cruiseConfig.validate(null); ConfigErrors errors = pipelineConfig.materialConfigs().errors(); assertThat(errors.on("base"), is("Circular dependency: pipeline1 <- pipeline1")); }
@Test public void shouldErrorOutWhenThreePipelinesFormACycle() throws Exception { CruiseConfig cruiseConfig = createCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); SvnMaterialConfig material = (SvnMaterialConfig) pipeline1.materialConfigs().get(0); material.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "svn_dir")); P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view"); p4MaterialConfig.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "p4_folder")); pipeline1.addMaterialConfig(p4MaterialConfig); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline3", "stage", "build"); PipelineConfig pipeline3 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline3, "pipeline3", "stage"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); goConfigMother.setDependencyOn(cruiseConfig, pipeline1, "pipeline2", "stage"); cruiseConfig.validate(null); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(false)); assertThat(pipeline2.materialConfigs().errors().isEmpty(), is(false)); assertThat(pipeline3.materialConfigs().errors().isEmpty(), is(false)); }
@Test public void shouldReturnTrueWhenNoDependencyDefined() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); pipelineConfig.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig)); assertThat(pipelineConfig.materialConfigs().errors().isEmpty(), is(true)); }
@Test public void shouldReturnTrueWhenDependencyPipelineDoesNotExist() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipelineConfig, "pipeline2", "stage"); pipelineConfig.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipelineConfig)); assertThat(pipelineConfig.materialConfigs().errors().isEmpty(), is(true)); }
public static void toJSON(OutputWriter jsonWriter, PipelineConfig pipelineConfig) { jsonWriter.addLinks(linksWriter -> linksWriter .addLink("self", Routes.PipelineConfig.name(pipelineConfig.getName().toString())) .addAbsoluteLink("doc", Routes.PipelineConfig.DOC) .addLink("find", Routes.PipelineConfig.find())); // This is needed for the case when there are no materials defined. Refer to pipeline_config_representer.rb#152 pipelineConfig.errors().addAll(pipelineConfig.materialConfigs().errors()); if (!pipelineConfig.errors().isEmpty()) { jsonWriter.addChild("errors", errorWriter -> { HashMap<String, String> errorMapping = new HashMap<>(); errorMapping.put("labelTemplate", "label_template"); errorMapping.put("params", "parameters"); errorMapping.put("variables", "environment_variables"); errorMapping.put("trackingTool", "tracking_tool"); new ErrorGetter(errorMapping).toJSON(errorWriter, pipelineConfig); }); } jsonWriter.add("label_template", pipelineConfig.getLabelTemplate()); jsonWriter.add("lock_behavior", pipelineConfig.getLockBehavior()); jsonWriter.add("name", pipelineConfig.name()); jsonWriter.add("template", pipelineConfig.getTemplateName()); writeOrigin(jsonWriter, pipelineConfig.getOrigin()); jsonWriter.addChildList("parameters", paramsWriter -> ParamRepresenter.toJSONArray(paramsWriter, pipelineConfig.getParams())); jsonWriter.addChildList("environment_variables", envVarsWriter -> EnvironmentVariableRepresenter.toJSON(envVarsWriter, pipelineConfig.getVariables())); jsonWriter.addChildList("materials", materialsWriter -> MaterialRepresenter.toJSONArray(materialsWriter, pipelineConfig.materialConfigs())); writeStages(jsonWriter, pipelineConfig); writeTrackingTool(jsonWriter, pipelineConfig); writeTimer(jsonWriter, pipelineConfig.getTimer()); }
@Test public void shouldValidateAndUpdatePipelineConfig() { PipelineConfig pipeline = new PipelineConfig(); pipeline.setName("validPipeline"); pipeline.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.gitMaterialConfig(), MaterialConfigsMother.svnMaterialConfig())); StageConfig stage1 = getStageConfig("stage1", "s1j1"); StageConfig stage2 = getStageConfig("stage2", "s2j1"); pipeline.getStages().add(stage1); pipeline.getStages().add(stage2); BasicCruiseConfig cruiseConfig = new BasicCruiseConfig(new BasicPipelineConfigs("group", new Authorization(), pipeline)); boolean isValid = pipeline.validateTree(PipelineConfigSaveValidationContext.forChain(true, cruiseConfig.getGroups().first().getGroup(), cruiseConfig, pipeline)); assertThat(isValid, is(true)); assertThat(pipeline.materialConfigs().errors().isEmpty(), is(true)); assertThat(pipeline.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipeline.materialConfigs().get(1).errors().isEmpty(), is(true)); assertThat(pipeline.errors().getAll().isEmpty(), is(true)); }
@Test public void shouldAllowToDependOnPipelineDefinedInFile_WhenInFile() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); pipeline1.setOrigin(new FileConfigOrigin()); pipeline2.setOrigin(new FileConfigOrigin()); pipeline1.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline1)); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(true)); pipeline2.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline2)); DependencyMaterialConfig dep = pipeline2.materialConfigs().findDependencyMaterial(new CaseInsensitiveString("pipeline1")); assertThat(dep.errors().isEmpty(), is(true)); }
@Test public void shouldValidateTree() { PipelineConfig pipeline = new PipelineConfig(); pipeline.setName("pipeline"); pipeline.addEnvironmentVariable("", ""); pipeline.addParam(new ParamConfig("", "")); pipeline.setMaterialConfigs(new MaterialConfigs(MaterialConfigsMother.gitMaterialConfig(), MaterialConfigsMother.svnMaterialConfig())); StageConfig stage1 = getStageConfig("stage1", "s1j1"); StageConfig stage2 = getStageConfig("stage2", "s2j1"); pipeline.getStages().add(stage1); pipeline.getStages().add(stage2); BasicCruiseConfig cruiseConfig = new BasicCruiseConfig(new BasicPipelineConfigs("group", new Authorization(), pipeline)); boolean isValid = pipeline.validateTree(PipelineConfigSaveValidationContext.forChain(true, cruiseConfig.getGroups().first().getGroup(), cruiseConfig, pipeline)); assertThat(isValid, is(false)); assertThat(pipeline.getVariables().get(0).errors().firstError(), is("Environment Variable cannot have an empty name for pipeline 'pipeline'.")); assertThat(pipeline.getParams().get(0).errors().firstError(), is("Parameter cannot have an empty name for pipeline 'pipeline'.")); assertThat(pipeline.materialConfigs().errors().isEmpty(), is(true)); assertThat(pipeline.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipeline.materialConfigs().get(1).errors().isEmpty(), is(true)); assertThat(pipeline.errors().getAll().isEmpty(), is(true)); }
@Test public void shouldDetectCyclicDependencies() { String pipelineName = "p1"; BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines(pipelineName, "p2", "p3"); PipelineConfig p2 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p2")); p2.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString(pipelineName), new CaseInsensitiveString("stage"))); PipelineConfig p3 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p3")); p3.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p2"), new CaseInsensitiveString("stage"))); PipelineConfig p1 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString(pipelineName)); p1 = new Cloner().deepClone(p1); // Do not remove cloning else it changes the underlying cache object defeating the purpose of the test. p1.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p3"), new CaseInsensitiveString("stage"))); p1.validateTree(PipelineConfigSaveValidationContext.forChain(true, cruiseConfig.getGroups().first().getGroup(), cruiseConfig, p1)); assertThat(p1.materialConfigs().errors().isEmpty(), is(false)); assertThat(p1.materialConfigs().errors().on("base"), is("Circular dependency: p1 <- p2 <- p3 <- p1")); }
@Test public void shouldNotAllowToDependOnPipelineDefinedInConfigRepository_WhenDownstreamInFile() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); pipeline1.setOrigin(new RepoConfigOrigin()); pipeline2.setOrigin(new FileConfigOrigin()); pipeline1.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline1)); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(true)); pipeline2.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline2)); DependencyMaterialConfig invalidDependency = pipeline2.materialConfigs().findDependencyMaterial(new CaseInsensitiveString("pipeline1")); assertThat(invalidDependency.errors().isEmpty(), is(false)); assertThat(invalidDependency.errors().on(DependencyMaterialConfig.ORIGIN),startsWith("Dependency from pipeline defined in")); } @Test
@Test public void shouldAllowToDependOnPipelineDefinedInConfigRepository_WhenInConfigRepository() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = goConfigMother.addPipeline(cruiseConfig, "pipeline2", "stage", "build"); goConfigMother.setDependencyOn(cruiseConfig, pipeline2, "pipeline1", "stage"); pipeline1.setOrigin(new RepoConfigOrigin(new ConfigRepoConfig(new SvnMaterialConfig("http://mysvn", false), "myplugin"), "123")); pipeline2.setOrigin(new RepoConfigOrigin(new ConfigRepoConfig(new SvnMaterialConfig("http://othersvn", false), "myplugin"), "2222")); pipeline1.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline1)); assertThat(pipeline1.materialConfigs().errors().isEmpty(), is(true)); pipeline2.materialConfigs().validate(ConfigSaveValidationContext.forChain(cruiseConfig, new BasicPipelineConfigs(), pipeline2)); DependencyMaterialConfig dep = pipeline2.materialConfigs().findDependencyMaterial(new CaseInsensitiveString("pipeline1")); assertThat(dep.errors().isEmpty(), is(true)); } @Test