@Override public boolean hasPipelineNamed(final CaseInsensitiveString pipelineName) { PipelineConfig pipelineConfig = getPipelineConfigByName(pipelineName); return pipelineConfig != null; }
@Override public boolean hasNextStage(final CaseInsensitiveString pipelineName, final CaseInsensitiveString lastStageName) { PipelineConfig pipelineConfig = getPipelineConfigByName(pipelineName); if (pipelineConfig == null) { return false; } return pipelineConfig.nextStage(lastStageName) != null; }
@Override public boolean hasPreviousStage(final CaseInsensitiveString pipelineName, final CaseInsensitiveString stageName) { PipelineConfig pipelineConfig = getPipelineConfigByName(pipelineName); if (pipelineConfig == null) { return false; } return pipelineConfig.previousStage(stageName) != null; }
@Override public boolean hasStageConfigNamed(final CaseInsensitiveString pipelineName, final CaseInsensitiveString stageName, boolean ignoreCase) { PipelineConfig pipelineConfig = getPipelineConfigByName(pipelineName); if (pipelineConfig == null) { return false; } return pipelineConfig.findBy(stageName) != null; }
@Override public boolean requiresApproval(final CaseInsensitiveString pipelineName, final CaseInsensitiveString stageName) { PipelineConfig pipelineConfig = getPipelineConfigByName(pipelineName); if (pipelineConfig == null) { return false; } final StageConfig stageConfig = pipelineConfig.findBy(stageName); return stageConfig != null && stageConfig.requiresApproval(); }
@Override public PipelineConfig pipelineConfigByName(final CaseInsensitiveString name) { if (pipelineNameToConfigMap == null) { pipelineNameToConfigMap = new PipelineNameToConfigMap(); } if (pipelineNameToConfigMap.containsKey(name)) { return pipelineNameToConfigMap.get(name); } PipelineConfig pipelineConfig = getPipelineConfigByName(name); if (pipelineConfig == null) { throw new PipelineNotFoundException("Pipeline '" + name + "' not found."); } pipelineNameToConfigMap.putIfAbsent(pipelineConfig.name(), pipelineConfig); return pipelineConfig; }
private void passReferenceValidationHelper(ConfigOrigin pipelineOrigin, ConfigOrigin envOrigin) { BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("pipe1"); cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("pipe1")).setOrigin(pipelineOrigin); BasicEnvironmentConfig environmentConfig = (BasicEnvironmentConfig) this.environmentConfig; environmentConfig.setOrigins(envOrigin); environmentConfig.addPipeline(new CaseInsensitiveString("pipe1")); cruiseConfig.addEnvironment(environmentConfig); environmentConfig.validate(ConfigSaveValidationContext.forChain(cruiseConfig, environmentConfig)); EnvironmentPipelineConfig reference = environmentConfig.getPipelines().first(); assertThat(reference.errors().isEmpty(),is(true)); }
@Test public void shouldGetDependencyMaterialsForPipelines(){ BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("p1", "p2", "p3"); PipelineConfig p2 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p2")); p2.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p1"),new CaseInsensitiveString("stage") )); PipelineConfig p3 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p3")); p3.addMaterialConfig(new DependencyMaterialConfig(new CaseInsensitiveString("p2"),new CaseInsensitiveString("stage") )); PipelineConfigSaveValidationContext context = PipelineConfigSaveValidationContext.forChain(true, "group", cruiseConfig); assertThat(context.getDependencyMaterialsFor(new CaseInsensitiveString("p1")).getDependencies().isEmpty(), is(true)); assertThat(context.getDependencyMaterialsFor(new CaseInsensitiveString("p2")).getDependencies(), contains(new Node.DependencyNode(new CaseInsensitiveString("p1"),new CaseInsensitiveString("stage")))); assertThat(context.getDependencyMaterialsFor(new CaseInsensitiveString("p3")).getDependencies(), contains(new Node.DependencyNode(new CaseInsensitiveString("p2"),new CaseInsensitiveString("stage")))); assertThat(context.getDependencyMaterialsFor(new CaseInsensitiveString("junk")).getDependencies().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 shouldValidateGroupNameWhenPipelineIsBeingCreatedUnderANonExistantGroup() { BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("p1"); PipelineConfig p1 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p1")); String groupName = "%$-with-invalid-characters"; cruiseConfig.addPipeline(groupName, p1); p1.validateTree(PipelineConfigSaveValidationContext.forChain(true, groupName, cruiseConfig, p1)); assertFalse(p1.errors().isEmpty()); assertThat(p1.errors().on(PipelineConfigs.GROUP), contains("Invalid group name '%$-with-invalid-characters'")); }
@Test public void shouldValidateWhenPipelineNotFound() { ConfigOrigin pipelineOrigin = new RepoConfigOrigin(); ConfigOrigin envOrigin = new FileConfigOrigin(); BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("pipe1"); cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("pipe1")).setOrigin(pipelineOrigin); BasicEnvironmentConfig environmentConfig = (BasicEnvironmentConfig) this.environmentConfig; environmentConfig.setOrigins(envOrigin); environmentConfig.addPipeline(new CaseInsensitiveString("unknown")); cruiseConfig.addEnvironment(environmentConfig); environmentConfig.validate(ConfigSaveValidationContext.forChain(cruiseConfig, environmentConfig)); EnvironmentPipelineConfig reference = environmentConfig.getPipelines().first(); assertThat(reference.errors().isEmpty(),is(true)); }
@Test public void shouldFailValidationIfAStageIsDeletedWhileItsStillReferredToByADownstreamPipeline() { BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("p1", "p2"); PipelineConfig p1 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p1")); PipelineConfig p2 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p2")); p2.addMaterialConfig(new DependencyMaterialConfig(p1.name(), p1.first().name())); String group = cruiseConfig.getGroups().first().getGroup(); StageConfig stageConfig = new StageConfig(new CaseInsensitiveString("s1"), new JobConfigs(new JobConfig(new CaseInsensitiveString("j1")))); PipelineConfig pipelineConfig = new PipelineConfig(p1.name(), new MaterialConfigs(), stageConfig); cruiseConfig.update(group, pipelineConfig.name().toString(), pipelineConfig); PipelineConfigSaveValidationContext validationContext = PipelineConfigSaveValidationContext.forChain(false, group, cruiseConfig, pipelineConfig); pipelineConfig.validateTree(validationContext); assertThat(pipelineConfig.errors().on("base"), is("Stage with name 'stage' does not exist on pipeline 'p1', it is being referred to from pipeline 'p2' (cruise-config.xml)")); }
@Test public void validate_shouldNotAllowToReferencePipelineDefinedInConfigRepo_WhenEnvironmentDefinedInFile() { ConfigOrigin pipelineOrigin = new RepoConfigOrigin(); ConfigOrigin envOrigin = new FileConfigOrigin(); BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("pipe1"); cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("pipe1")).setOrigin(pipelineOrigin); BasicEnvironmentConfig environmentConfig = (BasicEnvironmentConfig) this.environmentConfig; environmentConfig.setOrigins(envOrigin); environmentConfig.addPipeline(new CaseInsensitiveString("pipe1")); cruiseConfig.addEnvironment(environmentConfig); environmentConfig.validate(ConfigSaveValidationContext.forChain(cruiseConfig, environmentConfig)); EnvironmentPipelineConfig reference = environmentConfig.getPipelines().first(); assertThat(reference.errors().isEmpty(),is(false)); assertThat(reference.errors().on(EnvironmentPipelineConfig.ORIGIN),startsWith("Environment defined in")); }
@Test public void shouldAddValidationErrorsFromStagesOntoPipelineIfPipelineIsAssociatedToATemplate() { BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("p1", "p2", "p3"); PipelineConfig p1 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p1")); PipelineConfig p2 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p2")); PipelineConfig p3 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p3")); p2.addMaterialConfig(new DependencyMaterialConfig(p1.name(), p1.first().name())); p3.addMaterialConfig(new DependencyMaterialConfig(p2.name(), p2.first().name())); p3.first().getJobs().first().addTask(new FetchTask(new CaseInsensitiveString("p1/p2"), p1.first().name(), p1.first().getJobs().first().name(), "src", "dest")); StageConfig stageConfig = new StageConfig(new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig(new CaseInsensitiveString("new-job")))); PipelineConfig pipelineConfig = new PipelineConfig(p1.name(), new MaterialConfigs(), stageConfig); String group = cruiseConfig.getGroups().first().getGroup(); cruiseConfig.update(group, pipelineConfig.name().toString(), pipelineConfig); PipelineConfigSaveValidationContext validationContext = PipelineConfigSaveValidationContext.forChain(false, group, cruiseConfig, pipelineConfig); pipelineConfig.validateTree(validationContext); assertThat(pipelineConfig.errors().on("base"), is("\"p3 :: stage :: job\" tries to fetch artifact from job \"p1 :: stage :: job\" which does not exist.")); }
@Test public void shouldFailValidationIfAJobIsDeletedWhileItsStillReferredToByADescendentPipelineThroughFetchArtifact() { BasicCruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("p1", "p2", "p3"); PipelineConfig p1 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p1")); PipelineConfig p2 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p2")); PipelineConfig p3 = cruiseConfig.getPipelineConfigByName(new CaseInsensitiveString("p3")); p2.addMaterialConfig(new DependencyMaterialConfig(p1.name(), p1.first().name())); JobConfig p2S2J2 = new JobConfig(new CaseInsensitiveString("j2")); p2S2J2.addTask(fetchTaskFromSamePipeline(p2)); p2.add(new StageConfig(new CaseInsensitiveString("stage2"), new JobConfigs(p2S2J2))); p3.addMaterialConfig(new DependencyMaterialConfig(p2.name(), p2.first().name())); p3.first().getJobs().first().addTask(new FetchTask(new CaseInsensitiveString("p1/p2"), p1.first().name(), p1.first().getJobs().first().name(), "src", "dest")); StageConfig stageConfig = new StageConfig(new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig(new CaseInsensitiveString("new-job")))); PipelineConfig pipelineConfig = new PipelineConfig(p1.name(), new MaterialConfigs(), stageConfig); String group = cruiseConfig.getGroups().first().getGroup(); cruiseConfig.update(group, pipelineConfig.name().toString(), pipelineConfig); PipelineConfigSaveValidationContext validationContext = PipelineConfigSaveValidationContext.forChain(false, group, cruiseConfig, pipelineConfig); pipelineConfig.validateTree(validationContext); assertThat(pipelineConfig.errors().on("base"), is("\"p3 :: stage :: job\" tries to fetch artifact from job \"p1 :: stage :: job\" which does not exist.")); }