public PipelineConfig(CaseInsensitiveString name, String labelTemplate, String cronSpec, boolean timerShouldTriggerOnlyOnMaterialChanges, MaterialConfigs materialConfigs, List<StageConfig> stageConfigs) { super(stageConfigs); this.name = name; this.labelTemplate = labelTemplate; this.setMaterialConfigs(materialConfigs); if (cronSpec != null) { this.timer = new TimerConfig(cronSpec, timerShouldTriggerOnlyOnMaterialChanges); } }
private BuildWork getBuildWorkWithP4MaterialRevision(P4Material p4Material) { pipelineConfig.setMaterialConfigs(new Materials(p4Material).convertToConfigs()); JobPlan plan = new DefaultJobPlan(new Resources(), new ArrayList<>(), new ArrayList<>(), -1, new JobIdentifier(PIPELINE_NAME, 1, "1", STAGE_NAME, "1", JOB_NAME, 123L), null, new EnvironmentVariables(), new EnvironmentVariables(), null); MaterialRevisions materialRevisions = new MaterialRevisions(new MaterialRevision(p4Material, new Modification("user", "comment", "a@b.com", new Date(), "10"))); BuildCause buildCause = BuildCause.createWithModifications(materialRevisions, TRIGGERED_BY_USER); List<Builder> builders = new ArrayList<>(); builders.add(new CommandBuilder("ant", "", dir, new RunIfConfigs(), new NullBuilder(), "")); BuildAssignment assignment = BuildAssignment.create(plan, buildCause, builders, dir, environmentVariableContext, new ArtifactStores()); return new BuildWork(assignment, systemEnvironment.consoleLogCharset()); }
@Test public void shouldCheckSCMMaterialsHaveDestinationCorrectly() { HgMaterialConfig materialConfigOne = new HgMaterialConfig("http://url1", null); materialConfigOne.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "folder")); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs((new MaterialConfigs(materialConfigOne))); assertThat(pipelineOne.materialConfigs().scmMaterialsHaveDestination(), is(true)); PluggableSCMMaterialConfig materialConfigTwo = new PluggableSCMMaterialConfig(null, SCMMother.create("scm-id"), null, null); pipelineOne.materialConfigs().add(materialConfigTwo); assertThat(pipelineOne.materialConfigs().scmMaterialsHaveDestination(), is(false)); }
@Test public void shouldNotRunMultipleMaterialsValidationIfPipelineContainsOnlyOneMaterial() { CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); SvnMaterialConfig svnMaterialConfig = MaterialConfigsMother.svnMaterialConfig(); svnMaterialConfig.setFolder(null); pipelineOne.setMaterialConfigs(new MaterialConfigs(svnMaterialConfig)); pipelineOne.materialConfigs().validate(ConfigSaveValidationContext.forChain(config)); assertThat(svnMaterialConfig.errors().toString(), svnMaterialConfig.errors().getAll().size(), is(0)); }
@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 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 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 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 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 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 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'.")); }
@Test public void shouldMergeEnvironmentVariablesFromInitialContext() throws IOException { pipelineConfig.setMaterialConfigs(new MaterialConfigs()); BuildAssignment buildAssignment = createAssignment(new EnvironmentVariableContext("foo", "bar")); BuildWork work = new BuildWork(buildAssignment, systemEnvironment.consoleLogCharset()); EnvironmentVariableContext environmentContext = new EnvironmentVariableContext(); AgentIdentifier agentIdentifier = new AgentIdentifier("somename", "127.0.0.1", AGENT_UUID); work.doWork(environmentContext, new AgentWorkContext(agentIdentifier, new FakeBuildRepositoryRemote(), new GoArtifactsManipulatorStub(), new AgentRuntimeInfo(agentIdentifier, AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie", false), packageRepositoryExtension, scmExtension, taskExtension, null, null)); assertEnvironmentContext(environmentContext, "foo", is("bar")); }
@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() { uppestStream.getStage("uppest-stage1").jobConfigByConfigName("uppest-job1").artifactConfigs() .add(new PluggableArtifactConfig("s3", "cd.go.s3")); 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.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'.")); }
@Test public void shouldUseSvnMaterialNameIfPresent() throws IOException { svnMaterial.setName(new CaseInsensitiveString("Cruise")); pipelineConfig.setMaterialConfigs(new MaterialConfigs(svnMaterial.config())); BuildAssignment buildAssigment = createAssignment(null); BuildWork work = new BuildWork(buildAssigment, systemEnvironment.consoleLogCharset()); EnvironmentVariableContext environmentVariableContext = new EnvironmentVariableContext(); new SystemEnvironment().setProperty("serviceUrl", "some_random_place"); AgentIdentifier agentIdentifier = new AgentIdentifier("somename", "127.0.0.1", AGENT_UUID); work.doWork(environmentVariableContext, new AgentWorkContext(agentIdentifier, new FakeBuildRepositoryRemote(), new GoArtifactsManipulatorStub(), new AgentRuntimeInfo(agentIdentifier, AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie", false), packageRepositoryExtension, scmExtension, taskExtension, null, null)); assertThat(environmentVariableContext.getProperty("GO_REVISION_CRUISE"), is("3")); }
private EnvironmentVariableContext doWorkWithMaterials(Materials materials) throws IOException { pipelineConfig.setMaterialConfigs(materials.convertToConfigs()); BuildAssignment buildAssigment = createAssignment(null); BuildWork work = new BuildWork(buildAssigment, systemEnvironment.consoleLogCharset()); EnvironmentVariableContext environmentVariableContext = new EnvironmentVariableContext(); AgentIdentifier agentIdentifier = new AgentIdentifier("somename", "127.0.0.1", AGENT_UUID); work.doWork(environmentVariableContext, new AgentWorkContext(agentIdentifier, new FakeBuildRepositoryRemote(), new GoArtifactsManipulatorStub(), new AgentRuntimeInfo(agentIdentifier, AgentRuntimeStatus.Idle, currentWorkingDirectory(), "cookie", false), packageRepositoryExtension, scmExtension, taskExtension, null, null)); return environmentVariableContext; } }
@Test public void should_BeValidWhen_hasAnAlternatePathToAncestor() { 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("uppest_stream/upstream"), new CaseInsensitiveString("uppest-stage1"), new CaseInsensitiveString("uppest-job1"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")))); assertThat(task.errors().isEmpty(), is(true)); task = new FetchTask(new CaseInsensitiveString("uppest_stream/upstreams_peer"), new CaseInsensitiveString("uppest-stage1"), new CaseInsensitiveString("uppest-job1"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")))); assertThat(task.errors().isEmpty(), is(true)); }
@Test public void shouldAllowModifyingTheAutoUpdateFieldOfMaterials() throws Exception { GitMaterialConfig gitMaterial = new GitMaterialConfig("https://url", "master"); gitMaterial.setAutoUpdate(true); GitMaterialConfig modifiedGitMaterial = new GitMaterialConfig("https://url", "master"); modifiedGitMaterial.setAutoUpdate(false); MaterialConfigs configs = new MaterialConfigs(); configs.add(gitMaterial); CruiseConfig config = GoConfigMother.configWithPipelines("one"); PipelineConfig pipelineOne = config.pipelineConfigByName(new CaseInsensitiveString("one")); pipelineOne.setMaterialConfigs(new MaterialConfigs(modifiedGitMaterial)); configs.validate(ConfigSaveValidationContext.forChain(config)); assertTrue(gitMaterial.errors().isEmpty()); }
@Test public void should_NOT_BeValidWhen_stageMayNotHaveRunViaTheGivenPath_evenThoughItMayHaveActuallyRunAccordingToAnAlternatePath() {//TODO: Please fix this if someone cares about this corner case working -jj 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("uppest_stream/upstreams_peer"), new CaseInsensitiveString("uppest-stage1"), new CaseInsensitiveString("uppest-job1"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")), downstream.getStage(new CaseInsensitiveString("stage")).getJobs().first())); assertThat(task.errors().isEmpty(), is(true)); task = new FetchTask(new CaseInsensitiveString("uppest_stream/upstreams_peer"), new CaseInsensitiveString("uppest-stage2"), new CaseInsensitiveString("uppest-job2"), "src", "dest"); task.validate(ConfigSaveValidationContext.forChain(config, new BasicPipelineConfigs(), downstream, downstream.getStage(new CaseInsensitiveString("stage")), downstream.getStage(new CaseInsensitiveString("stage")).getJobs().first())); assertThat(task.errors().isEmpty(), is(false)); assertThat(task.errors().on(FetchTask.STAGE), is("\"downstream :: stage :: job\" tries to fetch artifact from stage \"uppest_stream :: uppest-stage2\" which does not complete before \"downstream\" pipeline's dependencies.")); }