private boolean isValidMaterial() { MaterialConfig materialConfig = getMaterialConfig(); if (materialConfig == null) { return false; } return materialConfig.errors().isEmpty(); }
private static void addErrors(OutputWriter json, MaterialConfig material) { if (!material.errors().isEmpty()) { json.addChild("errors", errorWriter -> new ErrorGetter(ERROR_MAPPING).toJSON(errorWriter, material)); } } }
public boolean validateTree(ValidationContext validationContext) { validate(validationContext); boolean isValid = errors.isEmpty(); if (getMaterialConfig() != null) { isValid = getMaterialConfig().errors().isEmpty() && isValid; } return isValid; }
private void validateAutoUpdateState(ValidationContext validationContext) { if (validationContext == null) return; MaterialConfig material = this.getMaterialConfig(); if (material != null) { MaterialConfigs allMaterialsByFingerPrint = validationContext.getAllMaterialsByFingerPrint(material.getFingerprint()); if (allMaterialsByFingerPrint.stream().anyMatch(m -> !m.isAutoUpdate())) { getMaterialConfig().errors().add("autoUpdate", format("Material of type %s (%s) is specified as a configuration repository and pipeline material with disabled autoUpdate." + " All copies of this material must have autoUpdate enabled or configuration repository must be removed", material.getTypeForDisplay(), material.getDescription())); } } }
private void validateAutoUpdateEnabled() { if (this.getMaterialConfig() != null) { if (!this.getMaterialConfig().isAutoUpdate()) this.getMaterialConfig().errors().add("autoUpdate", format( "Configuration repository material '%s' must have autoUpdate enabled.", this.getMaterialConfig().getDisplayName())); } }
@Test public void validateTree_shouldValidateTheMaterialConfig() { CruiseConfig cruiseConfig = new BasicCruiseConfig(); MaterialConfig materialConfig = mock(MaterialConfig.class); when(materialConfig.errors()).thenReturn(new ConfigErrors()); ConfigRepoConfig configRepoConfig = new ConfigRepoConfig(materialConfig, "plug"); cruiseConfig.setConfigRepos(new ConfigReposConfig(configRepoConfig)); ConfigSaveValidationContext validationContext = ConfigSaveValidationContext.forChain(cruiseConfig); configRepoConfig.validateTree(validationContext); verify(materialConfig).validateTree(validationContext); }
@Test public void validateTree_configRepoShouldBeInvalidIfMaterialConfigHasErrors() { CruiseConfig cruiseConfig = new BasicCruiseConfig(); MaterialConfig materialConfig = mock(MaterialConfig.class); when(materialConfig.errors()).thenReturn(new ConfigErrors()); ConfigRepoConfig configRepoConfig = new ConfigRepoConfig(materialConfig, "plug", "id"); cruiseConfig.setConfigRepos(new ConfigReposConfig(configRepoConfig)); ConfigSaveValidationContext validationContext = ConfigSaveValidationContext.forChain(cruiseConfig); assertFalse(configRepoConfig.validateTree(validationContext)); assertTrue(configRepoConfig.errors().isEmpty()); assertFalse(configRepoConfig.getMaterialConfig().errors().isEmpty()); }
@Test @RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, WINDOWS}) public void shouldFailIfMultipleMaterialsHaveSameFolderNameSet_CaseInSensitive() { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder")); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url2", null); materialTwo.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "foLder")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne, materialTwo)); MaterialConfigs materials = pipelineOne.materialConfigs(); materials.validate(ConfigSaveValidationContext.forChain(config)); assertThat(materials.get(0).errors().isEmpty(), is(false)); assertThat(materials.get(1).errors().isEmpty(), is(false)); assertThat(materials.get(0).errors().on(ScmMaterialConfig.FOLDER), is("The destination directory must be unique across materials.")); assertThat(materials.get(1).errors().on(ScmMaterialConfig.FOLDER), is("The destination directory must be unique across materials.")); }
@Test public void shouldNotFailIfMultipleMaterialsHaveUniqueDestinationFolderSet() { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder")); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url2", null); materialTwo.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder2")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne, materialTwo)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(pipelineOne.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipelineOne.materialConfigs().get(1).errors().isEmpty(), is(true)); }
@Test public void shouldFailIfMultipleMaterialsDoNotHaveDestinationFolderSet() { HgMaterialConfig materialConfigOne = new HgMaterialConfig("http://url1", null); materialConfigOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder")); HgMaterialConfig materialConfigTwo = new HgMaterialConfig("http://url2", null); PluggableSCMMaterialConfig materialConfigThree = new PluggableSCMMaterialConfig(null, SCMMother.create("scm-id"), null, null); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs((new MaterialConfigs(materialConfigOne, materialConfigTwo, materialConfigThree))); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(pipelineOne.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipelineOne.materialConfigs().get(1).errors().on(ScmMaterialConfig.FOLDER), is("Destination directory is required when specifying multiple scm materials")); assertThat(pipelineOne.materialConfigs().get(2).errors().on(PluggableSCMMaterialConfig.FOLDER), is("Destination directory is required when specifying multiple scm materials")); }
@Test public void shouldFailIfAllScmMaterialsInAPipelineHaveSameFolders() throws IOException { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder1")); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url2", null); materialTwo.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder1")); PluggableSCMMaterialConfig materialThree = new PluggableSCMMaterialConfig(null, SCMMother.create("scm-id"), "folder1", null); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne, materialTwo, materialThree)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); String conflictingDirMessage = "Invalid Destination Directory. Every material needs a different destination directory and the directories should not be nested."; assertThat(pipelineOne.materialConfigs().get(0).errors().on(ScmMaterialConfig.FOLDER), is(conflictingDirMessage)); assertThat(pipelineOne.materialConfigs().get(1).errors().on(ScmMaterialConfig.FOLDER), is(conflictingDirMessage)); assertThat(pipelineOne.materialConfigs().get(2).errors().on(PluggableSCMMaterialConfig.FOLDER), is(conflictingDirMessage)); }
@Test public void shouldNotFailIfAllScmMaterialsInAPipelineHaveDifferentFolders() { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder1")); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url2", null); materialTwo.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder2")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne, materialTwo)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(pipelineOne.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipelineOne.materialConfigs().get(1).errors().isEmpty(), is(true)); }
@Test public void validate_shouldValidateTheMaterialConfig() { CruiseConfig cruiseConfig = new BasicCruiseConfig(); GitMaterialConfig materialConfig = new GitMaterialConfig(null, "master"); ConfigRepoConfig configRepoConfig = new ConfigRepoConfig(materialConfig, "plug"); cruiseConfig.setConfigRepos(new ConfigReposConfig(configRepoConfig)); ConfigSaveValidationContext validationContext = ConfigSaveValidationContext.forChain(cruiseConfig); configRepoConfig.validate(validationContext); assertThat(configRepoConfig.getMaterialConfig().errors().on("url"), is("URL cannot be blank")); }
@Test public void shouldFailValidateWhenUpstreamPipelineForDependencyMaterialDoesNotExist() { String upstreamPipeline = "non-existant"; PipelineConfig pipelineConfig = GoConfigMother.createPipelineConfigWithMaterialConfig( new DependencyMaterialConfig(new CaseInsensitiveString(upstreamPipeline), new CaseInsensitiveString("non-existant"))); BasicCruiseConfig cruiseConfig = new BasicCruiseConfig(new BasicPipelineConfigs(pipelineConfig)); boolean isValid = pipelineConfig.validateTree(PipelineConfigSaveValidationContext.forChain(true, cruiseConfig.getGroups().first().getGroup(), cruiseConfig, pipelineConfig)); assertThat(isValid, is(false)); ConfigErrors materialErrors = pipelineConfig.materialConfigs().first().errors(); assertThat(materialErrors.isEmpty(), is(false)); assertThat(materialErrors.firstError(), is("Pipeline with name 'non-existant' does not exist, it is defined as a dependency for pipeline 'pipeline' (cruise-config.xml)")); }
@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 shouldNotThrowUpOnMaterialIfAutoUpdateValuesAreCorrect() throws Exception { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setAutoUpdate(true); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url1", null); materialTwo.setAutoUpdate(true); CruiseConfig config = GoConfigMother.configWithPipelines("one", "two", "three"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne)); PipelineConfig pipelineTwo = config.pipelineConfigByName(new CaseInsensitiveString("two")); pipelineTwo.setMaterialConfigs(new MaterialConfigs(materialTwo)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(pipelineOne.materialConfigs().get(0).errors().isEmpty(), is(true)); assertThat(pipelineTwo.materialConfigs().get(0).errors().isEmpty(), is(true)); }
@Test public void shouldAddErrorWhenMatchingPackageIDDoesNotExist(){ PackageMaterialConfig packageMaterialConfig = new PackageMaterialConfig(new CaseInsensitiveString("package-name"), "package-id", PackageDefinitionMother.create("package-id")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("one")); MaterialConfigs materialConfigs = new MaterialConfigs(packageMaterialConfig); pipelineConfig.setMaterialConfigs(materialConfigs); materialConfigs.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", config)); assertThat(pipelineConfig.materialConfigs().get(0).errors().on(packageMaterialConfig.PACKAGE_ID), is("Could not find repository for given package id:[package-id]")); }
@Test public void shouldFailValidateWhenUpstreamStageForDependencyMaterialDoesNotExist() { String upstreamPipeline = "upstream"; String upstreamStage = "non-existant"; PipelineConfig upstream = GoConfigMother.createPipelineConfigWithMaterialConfig(upstreamPipeline, new GitMaterialConfig("url")); PipelineConfig pipelineConfig = GoConfigMother.createPipelineConfigWithMaterialConfig("downstream", new DependencyMaterialConfig(new CaseInsensitiveString(upstreamPipeline), new CaseInsensitiveString(upstreamStage))); BasicCruiseConfig cruiseConfig = new BasicCruiseConfig(new BasicPipelineConfigs(pipelineConfig, upstream)); boolean isValid = pipelineConfig.validateTree(PipelineConfigSaveValidationContext.forChain(true, cruiseConfig.getGroups().first().getGroup(), cruiseConfig, pipelineConfig)); assertThat(isValid, is(false)); ConfigErrors materialErrors = pipelineConfig.materialConfigs().first().errors(); assertThat(materialErrors.isEmpty(), is(false)); assertThat(materialErrors.firstError(), is("Stage with name 'non-existant' does not exist on pipeline 'upstream', it is being referred to from pipeline 'downstream' (cruise-config.xml)")); }
@Test public void shouldAddErrorWhenMatchingScmConfigDoesNotExist(){ PluggableSCMMaterialConfig scmMaterialConfig = new PluggableSCMMaterialConfig(null, SCMMother.create("scm-id"), null, null); PackageMaterialConfig packageMaterialConfig = new PackageMaterialConfig(new CaseInsensitiveString("package-name"), "package-id", PackageDefinitionMother.create("package-id")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("one")); MaterialConfigs materialConfigs = new MaterialConfigs(scmMaterialConfig,packageMaterialConfig); pipelineConfig.setMaterialConfigs(materialConfigs); materialConfigs.validateTree(PipelineConfigSaveValidationContext.forChain(true, "group", config)); assertThat(pipelineConfig.materialConfigs().get(0).errors().on(scmMaterialConfig.SCM_ID), is("Could not find SCM for given scm-id: [scm-id].")); }
@Test public void shouldAddErrorOnMaterialIfAutoUpdateDoesNotMatchAcrossFingerPrint() throws Exception { HgMaterialConfig materialOne = new HgMaterialConfig("http://url1", null); materialOne.setAutoUpdate(false); HgMaterialConfig materialTwo = new HgMaterialConfig("http://url1", null); materialTwo.setAutoUpdate(true); CruiseConfig config = GoConfigMother.configWithPipelines("one", "two"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(materialOne)); PipelineConfig pipelineTwo = config.pipelineConfigByName(new CaseInsensitiveString("two")); pipelineTwo.setMaterialConfigs(new MaterialConfigs(materialTwo)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(pipelineOne.materialConfigs().get(0).errors().on(ScmMaterialConfig.AUTO_UPDATE), is("Material of type Mercurial (http://url1) is specified more than once in the configuration with different values for the autoUpdate attribute. All copies of this material must have the same value for this attribute.")); }