@Test public void shouldNotContinueWithConfigSaveIfObjectNotFound() { when(goConfigService.isUserAdmin(currentUser)).thenReturn(true); when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(false); SCM updatedScm = new SCM( "non-existent-id", new PluginConfiguration("plugin-id", "1"), new Configuration( new ConfigurationProperty( new ConfigurationKey("key1"), new ConfigurationValue("value1")))); UpdateSCMConfigCommand command = new UpdateSCMConfigCommand( updatedScm, pluggableScmService, goConfigService, currentUser, result, "md5", entityHashingService); thrown.expect(NullPointerException.class); thrown.expectMessage("The pluggable scm material with id 'non-existent-id' is not found."); assertThat(command.canContinue(cruiseConfig), is(false)); }
@Test public void shouldNotContinueWithConfigSaveIfUserIsUnauthorized() { when(goConfigService.isUserAdmin(currentUser)).thenReturn(false); when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(false); SCM updatedScm = new SCM( "id", new PluginConfiguration("plugin-id", "1"), new Configuration( new ConfigurationProperty( new ConfigurationKey("key1"), new ConfigurationValue("value1")))); UpdateSCMConfigCommand command = new UpdateSCMConfigCommand( updatedScm, pluggableScmService, goConfigService, currentUser, result, "md5", entityHashingService); assertThat(command.canContinue(cruiseConfig), is(false)); assertThat(result.toString(), containsString("UNAUTHORIZED_TO_EDIT")); }
@Test public void shouldNotContinueWithConfigSaveIfRequestIsNotFresh() { when(goConfigService.isUserAdmin(currentUser)).thenReturn(true); when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(false); SCM updatedScm = new SCM( "id", new PluginConfiguration("plugin-id", "1"), new Configuration( new ConfigurationProperty( new ConfigurationKey("key1"), new ConfigurationValue("value1")))); updatedScm.setName("material"); when(entityHashingService.md5ForEntity(cruiseConfig.getSCMs().find("id"), "material")) .thenReturn("another-md5"); UpdateSCMConfigCommand command = new UpdateSCMConfigCommand( updatedScm, pluggableScmService, goConfigService, currentUser, result, "md5", entityHashingService); assertThat(command.canContinue(cruiseConfig), is(false)); assertThat(result.toString(), containsString("STALE_RESOURCE_CONFIG")); assertThat(result.toString(), containsString(updatedScm.getName())); }
@Test public void shouldReturnTheCorrectLocalizedMessageForDuplicatePipelinesInAnEnvironment() { BasicEnvironmentConfig environmentConfig = environmentConfig("uat"); goConfigService.addPipeline( PipelineConfigMother.createPipelineConfig("foo", "dev", "job"), "foo-grp"); environmentConfig.addPipeline(new CaseInsensitiveString("foo")); goConfigService.addEnvironment(environmentConfig); ArrayList<String> pipelines = new ArrayList<>(); pipelines.add("foo"); HttpLocalizedOperationResult result = new HttpLocalizedOperationResult(); service.createEnvironment( env("foo-env", pipelines, new ArrayList<Map<String, String>>(), new ArrayList<String>()), new Username(new CaseInsensitiveString("any")), result); result = new HttpLocalizedOperationResult(); service.createEnvironment( env("env", pipelines, new ArrayList<Map<String, String>>(), new ArrayList<String>()), new Username(new CaseInsensitiveString("any")), result); assertThat( result.message(localizer), is( "Failed to add environment. Associating pipeline(s) which is already part of uat environment")); }
@Test public void shouldNotAutoRegisterAgentIfKeysDoNotMatch() throws Exception { String uuid = "uuid"; when(goConfigService.hasAgent(uuid)).thenReturn(false); ServerConfig serverConfig = new ServerConfig("artifacts", new SecurityConfig(), 10, 20, "1", ""); when(goConfigService.serverConfig()).thenReturn(serverConfig); when(agentService.agentUsername(uuid, request.getRemoteAddr(), "host")) .thenReturn(new Username("some-agent-login-name")); controller.agentRequest( "host", uuid, "location", "233232", "osx", "", "", "", "", "", "", false, request); verify(agentService) .requestRegistration( new Username("some-agent-login-name"), AgentRuntimeInfo.fromServer( new AgentConfig(uuid, "host", request.getRemoteAddr()), false, "location", 233232L, "osx", false)); verify(goConfigService, never()).updateConfig(any(UpdateConfigCommand.class)); }
private boolean isAuthorized() { if (!(goConfigService.isUserAdmin(username) || goConfigService.isGroupAdministrator(username.getUsername()))) { result.unauthorized( LocalizedMessage.string("UNAUTHORIZED_TO_EDIT"), HealthStateType.unauthorised()); return false; } return true; }
public List<CaseInsensitiveString> viewablePipelinesFor(Username username) { List<CaseInsensitiveString> pipelines = new ArrayList<CaseInsensitiveString>(); for (String group : goConfigService.allGroups()) { if (hasViewPermissionForGroup(CaseInsensitiveString.str(username.getUsername()), group)) { pipelines.addAll(goConfigService.pipelines(group)); } } return pipelines; }
@Override public boolean canContinue(CruiseConfig cruiseConfig) { if (goConfigService.groups().hasGroup(groupName) && !goConfigService.isUserAdminOfGroup(currentUser.getUsername(), groupName)) { result.unauthorized( LocalizedMessage.string("UNAUTHORIZED_TO_EDIT_GROUP", groupName), HealthStateType.unauthorised()); return false; } return true; }
@Test public void shouldContinueWithConfigSaveIfUserIsGroupAdmin() { when(goConfigService.isUserAdmin(currentUser)).thenReturn(false); when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(true); CreatePackageRepositoryCommand command = new CreatePackageRepositoryCommand( goConfigService, packageRepositoryService, packageRepository, currentUser, result); assertThat(command.canContinue(cruiseConfig), is(true)); }
public List<String> modifiableGroupsForUser(Username userName) { if (isUserAdmin(userName)) { return goConfigService.allGroups(); } List<String> modifiableGroups = new ArrayList<String>(); for (String group : goConfigService.allGroups()) { if (isUserAdminOfGroup(userName.getUsername(), group)) { modifiableGroups.add(group); } } return modifiableGroups; }
@Test public void shouldGetGroupWithTemplatesAsXml() throws Exception { configHelper.addTemplate("template-1", "dev"); configHelper.addPipelineWithGroup("group", "pipeline", "dev", "linux"); PipelineConfig pipelineWithTemplate = configHelper.addPipelineWithTemplate("group", "pipeline-with-template", "template-1"); assertThat( pipelineWithTemplate.size(), is(0)); // should not expect mutation of pipeline config passed in assertThat( configHelper .currentConfig() .pipelineConfigByName(new CaseInsensitiveString("pipeline-with-template")) .size(), is(1)); CruiseConfig config = goConfigService.currentCruiseConfig(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-with-template")); assertThat("Should not modify the original template", pipelineConfig.size(), is(1)); controller.getGroupAsXmlPartial("group", null, response); String content = "<pipelines group=\"group\">\n" + " <pipeline name=\"pipeline\">\n" + " <materials>\n" + " <svn url=\"svn:///user:pass@tmp/foo\" />\n" + " </materials>\n" + " <stage name=\"dev\">\n" + " <jobs>\n" + " <job name=\"linux\" />\n" + " </jobs>\n" + " </stage>\n" + " </pipeline>\n" + " <pipeline name=\"pipeline-with-template\" template=\"template-1\">\n" + " <materials>\n" + " <svn url=\"svn:///user:pass@tmp/foo\" />\n" + " </materials>\n" + " </pipeline>\n" + "</pipelines>"; assertValidContentAndStatus(SC_OK, "text/xml", content); MockHttpServletResponse postResponse = new MockHttpServletResponse(); controller.postGroupAsXmlPartial("group", content, null, postResponse); config = goConfigService.currentCruiseConfig(); pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString("pipeline-with-template")); assertThat("Should not modify the original template", pipelineConfig.size(), is(1)); }
@Test public void shouldCancelBuildBelongingToNonExistentPipelineWhenCreatingWork() throws Exception { fixture.createPipelineWithFirstStageScheduled(); Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName); ScheduledPipelineLoader scheduledPipelineLoader = mock(ScheduledPipelineLoader.class); when(scheduledPipelineLoader.pipelineWithPasswordAwareBuildCauseByBuildId( pipeline.getFirstStage().getJobInstances().first().getId())) .thenThrow(new PipelineNotFoundException("thrown by mockPipelineService")); GoConfigService mockGoConfigService = mock(GoConfigService.class); CruiseConfig config = configHelper.currentConfig(); configHelper.removePipeline(fixture.pipelineName, config); when(mockGoConfigService.getCurrentConfig()).thenReturn(config); buildAssignmentService = new BuildAssignmentService( mockGoConfigService, jobInstanceService, scheduleService, agentService, environmentConfigService, timeProvider, transactionTemplate, scheduledPipelineLoader, pipelineService, builderFactory, agentRemoteHandler); buildAssignmentService.onTimer(); AgentConfig agentConfig = AgentMother.localAgent(); agentConfig.addResource(new Resource("some-other-resource")); try { buildAssignmentService.assignWorkToAgent(agent(agentConfig)); fail("should have thrown PipelineNotFoundException"); } catch (PipelineNotFoundException e) { // ok } pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName); JobInstance job = pipeline.getFirstStage().getJobInstances().first(); assertThat(job.getState(), is(JobState.Completed)); assertThat(job.getResult(), is(JobResult.Cancelled)); Stage stage = stageDao.findStageWithIdentifier(job.getIdentifier().getStageIdentifier()); assertThat(stage.getState(), is(StageState.Cancelled)); assertThat(stage.getResult(), is(StageResult.Cancelled)); }
@Test public void shouldNotThrowErrorWhenMaterialsChange() throws Exception { configHelper.addPipeline("cruise", "dev", repository); goConfigService.forceNotifyListeners(); scheduleHelper.autoSchedulePipelinesWithRealMaterials("mingle", "evolve", "cruise"); configHelper.replaceMaterialForPipeline( "cruise", svnMaterialConfig("http://new-material", null)); goConfigService.forceNotifyListeners(); try { scheduleService.autoSchedulePipelinesFromRequestBuffer(); } catch (Exception e) { fail("#2520 - should not cause an error if materials have changed"); } }
@Test public void shouldAutoRegisterAgentWithHostnameFromAutoRegisterProperties() throws Exception { String uuid = "uuid"; when(goConfigService.hasAgent(uuid)).thenReturn(false); ServerConfig serverConfig = new ServerConfig("artifacts", new SecurityConfig(), 10, 20, "1", "someKey"); when(goConfigService.serverConfig()).thenReturn(serverConfig); when(agentService.agentUsername(uuid, request.getRemoteAddr(), "autoregister-hostname")) .thenReturn(new Username("some-agent-login-name")); when(agentConfigService.updateAgent( any(UpdateConfigCommand.class), eq(uuid), any(HttpOperationResult.class), eq(new Username("some-agent-login-name")))) .thenReturn(new AgentConfig(uuid, "autoregister-hostname", request.getRemoteAddr())); controller.agentRequest( "host", uuid, "location", "233232", "osx", "someKey", "", "", "autoregister-hostname", "", "", false, request); verify(agentService) .requestRegistration( new Username("some-agent-login-name"), AgentRuntimeInfo.fromServer( new AgentConfig(uuid, "autoregister-hostname", request.getRemoteAddr()), false, "location", 233232L, "osx", false)); verify(agentConfigService) .updateAgent( any(UpdateConfigCommand.class), eq(uuid), any(HttpOperationResult.class), eq(new Username("some-agent-login-name"))); }
@Test public void shouldDeleteAnEnvironment() throws Exception { String environmentName = "dev"; HttpLocalizedOperationResult result = new HttpLocalizedOperationResult(); goConfigService.addEnvironment( new BasicEnvironmentConfig(new CaseInsensitiveString(environmentName))); assertTrue(goConfigService.hasEnvironmentNamed(new CaseInsensitiveString(environmentName))); service.deleteEnvironment( service.getEnvironmentConfig(environmentName), new Username(new CaseInsensitiveString("foo")), result); assertFalse(goConfigService.hasEnvironmentNamed(new CaseInsensitiveString(environmentName))); assertThat( result.message(localizer), containsString("Environment 'dev' was deleted successfully.")); }
@Before public void setup() throws Exception { configHelper = new GoConfigFileHelper(); configHelper.usingCruiseConfigDao(goConfigDao).initializeConfigFile(); configHelper.onSetUp(); goConfigService.forceNotifyListeners(); }
@Test public void shouldReturnTheRevisionsThatMatchTheGivenSearchString() { when(securityService.hasViewPermissionForPipeline("pavan", "pipeline")).thenReturn(true); LocalizedOperationResult operationResult = mock(LocalizedOperationResult.class); MaterialConfig materialConfig = mock(MaterialConfig.class); when(goConfigService.materialForPipelineWithFingerprint("pipeline", "sha")) .thenReturn(materialConfig); List<MatchedRevision> expected = Arrays.asList( new MatchedRevision( "23", "revision", "revision", "user", new DateTime(2009, 10, 10, 12, 0, 0, 0).toDate(), "comment")); when(materialRepository.findRevisionsMatching(materialConfig, "23")).thenReturn(expected); assertThat( materialService.searchRevisions( "pipeline", "sha", "23", new Username(new CaseInsensitiveString("pavan")), operationResult), is(expected)); }
@Test public void shouldCancelBuildsForDeletedJobsWhenPipelineConfigChanges() throws Exception { fixture = new PipelineWithTwoStages(materialRepository, transactionTemplate).usingTwoJobs(); fixture.usingConfigHelper(configHelper).usingDbHelper(dbHelper).onSetUp(); fixture.createPipelineWithFirstStageScheduled(); buildAssignmentService.onTimer(); configHelper.removeJob(fixture.pipelineName, fixture.devStage, fixture.JOB_FOR_DEV_STAGE); buildAssignmentService.onPipelineConfigChange( goConfigService .getCurrentConfig() .getPipelineConfigByName(new CaseInsensitiveString(fixture.pipelineName)), "g1"); Pipeline pipeline = pipelineDao.mostRecentPipeline(fixture.pipelineName); JobInstance deletedJob = pipeline.getFirstStage().getJobInstances().getByName(fixture.JOB_FOR_DEV_STAGE); assertThat(deletedJob.getState(), is(JobState.Completed)); assertThat(deletedJob.getResult(), is(JobResult.Cancelled)); JobInstance retainedJob = pipeline.getFirstStage().getJobInstances().getByName(fixture.DEV_STAGE_SECOND_JOB); assertThat(retainedJob.getState(), is(JobState.Scheduled)); assertThat(retainedJob.getResult(), is(JobResult.Unknown)); }
@Test public void shouldFailAndReturnReturnFailureResponse() throws Exception { service = spy(service); Username username = new Username(new CaseInsensitiveString("user")); final PackageRepository packageRepository = new PackageRepository(); packageRepository.errors().add("name", "Name is invalid"); final CruiseConfig cruiseConfig = GoConfigMother.configWithPipelines("sample"); cruiseConfig.errors().add("global", "error"); final UpdateConfigFromUI updateConfigFromUI = mock(UpdateConfigFromUI.class); final ConfigAwareUpdate configAwareUpdate = mock(ConfigAwareUpdate.class); doNothing().when(service).performPluginValidationsFor(packageRepository); doReturn(updateConfigFromUI) .when(service) .getPackageRepositoryUpdateCommand(packageRepository, username); when(configAwareUpdate.configAfter()).thenReturn(cruiseConfig); when(goConfigService.updateConfigFromUI( eq(updateConfigFromUI), eq("md5"), eq(username), any(LocalizedOperationResult.class))) .then( new Answer<ConfigUpdateResponse>() { @Override public ConfigUpdateResponse answer(InvocationOnMock invocationOnMock) throws Throwable { LocalizedOperationResult result = (LocalizedOperationResult) invocationOnMock.getArguments()[3]; result.badRequest(LocalizedMessage.string("BAD_REQUEST")); return new ConfigUpdateResponse( cruiseConfig, cruiseConfig, packageRepository, configAwareUpdate, ConfigSaveState.UPDATED); } }); when(localizer.localize("BAD_REQUEST", new Object[] {})).thenReturn("Save Failed"); ConfigUpdateAjaxResponse response = service.savePackageRepositoryToConfig(packageRepository, "md5", username); assertThat(response.isSuccessful(), is(false)); assertThat(response.getMessage(), is("Save Failed")); assertThat(response.getFieldErrors().size(), is(1)); assertThat( response.getFieldErrors().get("package_repository[name]"), is(asList("Name is invalid"))); assertThat(response.getGlobalErrors().size(), is(1)); assertThat(response.getGlobalErrors().contains("error"), is(true)); assertThat(response.getStatusCode(), is(HttpStatus.SC_BAD_REQUEST)); verify(service).performPluginValidationsFor(packageRepository); verify(service).getPackageRepositoryUpdateCommand(packageRepository, username); }
@Test public void shouldRemoveBuildCauseIfAnyExceptionIsThrown() throws Exception { configHelper.addPipeline("cruise", "dev", repository); goConfigService.forceNotifyListeners(); goConfigService .getCurrentConfig() .pipelineConfigByName(new CaseInsensitiveString("cruise")) .get(0) .jobConfigByConfigName(new CaseInsensitiveString("unit")) .setRunOnAllAgents(true); scheduleHelper.autoSchedulePipelinesWithRealMaterials("cruise"); goConfigService.forceNotifyListeners(); scheduleService.autoSchedulePipelinesFromRequestBuffer(); assertThat(pipelineScheduleQueue.toBeScheduled().size(), is(0)); }
public boolean hasViewPermissionForPipeline(Username username, String pipelineName) { String groupName = goConfigService.findGroupNameByPipeline(new CaseInsensitiveString(pipelineName)); if (groupName == null) { return true; } return hasViewPermissionForGroup(CaseInsensitiveString.str(username.getUsername()), groupName); }
@After public void teardown() throws Exception { dbHelper.onTearDown(); FileUtil.deleteFolder(goConfigService.artifactsDir()); pipelineScheduleQueue.clear(); agentAssignment.clear(); CONFIG_HELPER.onTearDown(); }
public boolean hasOperatePermissionForStage( String pipelineName, String stageName, String username) { if (!goConfigService.isSecurityEnabled()) { return true; } if (!goConfigService.hasStageConfigNamed(pipelineName, stageName)) { return false; } StageConfig stage = goConfigService.stageConfigNamed(pipelineName, stageName); CaseInsensitiveString userName = new CaseInsensitiveString(username); // TODO - #2517 - stage not exist if (stage.hasOperatePermissionDefined()) { CruiseConfig cruiseConfig = goConfigService.getCurrentConfig(); String groupName = goConfigService.findGroupNameByPipeline(new CaseInsensitiveString(pipelineName)); PipelineConfigs group = goConfigService.getCurrentConfig().findGroup(groupName); if (isUserAdmin(new Username(userName)) || isUserAdminOfGroup(userName, group)) { return true; } return goConfigService.readAclBy(pipelineName, stageName).isGranted(userName); } return hasOperatePermissionForPipeline(new CaseInsensitiveString(username), pipelineName); }
@Test public void shouldRemoveBuildCauseIfPipelineNotExist() throws Exception { configHelper.addPipeline("cruise", "dev", repository); goConfigService.forceNotifyListeners(); scheduleHelper.autoSchedulePipelinesWithRealMaterials("mingle", "evolve", "cruise"); Assertions.assertWillHappen( 2, PipelineScheduleQueueMatcher.numberOfScheduledPipelinesIsAtLeast(pipelineScheduleQueue), Timeout.FIVE_SECONDS); int originalSize = pipelineScheduleQueue.toBeScheduled().size(); assertThat(originalSize, greaterThan(1)); configHelper.initializeConfigFile(); goConfigService.forceNotifyListeners(); scheduleService.autoSchedulePipelinesFromRequestBuffer(); assertThat(pipelineScheduleQueue.toBeScheduled().size(), is(0)); }
@After public void teardown() throws Exception { TestRepo.internalTearDown(); dbHelper.onTearDown(); FileUtil.deleteFolder(goConfigService.artifactsDir()); FileUtil.deleteFolder(workingFolder); TestRepo.internalTearDown(); pipelineScheduleQueue.clear(); }
public boolean hasOperatePermissionForPipeline( final CaseInsensitiveString username, String pipelineName) { String groupName = goConfigService.findGroupNameByPipeline(new CaseInsensitiveString(pipelineName)); if (groupName == null) { return true; } return hasOperatePermissionForGroup(username, groupName); }
@Test public void shouldNotDeadlockWhenAllPossibleWaysOfUpdatingTheConfigAreBeingUsedAtTheSameTime() throws Exception { final ArrayList<Thread> configSaveThreads = new ArrayList<>(); final int pipelineCreatedThroughApiCount = 100; final int pipelineCreatedThroughUICount = 100; for (int i = 0; i < pipelineCreatedThroughUICount; i++) { Thread thread = configSaveThread(i); configSaveThreads.add(thread); } for (int i = 0; i < pipelineCreatedThroughApiCount; i++) { Thread thread = pipelineSaveThread(i); configSaveThreads.add(thread); } for (Thread configSaveThread : configSaveThreads) { Thread timerThread = null; try { timerThread = createThread( new Runnable() { @Override public void run() { try { File configFile = new File(goConfigDao.fileLocation()); String currentConfig = FileUtil.readContentFromFile(configFile); String updatedConfig = currentConfig.replaceFirst( "artifactsdir=\".*\"", "artifactsdir=\"" + UUID.randomUUID().toString() + "\""); FileUtil.writeContentToFile(updatedConfig, configFile); } catch (IOException e) { fail("Failed with error: " + e.getMessage()); } cachedFileGoConfig.forceReload(); } }, "timer-thread"); } catch (InterruptedException e) { fail(e.getMessage()); } try { configSaveThread.start(); timerThread.start(); configSaveThread.join(); timerThread.join(); } catch (InterruptedException e) { fail(e.getMessage()); } } assertThat( goConfigService.getAllPipelineConfigs().size(), is(pipelineCreatedThroughApiCount + pipelineCreatedThroughUICount)); }
public List<PipelineConfigs> viewableGroupsFor(Username username) { ArrayList<PipelineConfigs> list = new ArrayList<PipelineConfigs>(); for (PipelineConfigs pipelineConfigs : goConfigService.getCurrentConfig().getGroups()) { if (hasViewPermissionForGroup( CaseInsensitiveString.str(username.getUsername()), pipelineConfigs.getGroup())) { list.add(pipelineConfigs); } } return list; }
@Test public void shouldNotContinueWhenTemplateNoLongerExists() { when(goConfigService.isAuthorizedToEditTemplate("template", currentUser)).thenReturn(true); DeleteTemplateConfigCommand command = new DeleteTemplateConfigCommand( pipelineTemplateConfig, result, goConfigService, currentUser); assertThat(command.canContinue(cruiseConfig), is(false)); }
@Test public void shouldContinueWithConfigSaveIfUserIsGroupAdmin() { when(goConfigService.isUserAdmin(currentUser)).thenReturn(false); when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(true); when(entityHashingService.md5ForEntity(any(PackageRepository.class))).thenReturn("md5"); UpdatePackageRepositoryCommand command = new UpdatePackageRepositoryCommand( goConfigService, packageRepositoryService, newPackageRepo, currentUser, "md5", entityHashingService, result, repoId); assertThat(command.canContinue(cruiseConfig), is(true)); }