@Test public void shouldUpdateScmConfigurationOfPluggableScmMaterialsOnPipeline() { String jobName = "job-one"; PipelineConfig pipelineConfig = setupPipelineWithScmMaterial("pipeline_with_pluggable_scm_mat", "stage", jobName); final Pipeline previousSuccessfulBuildWithOlderScmConfig = simulateSuccessfulPipelineRun(pipelineConfig); PipelineConfig updatedPipelineConfig = configHelper.updatePipeline( pipelineConfig.name(), new GoConfigFileHelper.Updater<PipelineConfig>() { @Override public void update(PipelineConfig config) { PluggableSCMMaterialConfig materialConfig = (PluggableSCMMaterialConfig) config.materialConfigs().first(); materialConfig .getSCMConfig() .getConfiguration() .getProperty("password") .setConfigurationValue(new ConfigurationValue("new_value")); } }); final long jobId = rerunJob(jobName, pipelineConfig, previousSuccessfulBuildWithOlderScmConfig); Pipeline loadedPipeline = (Pipeline) transactionTemplate.execute( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { return loader.pipelineWithPasswordAwareBuildCauseByBuildId(jobId); } }); MaterialRevisions revisions = loadedPipeline.getBuildCause().getMaterialRevisions(); Configuration updatedConfiguration = ((PluggableSCMMaterial) revisions .findRevisionFor(updatedPipelineConfig.materialConfigs().first()) .getMaterial()) .getScmConfig() .getConfiguration(); assertThat(updatedConfiguration.size(), is(2)); assertThat( updatedConfiguration.getProperty("password").getConfigurationValue(), is(new ConfigurationValue("new_value"))); }
@Test public void shouldReadFolderAndFilterForPluggableSCMMaterialConfig() throws Exception { String xml = "<cruise schemaVersion='" + GoConstants.CONFIG_SCHEMA_VERSION + "'>\n" + "<scms>\n" + " <scm id='scm-id' name='scm-name'>\n" + " <pluginConfiguration id='plugin-id' version='1.0'/>\n" + " <configuration>\n" + " <property>\n" + " <key>url</key>\n" + " <value>http://go</value>\n" + " </property>\n" + " </configuration>\n" + " </scm>\n" + " </scms>" + "<pipelines group=\"group_name\">\n" + " <pipeline name=\"new_name\">\n" + " <materials>\n" + " <scm ref='scm-id' dest='dest'>\n" + " <filter>\n" + " <ignore pattern=\"x\"/>\n" + " <ignore pattern=\"y\"/>\n" + " </filter>\n" + " </scm>\n" + " </materials>\n" + " <stage name=\"stage_name\">\n" + " <jobs>\n" + " <job name=\"job_name\" />\n" + " </jobs>\n" + " </stage>\n" + " </pipeline>\n" + "</pipelines></cruise>"; GoConfigHolder goConfigHolder = xmlLoader.loadConfigHolder(xml); PipelineConfig pipelineConfig = goConfigHolder.config.pipelineConfigByName(new CaseInsensitiveString("new_name")); PluggableSCMMaterialConfig pluggableSCMMaterialConfig = (PluggableSCMMaterialConfig) pipelineConfig.materialConfigs().get(0); assertThat( pluggableSCMMaterialConfig.getSCMConfig(), is(goConfigHolder.config.getSCMs().get(0))); assertThat(pluggableSCMMaterialConfig.getFolder(), is("dest")); assertThat( pluggableSCMMaterialConfig.filter(), is(new Filter(new IgnoredFiles("x"), new IgnoredFiles("y")))); }
@Test public void shouldLoadPipelineAlongwithBuildCauseHavingMaterialPasswordsPopulated() { PipelineConfig pipelineConfig = PipelineConfigMother.pipelineConfig( "last", new StageConfig( new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig("job-one")))); pipelineConfig.materialConfigs().clear(); SvnMaterial onDirOne = MaterialsMother.svnMaterial("google.com", "dirOne", "loser", "boozer", false, "**/*.html"); P4Material onDirTwo = MaterialsMother.p4Material( "host:987654321", "zoozer", "secret", "through-the-window", true); onDirTwo.setFolder("dirTwo"); pipelineConfig.addMaterialConfig(onDirOne.config()); pipelineConfig.addMaterialConfig(onDirTwo.config()); configHelper.addPipeline(pipelineConfig); Pipeline building = PipelineMother.building(pipelineConfig); Pipeline pipeline = dbHelper.savePipelineWithMaterials(building); final long jobId = pipeline.getStages().get(0).getJobInstances().get(0).getId(); Pipeline loadedPipeline = (Pipeline) transactionTemplate.execute( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { return loader.pipelineWithPasswordAwareBuildCauseByBuildId(jobId); } }); MaterialRevisions revisions = loadedPipeline.getBuildCause().getMaterialRevisions(); assertThat( ((SvnMaterial) revisions.findRevisionFor(onDirOne).getMaterial()).getPassword(), is("boozer")); assertThat( ((P4Material) revisions.findRevisionFor(onDirTwo).getMaterial()).getPassword(), is("secret")); }
@Test // if other materials have expansion concept at some point, add more tests here public void shouldSetPasswordForExpandedSvnMaterial() { PipelineConfig pipelineConfig = PipelineConfigMother.pipelineConfig( "last", new StageConfig( new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig("job-one")))); pipelineConfig.materialConfigs().clear(); SvnMaterialConfig materialConfig = svnRepo.materialConfig(); materialConfig.setConfigAttributes( Collections.singletonMap(SvnMaterialConfig.CHECK_EXTERNALS, String.valueOf(true))); materialConfig.setPassword("boozer"); pipelineConfig.addMaterialConfig(materialConfig); configHelper.addPipeline(pipelineConfig); Pipeline loadedPipeline = createAndLoadModifyOneFilePipeline(pipelineConfig); MaterialRevisions revisions = loadedPipeline.getBuildCause().getMaterialRevisions(); assertThat(revisions.getRevisions().size(), is(2)); assertThat( ((SvnMaterial) revisions.getRevisions().get(0).getMaterial()).getPassword(), is("boozer")); assertThat( ((SvnMaterial) revisions.getRevisions().get(1).getMaterial()).getPassword(), is("boozer")); }
private long rerunJob( String jobName, PipelineConfig pipelineConfig, Pipeline previousSuccessfulBuildWithOlderPackageConfig) { Stage stage = instanceFactory.createStageForRerunOfJobs( previousSuccessfulBuildWithOlderPackageConfig.getFirstStage(), asList(jobName), new DefaultSchedulingContext(), pipelineConfig.getFirstStageConfig(), new TimeProvider(), configHelper.getGoConfigDao().md5OfConfigFile()); stage = stageService.save(previousSuccessfulBuildWithOlderPackageConfig, stage); return stage.getFirstJob().getId(); }
private Pipeline createAndLoadModifyOneFilePipeline(PipelineConfig pipelineConfig) { MaterialConfigs expandedConfigs = materialExpansionService.expandMaterialConfigsForScheduling( pipelineConfig.materialConfigs()); MaterialRevisions materialRevisions = ModificationsMother.modifyOneFile( MaterialsMother.createMaterialsFromMaterialConfigs(expandedConfigs)); Pipeline building = PipelineMother.buildingWithRevisions(pipelineConfig, materialRevisions); Pipeline pipeline = dbHelper.savePipelineWithMaterials(building); final long jobId = pipeline.getStages().get(0).getJobInstances().get(0).getId(); return (Pipeline) transactionTemplate.execute( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { return loader.pipelineWithPasswordAwareBuildCauseByBuildId(jobId); } }); }
public PipelineConfig toPipelineConfig(CRPipeline crPipeline) { MaterialConfigs materialConfigs = new MaterialConfigs(); for (CRMaterial crMaterial : crPipeline.getMaterials()) { materialConfigs.add(toMaterialConfig(crMaterial)); } PipelineConfig pipelineConfig = new PipelineConfig(new CaseInsensitiveString(crPipeline.getName()), materialConfigs); for (CRStage crStage : crPipeline.getStages()) { pipelineConfig.add(toStage(crStage)); } if (crPipeline.getLabelTemplate() != null) pipelineConfig.setLabelTemplate(crPipeline.getLabelTemplate()); CRTrackingTool crTrackingTool = crPipeline.getTrackingTool(); if (crTrackingTool != null) { pipelineConfig.setTrackingTool(toTrackingTool(crTrackingTool)); } CRMingle crMingle = crPipeline.getMingle(); if (crMingle != null) { pipelineConfig.setMingleConfig(toMingleConfig(crMingle)); } CRTimer crTimer = crPipeline.getTimer(); if (crTimer != null) { pipelineConfig.setTimer(toTimerConfig(crTimer)); } EnvironmentVariablesConfig variables = pipelineConfig.getVariables(); for (CREnvironmentVariable crEnvironmentVariable : crPipeline.getEnvironmentVariables()) { variables.add(toEnvironmentVariableConfig(crEnvironmentVariable)); } pipelineConfig.setLock(crPipeline.isLocked()); return pipelineConfig; }
@Test public void shouldLoadShallowCloneFlagForGitMaterialsBaseOnTheirOwnPipelineConfig() throws IOException { GitTestRepo testRepo = new GitTestRepo(); PipelineConfig shallowPipeline = PipelineConfigMother.pipelineConfig( "shallowPipeline", new StageConfig( new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig("job-one")))); shallowPipeline.materialConfigs().clear(); shallowPipeline.addMaterialConfig( new GitMaterialConfig(testRepo.projectRepositoryUrl(), null, true)); configHelper.addPipeline(shallowPipeline); PipelineConfig fullPipeline = PipelineConfigMother.pipelineConfig( "fullPipeline", new StageConfig( new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig("job-one")))); fullPipeline.materialConfigs().clear(); fullPipeline.addMaterialConfig( new GitMaterialConfig(testRepo.projectRepositoryUrl(), null, false)); configHelper.addPipeline(fullPipeline); Pipeline shallowPipelineInstance = createAndLoadModifyOneFilePipeline(shallowPipeline); MaterialRevisions shallowRevisions = shallowPipelineInstance.getBuildCause().getMaterialRevisions(); assertThat( ((GitMaterial) shallowRevisions.getRevisions().get(0).getMaterial()).isShallowClone(), is(true)); Pipeline fullPipelineInstance = createAndLoadModifyOneFilePipeline(fullPipeline); MaterialRevisions fullRevisions = fullPipelineInstance.getBuildCause().getMaterialRevisions(); assertThat( ((GitMaterial) fullRevisions.getRevisions().get(0).getMaterial()).isShallowClone(), is(false)); }
@Test public void shouldSetAServerHealthMessageWhenMaterialForPipelineWithBuildCauseIsNotFound() throws IllegalArtifactLocationException, IOException { PipelineConfig pipelineConfig = PipelineConfigMother.pipelineConfig( "last", new StageConfig( new CaseInsensitiveString("stage"), new JobConfigs(new JobConfig("job-one")))); pipelineConfig.materialConfigs().clear(); SvnMaterialConfig onDirOne = MaterialConfigsMother.svnMaterialConfig( "google.com", "dirOne", "loser", "boozer", false, "**/*.html"); final P4MaterialConfig onDirTwo = MaterialConfigsMother.p4MaterialConfig( "host:987654321", "zoozer", "secret", "through-the-window", true); onDirTwo.setConfigAttributes(Collections.singletonMap(ScmMaterialConfig.FOLDER, "dirTwo")); pipelineConfig.addMaterialConfig(onDirOne); pipelineConfig.addMaterialConfig(onDirTwo); configHelper.addPipeline(pipelineConfig); Pipeline building = PipelineMother.building(pipelineConfig); final Pipeline pipeline = dbHelper.savePipelineWithMaterials(building); CruiseConfig cruiseConfig = configHelper.currentConfig(); PipelineConfig cfg = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString("last")); cfg.removeMaterialConfig(cfg.materialConfigs().get(1)); configHelper.writeConfigFile(cruiseConfig); assertThat( serverHealthService.filterByScope(HealthStateScope.forPipeline("last")).size(), is(0)); final long jobId = pipeline.getStages().get(0).getJobInstances().get(0).getId(); Date currentTime = new Date(System.currentTimeMillis() - 1); Pipeline loadedPipeline = (Pipeline) transactionTemplate.execute( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { Pipeline loadedPipeline = null; try { loadedPipeline = loader.pipelineWithPasswordAwareBuildCauseByBuildId(jobId); fail( "should not have loaded pipeline with build-cause as one of the necessary materials was not found"); } catch (Exception e) { assertThat(e, is(instanceOf(StaleMaterialsOnBuildCause.class))); assertThat( e.getMessage(), is( "Cannot load job 'last/" + pipeline.getCounter() + "/stage/1/job-one' because material " + onDirTwo + " was not found in config.")); } return loadedPipeline; } }); assertThat(loadedPipeline, is(nullValue())); JobInstance reloadedJobInstance = jobInstanceService.buildById(jobId); assertThat(reloadedJobInstance.getState(), is(JobState.Completed)); assertThat(reloadedJobInstance.getResult(), is(JobResult.Failed)); assertThat( serverHealthService .filterByScope(HealthStateScope.forJob("last", "stage", "job-one")) .size(), is(1)); ServerHealthState error = serverHealthService .filterByScope(HealthStateScope.forJob("last", "stage", "job-one")) .get(0); assertThat( error, is( ServerHealthState.error( "Cannot load job 'last/" + pipeline.getCounter() + "/stage/1/job-one' because material " + onDirTwo + " was not found in config.", "Job for pipeline 'last/" + pipeline.getCounter() + "/stage/1/job-one' has been failed as one or more material configurations were either changed or removed.", HealthStateType.general(HealthStateScope.forJob("last", "stage", "job-one"))))); DateTime expiryTime = (DateTime) ReflectionUtil.getField(error, "expiryTime"); assertThat(expiryTime.toDate().after(currentTime), is(true)); assertThat( expiryTime.toDate().before(new Date(System.currentTimeMillis() + 5 * 60 * 1000 + 1)), is(true)); String logText = FileUtil.readToEnd(consoleService.findConsoleArtifact(reloadedJobInstance.getIdentifier())); assertThat( logText, containsString( "Cannot load job 'last/" + pipeline.getCounter() + "/stage/1/job-one' because material " + onDirTwo + " was not found in config.")); assertThat( logText, containsString( "Job for pipeline 'last/" + pipeline.getCounter() + "/stage/1/job-one' has been failed as one or more material configurations were either changed or removed.")); }
@Test public void shouldBeAbleToResolveSecureConfigPropertiesForSCMs() throws Exception { String encryptedValue = new GoCipher().encrypt("secure-two"); String xml = "<cruise schemaVersion='" + GoConstants.CONFIG_SCHEMA_VERSION + "'>\n" + "<scms>\n" + " <scm id='scm-id' name='name'>\n" + " <pluginConfiguration id='plugin-id' version='1.0'/>\n" + " <configuration>\n" + " <property>\n" + " <key>plain</key>\n" + " <value>value</value>\n" + " </property>\n" + " <property>\n" + " <key>secure-one</key>\n" + " <value>secure-value</value>\n" + " </property>\n" + " <property>\n" + " <key>secure-two</key>\n" + " <encryptedValue>" + encryptedValue + "</encryptedValue>\n" + " </property>\n" + " </configuration>\n" + " </scm>\n" + " </scms>" + "<pipelines group=\"group_name\">\n" + " <pipeline name=\"new_name\">\n" + " <materials>\n" + " <scm ref='scm-id' />\n" + " </materials>\n" + " <stage name=\"stage_name\">\n" + " <jobs>\n" + " <job name=\"job_name\" />\n" + " </jobs>\n" + " </stage>\n" + " </pipeline>\n" + "</pipelines></cruise>"; // meta data of scm SCMPropertyConfiguration scmConfiguration = new SCMPropertyConfiguration(); scmConfiguration.add(new SCMProperty("plain")); scmConfiguration.add(new SCMProperty("secure-one").with(SCMConfiguration.SECURE, true)); scmConfiguration.add(new SCMProperty("secure-two").with(SCMConfiguration.SECURE, true)); SCMMetadataStore.getInstance() .addMetadataFor("plugin-id", new SCMConfigurations(scmConfiguration), null); GoConfigHolder goConfigHolder = xmlLoader.loadConfigHolder(xml); SCM scmConfig = goConfigHolder.config.getSCMs().first(); PipelineConfig pipelineConfig = goConfigHolder.config.pipelineConfigByName(new CaseInsensitiveString("new_name")); PluggableSCMMaterialConfig pluggableSCMMaterialConfig = (PluggableSCMMaterialConfig) pipelineConfig.materialConfigs().get(0); assertThat(pluggableSCMMaterialConfig.getSCMConfig(), is(scmConfig)); Configuration configuration = pluggableSCMMaterialConfig.getSCMConfig().getConfiguration(); assertThat(configuration.get(0).getConfigurationValue().getValue(), is("value")); assertThat( configuration.get(1).getEncryptedValue().getValue(), is(new GoCipher().encrypt("secure-value"))); assertThat(configuration.get(2).getEncryptedValue().getValue(), is(encryptedValue)); }