public static List<ConfigErrors> validate(CruiseConfig config) { List<ConfigErrors> validationErrors = new ArrayList<>(); validationErrors.addAll(config.validateAfterPreprocess()); return validationErrors; }
public static List<ConfigErrors> validate(CruiseConfig config) { preprocess(config); List<ConfigErrors> validationErrors = new ArrayList<>(); validationErrors.addAll(config.validateAfterPreprocess()); return validationErrors; }
@Test public void shouldIgnoreConstantFieldsWhileCollectingErrorsToAvoidPotentialCycles() { CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1"); List<ConfigErrors> allErrors = config.validateAfterPreprocess(); assertThat(allErrors.size(), is(0)); }
@Test public void agentWithNoIpAddressShouldBeValid() throws Exception { CruiseConfig cruiseConfig = new BasicCruiseConfig(); AgentConfig agent = new AgentConfig("uuid", null, null); cruiseConfig.agents().add(agent); assertThat(cruiseConfig.validateAfterPreprocess().isEmpty(), is(true)); }
@Test public void shouldCollectPipelineNameConflictErrorsInTheChildren_InMergedConfig_WhenPipelinesIn2Groups() { BasicCruiseConfig mainCruiseConfig = GoConfigMother.configWithPipelines("pipeline-1"); PartialConfig partialConfig = PartialConfigMother.withPipelineInGroup("pipeline-1", "g2"); partialConfig.setOrigin(new RepoConfigOrigin()); CruiseConfig config = new BasicCruiseConfig(mainCruiseConfig, partialConfig); List<ConfigErrors> allErrors = config.validateAfterPreprocess(); assertThat(allErrors.size(), is(2)); assertThat(allErrors.get(0).on("name"), is("You have defined multiple pipelines named 'pipeline-1'. Pipeline names must be unique. Source(s): [http://some.git at 1234fed, cruise-config.xml]")); assertThat(allErrors.get(1).on("name"), is("You have defined multiple pipelines named 'pipeline-1'. Pipeline names must be unique. Source(s): [http://some.git at 1234fed, cruise-config.xml]")); }
@Test public void shouldCollectPipelineNameConflictErrorsInTheChildren_InMergedConfig_WhenCloned() { //we need this case because cloning has proven to be problematic with complex object graph in merged config BasicCruiseConfig mainCruiseConfig = GoConfigMother.configWithPipelines("pipeline-1"); PartialConfig partialConfig = PartialConfigMother.withPipelineInGroup("pipeline-1", "g2"); partialConfig.setOrigin(new RepoConfigOrigin()); CruiseConfig config = new BasicCruiseConfig(mainCruiseConfig, partialConfig); Cloner CLONER = new Cloner(); CruiseConfig cloned = CLONER.deepClone(config); List<ConfigErrors> allErrors = cloned.validateAfterPreprocess(); assertThat(allErrors.size(), is(2)); assertThat(allErrors.get(0).on("name"), is("You have defined multiple pipelines named 'pipeline-1'. Pipeline names must be unique. Source(s): [http://some.git at 1234fed, cruise-config.xml]")); assertThat(allErrors.get(1).on("name"), is("You have defined multiple pipelines named 'pipeline-1'. Pipeline names must be unique. Source(s): [http://some.git at 1234fed, cruise-config.xml]")); }
@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 shouldEnsureStageNameUniqueness() { CruiseConfig cruiseConfig = new BasicCruiseConfig(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); JobConfig jobConfig = new JobConfig("my-build"); jobConfig.addTask(new ExecTask("ls", "-la", "tmp")); StageConfig stageConfig = new StageConfig(new CaseInsensitiveString("stage"), new JobConfigs(jobConfig)); pipelineConfig.addStageWithoutValidityAssertion(stageConfig); pipelineConfig.validate(null); assertThat(stageConfig.errors().getAllOn("name"), is(singletonList("You have defined multiple stages called 'stage'. Stage names are case-insensitive and must be unique."))); assertThat(pipelineConfig.get(0).errors().getAllOn("name"), is(singletonList("You have defined multiple stages called 'stage'. Stage names are case-insensitive and must be unique."))); assertThat(cruiseConfig.validateAfterPreprocess().get(0).getAllOn("name"), is(singletonList("You have defined multiple stages called 'stage'. Stage names are case-insensitive and must be unique."))); }
protected void shouldCollectAllTheErrorsInTheChildrenHelper(CruiseConfig config) { SecurityAuthConfig ldapConfig = new SecurityAuthConfig("ldap", "cd.go.authorization.ldap"); ldapConfig.errors().add("uri", "invalid ldap uri"); ldapConfig.errors().add("searchBase", "invalid search base"); config.server().security().securityAuthConfigs().add(ldapConfig); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1")); pipelineConfig.errors().add("base", "Some base errors"); P4MaterialConfig p4MaterialConfig = new P4MaterialConfig("localhost:1999", "view"); p4MaterialConfig.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "p4_folder")); pipelineConfig.addMaterialConfig(p4MaterialConfig); p4MaterialConfig.errors().add("materialName", "material name does not follow pattern"); StageConfig stage = pipelineConfig.first(); stage.errors().add("role", "Roles must be proper"); List<ConfigErrors> allErrors = config.validateAfterPreprocess(); assertThat(allErrors.size(), is(5)); assertThat(allErrors.get(0).on("uri"), is("invalid ldap uri")); assertThat(allErrors.get(0).on("searchBase"), is("invalid search base")); assertThat(allErrors.get(1).on("base"), is("Some base errors")); assertThat(allErrors.get(2).on("role"), is("Roles must be proper")); assertThat(allErrors.get(3).on(ScmMaterialConfig.FOLDER), is("Destination directory is required when specifying multiple scm materials")); assertThat(allErrors.get(4).on("materialName"), is("material name does not follow pattern")); }
@Test public void mergeShouldThrowWhenCalledSecondTime() { cruiseConfig = new BasicCruiseConfig(new BasicCruiseConfig(pipelines), PartialConfigMother.withEnvironment("remote-env")); assertThat(cruiseConfig.getEnvironments().size(),is(1)); try { cruiseConfig.merge(Arrays.asList(PartialConfigMother.withEnvironment("remote-env")), false); } catch (RuntimeException ex) { //ok assertThat(cruiseConfig.getEnvironments().size(),is(1)); cruiseConfig.validateAfterPreprocess(); return; } fail("should have thrown"); }
@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)); } }
@Test public void shouldErrorOutIfWorkingDirectoryIsOutsideTheCurrentWorkingDirectory() { BuildTask task = new BuildTask() { @Override public String getTaskType() { return "build"; } public String getTypeForDisplay() { return null; } @Override public String command() { return null; } @Override public String arguments() { return null; } }; task.setWorkingDirectory("/blah"); 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 = "Task of job 'job' in stage 'stage' of pipeline 'pipeline' has path '/blah' which is outside the working directory."; assertThat(task.errors().on(BuildTask.WORKING_DIRECTORY), is(message)); }
@Test public void shouldCollectOriginErrorsFromMaterialConfigs_InMergedConfig() { BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines); PartialConfig partialConfig = PartialConfigMother.withPipelineInGroup("pipe2", "g2"); partialConfig.getGroups().get(0).get(0).setOrigin(new RepoConfigOrigin()); cruiseConfig = new BasicCruiseConfig(mainCruiseConfig, partialConfig); PipelineConfig pipeline1 = goConfigMother.addPipeline(cruiseConfig, "pipeline1", "stage", "build"); PipelineConfig pipeline2 = PipelineConfigMother.createPipelineConfigWithStage("pipeline2", "stage"); pipeline2.setOrigin(new RepoConfigOrigin()); partialConfig.getGroups().addPipeline("g2", pipeline2); goConfigMother.setDependencyOn(cruiseConfig, pipeline1, "pipeline2", "stage"); List<ConfigErrors> allErrors = cruiseConfig.validateAfterPreprocess(); assertThat(allErrors.size(), is(1)); assertNotNull(allErrors.get(0).on("origin")); }
@Test public void shouldPopulateErrorMessagesWhenHasJobNamesRepeated() { CruiseConfig config = new BasicCruiseConfig(); PipelineConfig pipelineConfig = PipelineConfigMother.createPipelineConfig("pipeline", "stage-1", "con-job"); config.addPipeline("group-foo", pipelineConfig); StageConfig stageConfig = pipelineConfig.get(0); JobConfig newJob = new JobConfig("foo!"); StageConfig newlyAddedStage = new StageConfig(new CaseInsensitiveString("."), new JobConfigs(newJob)); pipelineConfig.addStageWithoutValidityAssertion(newlyAddedStage); stageConfig.getJobs().addJobWithoutValidityAssertion(new JobConfig(new CaseInsensitiveString("con-job"), new ResourceConfigs(), new ArtifactConfigs(), new Tasks(new ExecTask("ls", "-la", "foo")))); List<ConfigErrors> allErrors = config.validateAfterPreprocess(); assertThat(allErrors.size(), is(4)); assertThat(allErrors.get(0).on(JobConfig.NAME), is("You have defined multiple jobs called 'con-job'. Job names are case-insensitive and must be unique.")); assertThat(allErrors.get(1).on(JobConfig.NAME), is("You have defined multiple jobs called 'con-job'. Job names are case-insensitive and must be unique.")); assertThat(allErrors.get(2).on(StageConfig.NAME), is("Invalid stage name '.'. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters.")); assertThat(allErrors.get(3).on(JobConfig.NAME), is("Invalid job name 'foo!'. This must be alphanumeric and may contain underscores and periods. The maximum allowed length is 255 characters.")); assertThat(stageConfig.getJobs().get(0).errors().on(JobConfig.NAME), is("You have defined multiple jobs called 'con-job'. Job names are case-insensitive and must be unique.")); assertThat(stageConfig.getJobs().get(1).errors().on(JobConfig.NAME), is("You have defined multiple jobs called 'con-job'. Job names are case-insensitive and must be unique.")); assertThat(newlyAddedStage.errors().on(StageConfig.NAME), is("Invalid stage name '.'. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters.")); assertThat(newJob.errors().on(JobConfig.NAME), is("Invalid job name 'foo!'. This must be alphanumeric and may contain underscores and periods. The maximum allowed length is 255 characters.")); }
@Test public void shouldBuildTheValidationContextForAnOnCancelTask() { CruiseConfig config = GoConfigMother.configWithPipelines("pipeline-1"); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-1")); StageConfig stageConfig = pipelineConfig.get(0); JobConfig jobConfig = stageConfig.getJobs().get(0); ExecTask execTask = new ExecTask("ls", "-la", "dir"); Task mockTask = mock(Task.class); when(mockTask.errors()).thenReturn(new ConfigErrors()); execTask.setCancelTask(mockTask); jobConfig.addTask(execTask); config.validateAfterPreprocess(); verify(mockTask).validate(ConfigSaveValidationContext.forChain( config, config.getGroups(), config.getGroups().findGroup("defaultGroup"), pipelineConfig, stageConfig, stageConfig.getJobs(), jobConfig, jobConfig.getTasks(), execTask, execTask.onCancelConfig())); }
@Test public void shouldCollectOriginErrorsFromEnvironments_InMergedConfig() { pipelines = new BasicPipelineConfigs("group_main", new Authorization(), PipelineConfigMother.pipelineConfig("pipe1")); BasicCruiseConfig mainCruiseConfig = new BasicCruiseConfig(pipelines); PartialConfig partialConfig = PartialConfigMother.withPipelineInGroup("pipe2", "g2"); partialConfig.getGroups().get(0).get(0).setOrigin(new RepoConfigOrigin()); cruiseConfig = new BasicCruiseConfig(mainCruiseConfig, partialConfig); BasicEnvironmentConfig uat = new BasicEnvironmentConfig(new CaseInsensitiveString("UAT")); uat.addPipeline(new CaseInsensitiveString("pipe2")); cruiseConfig.addEnvironment(uat); List<ConfigErrors> allErrors = cruiseConfig.validateAfterPreprocess(); assertThat(allErrors.size(), is(1)); assertNotNull(allErrors.get(0).on("origin")); }