@Test public void shouldNotUpdateEnvironmentIfEditingOverAStaleCopy() throws Exception { configHelper.addEnvironments("prod"); String staleMd5 = goConfigDao.md5OfConfigFile(); service.updateEnvironment( "prod", environmentConfig("uat1"), new Username(new CaseInsensitiveString("foo")), staleMd5); assertThat("md5 should be stale", goConfigDao.md5OfConfigFile(), is(not(staleMd5))); HttpLocalizedOperationResult result = service.updateEnvironment( "prod", environmentConfig("uat2"), new Username(new CaseInsensitiveString("foo")), staleMd5); assertThat(result.isSuccessful(), is(false)); assertThat( result.message(localizer), is( "Failed to update environment 'prod'. " + ConfigFileHasChangedException.CONFIG_CHANGED_PLEASE_REFRESH)); }
public CruiseConfig loadForEdit() { try { goConfigDao.forceReload(); return new Cloner().deepClone(goConfigDao.loadForEditing()); } catch (Exception e) { throw new RuntimeException(e); } }
@Test public void shouldGetConfigAsXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); controller.getCurrentConfigXml(null, response); ByteArrayOutputStream os = new ByteArrayOutputStream(); new MagicalGoConfigXmlWriter(new ConfigCache(), registry, metricsProbeService) .write(goConfigDao.loadForEditing(), os, true); assertValidContentAndStatus(SC_OK, "text/xml", os.toString()); assertThat( response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(goConfigDao.md5OfConfigFile())); }
@Test public void shouldReturnConflictIfGetRequestUsesIncorrectConfigMD5() throws Exception { String oldMd5 = goConfigDao.md5OfConfigFile(); configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String newMd5 = goConfigDao.md5OfConfigFile(); controller.getBuildAsXmlPartial("pipeline", "stage", 1, oldMd5, response); assertValidContentAndStatus( SC_CONFLICT, RESPONSE_CHARSET, ConfigFileHasChangedException.CONFIG_CHANGED_PLEASE_REFRESH); assertThat(response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(newMd5)); }
@Test public void shouldReturnXmlAndErrorMessageWhenPostOfPipelineAsInvalidPartialXml() throws Exception { groupName = BasicPipelineConfigs.DEFAULT_GROUP; configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String badXml = "<pipeline name=\"cruise\" labeltemplate=\"invalid\">\n" + " <materials>\n" + " <svn url=\"file:///tmp/foo\" checkexternals=\"true\" />\n" + " </materials>\n" + " <stage name=\"dev\">\n" + " <jobs>\n" + " <job name=\"linux\" />\n" + " <job name=\"windows\" />\n" + " </jobs>\n" + " </stage>\n" + "</pipeline>"; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postPipelineAsXmlPartial(0, groupName, badXml, md5, response); assertThat(response.getStatus(), is(SC_CONFLICT)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map<String, String> json = (Map) mav.getModel().get("json"); assertThat(json.get("result").toString(), containsString("Label is invalid")); assertThat(json.get("originalContent"), is(badXml)); }
public ConfigSaveState updateServerConfig( final MailHost mailHost, final LdapConfig ldapConfig, final PasswordFileConfig passwordFileConfig, final boolean shouldAllowAutoLogin, final String md5, final String artifactsDir, final Double purgeStart, final Double purgeUpto, final String jobTimeout, final String siteUrl, final String secureSiteUrl, final String taskRepositoryLocation) { final List<ConfigSaveState> result = new ArrayList<>(); result.add( updateConfig( new GoConfigDao.NoOverwriteCompositeConfigCommand( md5, goConfigDao.mailHostUpdater(mailHost), securityUpdater(ldapConfig, passwordFileConfig, shouldAllowAutoLogin), serverConfigUpdater( artifactsDir, purgeStart, purgeUpto, jobTimeout, siteUrl, secureSiteUrl, taskRepositoryLocation)))); // should not reach here with empty result return result.get(0); }
@Test public void shouldConflictWhenGivenMd5IsDifferent() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); controller.getCurrentConfigXml("crapy_md5", response); ByteArrayOutputStream os = new ByteArrayOutputStream(); new MagicalGoConfigXmlWriter( new ConfigCache(), ConfigElementImplementationRegistryMother.withNoPlugins(), metricsProbeService) .write(goConfigDao.loadForEditing(), os, true); assertValidContentAndStatus( SC_CONFLICT, "text/plain; charset=utf-8", CONFIG_CHANGED_PLEASE_REFRESH); assertThat( response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(goConfigDao.md5OfConfigFile())); }
public void writeXmlToConfigFile(String xml) { try { FileUtils.writeStringToFile(configFile, xml); goConfigDao.forceReload(); } catch (Exception e) { throw bomb("Error writing config file: " + configFile.getAbsolutePath(), e); } }
public void onSetUp() throws IOException { initializeConfigFile(); goConfigDao.forceReload(); writeConfigFile(load()); originalConfigDir = sysEnv.getConfigDir(); File configDir = configFile.getParentFile(); sysEnv.setProperty(SystemEnvironment.CONFIG_DIR_PROPERTY, configDir.getAbsolutePath()); }
@Test public void shouldPostGroupWithChangedNameAsPartialXml() throws Exception { configHelper.addPipelineWithGroup("group", "pipeline", "dev", "linux", "windows"); String newXml = RENAMED_GROUP; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postGroupAsXmlPartial("group", newXml, md5, response); assertThat(response.getStatus(), is(SC_OK)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); assertResponseMessage(mav, "Group changed successfully."); }
@Test public void shouldGetBuildAsPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String md5 = goConfigDao.md5OfConfigFile(); controller.getBuildAsXmlPartial("pipeline", "stage", 1, null, response); assertValidContentAndStatus(SC_OK, "text/xml", "<job name=\"build2\" />"); assertThat(response.getHeader(XmlAction.X_CRUISE_CONFIG_MD5), is(md5)); }
@Test public void shouldPostStageAsPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String newXml = NEW_STAGE; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 0, newXml, md5, response); assertThat(response.getStatus(), is(SC_OK)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map json = (Map) mav.getModel().get("json"); new JsonTester(json).shouldContain("{ 'result' : 'Stage changed successfully.' }"); }
@Test public void shouldReturnXmlAndErrorMessageWhenInvalidPostOfStageAsPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 4, NEW_STAGE, md5, response); assertThat(response.getStatus(), is(SC_NOT_FOUND)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map<String, Object> json = (Map) mav.getModel().get("json"); Map<String, Object> jsonMap = new LinkedHashMap<>(); jsonMap.put("result", "Stage does not exist."); jsonMap.put("originalContent", NEW_STAGE); assertThat(json, is(jsonMap)); }
private String setUpPipelineGroupsWithAdminPermissions() throws IOException { setCurrentUser("ram"); assertThat(CaseInsensitiveString.str(UserHelper.getUserName().getUsername()), is("ram")); configHelper.addPipelineWithGroup("studios", "go", "stage", "build1", "build2"); configHelper.setAdminPermissionForGroup("studios", "barrow"); configHelper.addPipelineWithGroup("consulting", "bcg", "stage", "build1", "build2"); configHelper.setAdminPermissionForGroup("consulting", "ram"); configHelper.addTemplate("newTemplate", "stage"); return goConfigDao.md5OfConfigFile(); }
@Test public void shouldReturnXmlAndErrorMessageWhenInvalidPostOfBuildAsPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String newXml = "<job name=\"build3\" />"; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postBuildAsXmlPartial("pipeline", "stage", 4, newXml, md5, response); assertThat(response.getStatus(), is(SC_NOT_FOUND)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map json = (Map) mav.getModel().get("json"); new JsonTester(json) .shouldContain( "{ 'result' : 'Build does not exist.'," + " 'originalContent' : '" + newXml + "' }"); }
@Test public void shouldModifyExistingPipelineTemplateWhenPostedAsPartial() throws Exception { configHelper.addPipelineWithGroup( "some-group", "some-pipeline", "some-dev", "some-linux", "some-windows"); configHelper.addAgent("some-home", "UUID"); String newXml = NEW_TEMPLATES; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postGroupAsXmlPartial("Pipeline Templates", newXml, md5, response); assertResponseMessage(mav, "Template changed successfully."); assertThat(response.getStatus(), is(SC_OK)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); assertThat(configHelper.currentConfig().getTemplates().size(), is(1)); }
@Test public void shouldReturnXmlAndErrorMessageWhenPostOfStageAsInvalidPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String badXml = "<;askldjfa;dsklfja;sdjas;lkdf"; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postStageAsXmlPartial("pipeline", 0, badXml, md5, response); assertThat(response.getStatus(), is(SC_CONFLICT)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map json = (Map) mav.getModel().get("json"); new JsonTester(json) .shouldContain( "{ 'result' : 'Error on line 1 of document : The markup in the document preceding the root element must be well-formed. Nested exception: The markup in the document preceding the root element must be well-formed.'," + " 'originalContent' : '" + badXml + "' }"); }
@Test public void shouldReturnBadRequestForUpdateWhenUsingInvalidEnvName() { configHelper.addEnvironments("foo-env"); HttpLocalizedOperationResult result = service.updateEnvironment( "foo-env", env( "foo env", new ArrayList<String>(), new ArrayList<Map<String, String>>(), new ArrayList<String>()), new Username(new CaseInsensitiveString("any")), goConfigDao.md5OfConfigFile()); assertThat(result.httpCode(), is(HttpServletResponse.SC_BAD_REQUEST)); assertThat( result.message(localizer), containsString("Failed to update environment 'foo-env'.")); }
@Test public void shouldReturnXmlAndErrorMessageWhenPostOfBuildWithDuplicatedNameAsPartialXml() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String newXml = "<job name=\"build2\" />"; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postBuildAsXmlPartial("pipeline", "stage", 0, newXml, md5, response); assertThat(response.getStatus(), is(SC_CONFLICT)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map<String, Object> json = (Map) mav.getModel().get("json"); Map<String, Object> expected = new LinkedHashMap<>(); expected.put( "result", "Duplicate unique value [build2] declared for identity constraint \"uniqueJob\" of element \"jobs\"."); expected.put("originalContent", newXml); assertThat(json, is(expected)); }
@Test public void shouldReturnTheCorrectLocalizedMessageForUpdateWhenDuplicateEnvironmentExists() { configHelper.addEnvironments("foo-env"); configHelper.addEnvironments("bar-env"); HttpLocalizedOperationResult result = service.updateEnvironment( "bar-env", env( "foo-env", new ArrayList<String>(), new ArrayList<Map<String, String>>(), new ArrayList<String>()), new Username(new CaseInsensitiveString("any")), goConfigDao.md5OfConfigFile()); assertThat( result.message(localizer), is( "Failed to update environment 'bar-env'. Duplicate unique value [foo-env] declared for identity constraint \"uniqueEnvironmentName\" of element \"environments\".")); }
@Test public void shouldUpdateExistingEnvironment() throws Exception { BasicEnvironmentConfig uat = environmentConfig("uat"); goConfigService.addPipeline( PipelineConfigMother.createPipelineConfig("foo", "dev", "job"), "foo-grp"); goConfigService.addPipeline( PipelineConfigMother.createPipelineConfig("bar", "dev", "job"), "foo-grp"); Username user = Username.ANONYMOUS; agentConfigService.addAgent(new AgentConfig("uuid-1", "host-1", "192.168.1.2"), user); agentConfigService.addAgent(new AgentConfig("uuid-2", "host-2", "192.168.1.3"), user); uat.addPipeline(new CaseInsensitiveString("foo")); uat.addAgent("uuid-2"); uat.addEnvironmentVariable("env-one", "ONE"); uat.addEnvironmentVariable("env-two", "TWO"); goConfigService.addEnvironment(new BasicEnvironmentConfig(new CaseInsensitiveString("dev"))); goConfigService.addEnvironment(new BasicEnvironmentConfig(new CaseInsensitiveString("qa"))); goConfigService.addEnvironment(uat); goConfigService.addEnvironment( new BasicEnvironmentConfig(new CaseInsensitiveString("acceptance"))); goConfigService.addEnvironment( new BasicEnvironmentConfig(new CaseInsensitiveString("function_testing"))); EnvironmentConfig newUat = new BasicEnvironmentConfig(new CaseInsensitiveString("prod")); newUat.addPipeline(new CaseInsensitiveString("bar")); newUat.addAgent("uuid-1"); newUat.addEnvironmentVariable("env-three", "THREE"); HttpLocalizedOperationResult result = service.updateEnvironment( "uat", newUat, new Username(new CaseInsensitiveString("foo")), goConfigDao.md5OfConfigFile()); EnvironmentConfig updatedEnv = service.named("prod"); assertThat(updatedEnv.name(), is(new CaseInsensitiveString("prod"))); assertThat(updatedEnv.getAgents().getUuids(), is(Arrays.asList("uuid-1"))); assertThat(updatedEnv.getPipelineNames(), is(Arrays.asList(new CaseInsensitiveString("bar")))); EnvironmentVariablesConfig updatedVariables = new EnvironmentVariablesConfig(); updatedVariables.add("env-three", "THREE"); assertThat(updatedEnv.getVariables(), is(updatedVariables)); EnvironmentsConfig currentEnvironments = goConfigService.getCurrentConfig().getEnvironments(); assertThat(currentEnvironments.indexOf(updatedEnv), is(2)); assertThat(currentEnvironments.size(), is(5)); }
@Test public void shouldReturnErrorMessageIfConfigFileChangesBeforePostBuildAsPartialXml() throws Exception { String md5 = goConfigDao.md5OfConfigFile(); configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String newXml = "<job name=\"build3\" />"; ModelAndView mav = controller.postBuildAsXmlPartial("pipeline", "stage", 0, newXml, md5, response); assertThat(response.getStatus(), is(SC_CONFLICT)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map json = (Map) mav.getModel().get("json"); new JsonTester(json) .shouldContain( "{ 'result' : '" + ConfigFileHasChangedException.CONFIG_CHANGED_PLEASE_REFRESH + "'," + " 'originalContent' : '" + newXml + "' }"); }
@Test public void shouldReturnErrorMessageWhenPostOfJobContainsDotForExecWorkingDir() throws Exception { configHelper.addPipeline("pipeline", "stage", "build1", "build2"); String badXml = "<job name=\"build3\" >" + "<tasks>" + "<exec command=\"ant\" workingdir=\".\"/>" + "</tasks>" + "</job>"; String md5 = goConfigDao.md5OfConfigFile(); ModelAndView mav = controller.postBuildAsXmlPartial("pipeline", "stage", 0, badXml, md5, response); assertThat(response.getStatus(), is(SC_CONFLICT)); assertThat(response.getContentType(), is(RESPONSE_CHARSET_JSON)); Map json = (Map) mav.getModel().get("json"); JsonValue jsonValue = JsonUtils.from(json); assertThat(unescapeJavaScript(jsonValue.getString("originalContent")), is(badXml)); assertThat( unescapeJavaScript(jsonValue.getString("result")), containsString("File path is invalid")); }
@Test public void shouldReturnTheCorrectLocalizedMessageWhenUserDoesNotHavePermissionToUpdate() throws IOException { configHelper.addEnvironments("foo"); configHelper.turnOnSecurity(); configHelper.addAdmins("super_hero"); HttpLocalizedOperationResult result = service.updateEnvironment( "foo", env( "foo-env", new ArrayList<String>(), new ArrayList<Map<String, String>>(), new ArrayList<String>()), new Username(new CaseInsensitiveString("evil_hacker")), goConfigDao.md5OfConfigFile()); assertThat( result.message(localizer), is( "Failed to update environment 'foo'. User 'evil_hacker' does not have permission to update environments")); }
@Test public void shouldGetPipelineAsPartialXml() throws Exception { // get the pipeline XML configHelper.addPipeline("pipeline", "dev", "linux", "windows"); groupName = BasicPipelineConfigs.DEFAULT_GROUP; controller.getPipelineAsXmlPartial(0, groupName, null, response); String xml = response.getContentAsString(); assertThat(xml, containsString("pass")); // save the pipeline XML MockHttpServletResponse postResponse = new MockHttpServletResponse(); String modifiedXml = xml.replace("pass", "secret"); controller.postPipelineAsXmlPartial( 0, groupName, modifiedXml, goConfigDao.md5OfConfigFile(), postResponse); // get the pipeline XML again MockHttpServletResponse getResponse = new MockHttpServletResponse(); controller.getPipelineAsXmlPartial(0, groupName, null, getResponse); assertThat(getResponse.getContentAsString(), containsString("secret")); assertThat(getResponse.getContentAsString(), is(modifiedXml)); }
@Test public void shouldGetTemplateAsPartialXmlOnlyIfUserHasAdminRights() throws Exception { // get the pipeline XML configHelper.addPipeline("pipeline", "dev", "linux", "windows"); configHelper.addTemplate("new-template", "dev"); controller.getPipelineAsXmlPartial( 0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, response); String xml = response.getContentAsString(); assertThat(xml, containsString("new-template")); // save the pipeline XML MockHttpServletResponse postResponse = new MockHttpServletResponse(); String modifiedXml = xml.replace("new-template", "new-name-for-template"); controller.postPipelineAsXmlPartial( 0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, modifiedXml, goConfigDao.md5OfConfigFile(), postResponse); // get the pipeline XML again MockHttpServletResponse getResponse = new MockHttpServletResponse(); controller.getPipelineAsXmlPartial( 0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, getResponse); assertThat(getResponse.getContentAsString(), containsString("new-name-for-template")); assertThat(getResponse.getContentAsString(), is(modifiedXml)); setCurrentUser("user"); MockHttpServletResponse nonAdminResponse = new MockHttpServletResponse(); controller.getPipelineAsXmlPartial( 0, TemplatesConfig.PIPELINE_TEMPLATES_FAKE_GROUP_NAME, null, nonAdminResponse); assertThat(nonAdminResponse.getStatus(), is(SC_UNAUTHORIZED)); assertThat( nonAdminResponse.getContentAsString(), is("User 'user' does not have permission to administer pipeline templates")); }
public String configFileMd5() { return goConfigDao.md5OfConfigFile(); }
public GoConfigValidity checkConfigFileValid() { return goConfigDao.checkConfigFileValid(); }
public void register(ConfigChangedListener listener) { goConfigDao.registerListener(listener); }
public void addPipeline(PipelineConfig pipeline, String groupName) { goConfigDao.addPipeline(pipeline, groupName); }