diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2019-08-13 17:17:51 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-08-14 20:21:15 +0200 |
commit | 5334895ce0eacaa2a2787cd6c47ac507dbe0d723 (patch) | |
tree | d4789ca54c97f2b6d2bbfd6cad21bf1e8377929b /server/sonar-server/src/test | |
parent | 028b9c7723901c175ec488ab7a8cb67f76c77fe7 (diff) | |
download | sonarqube-5334895ce0eacaa2a2787cd6c47ac507dbe0d723.tar.gz sonarqube-5334895ce0eacaa2a2787cd6c47ac507dbe0d723.zip |
remove dependency from sonar-webserver-webapi to sonar-server
Diffstat (limited to 'server/sonar-server/src/test')
173 files changed, 1 insertions, 22070 deletions
diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/ProcessCommandWrapperImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/ProcessCommandWrapperImplTest.java deleted file mode 100644 index de5f24347fc..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/app/ProcessCommandWrapperImplTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.app; - -import java.io.File; -import java.io.IOException; -import java.util.Random; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.process.sharedmemoryfile.DefaultProcessCommands; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_INDEX; -import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH; - -public class ProcessCommandWrapperImplTest { - private static final int PROCESS_NUMBER = 2; - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private MapSettings settings = new MapSettings(); - - @Test - public void requestSQRestart_throws_IAE_if_process_index_property_not_set() { - ProcessCommandWrapperImpl processCommandWrapper = new ProcessCommandWrapperImpl(settings.asConfig()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Property process.index is not set"); - - processCommandWrapper.requestSQRestart(); - } - - @Test - public void requestSQRestart_throws_IAE_if_process_shared_path_property_not_set() { - settings.setProperty(PROPERTY_PROCESS_INDEX, 1); - ProcessCommandWrapperImpl processCommandWrapper = new ProcessCommandWrapperImpl(settings.asConfig()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Property process.sharedDir is not set"); - - processCommandWrapper.requestSQRestart(); - } - - @Test - public void requestSQRestart_updates_shareMemory_file() throws IOException { - File tmpDir = temp.newFolder().getAbsoluteFile(); - settings.setProperty(PROPERTY_SHARED_PATH, tmpDir.getAbsolutePath()); - settings.setProperty(PROPERTY_PROCESS_INDEX, PROCESS_NUMBER); - - ProcessCommandWrapperImpl underTest = new ProcessCommandWrapperImpl(settings.asConfig()); - underTest.requestSQRestart(); - - try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tmpDir, PROCESS_NUMBER)) { - assertThat(processCommands.askedForRestart()).isTrue(); - } - } - - @Test - public void requestSQStop_throws_IAE_if_process_shared_path_property_not_set() { - settings.setProperty(PROPERTY_PROCESS_INDEX, 1); - ProcessCommandWrapperImpl processCommandWrapper = new ProcessCommandWrapperImpl(settings.asConfig()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Property process.sharedDir is not set"); - - processCommandWrapper.requestHardStop(); - } - - @Test - public void requestSQStop_updates_shareMemory_file() throws IOException { - File tmpDir = temp.newFolder().getAbsoluteFile(); - settings.setProperty(PROPERTY_SHARED_PATH, tmpDir.getAbsolutePath()); - settings.setProperty(PROPERTY_PROCESS_INDEX, PROCESS_NUMBER); - - ProcessCommandWrapperImpl underTest = new ProcessCommandWrapperImpl(settings.asConfig()); - underTest.requestHardStop(); - - try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tmpDir, PROCESS_NUMBER)) { - assertThat(processCommands.askedForHardStop()).isTrue(); - } - } - - @Test - public void notifyOperational_throws_IAE_if_process_sharedDir_property_not_set() { - settings.setProperty(PROPERTY_PROCESS_INDEX, 1); - ProcessCommandWrapperImpl processCommandWrapper = new ProcessCommandWrapperImpl(settings.asConfig()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Property process.sharedDir is not set"); - - processCommandWrapper.notifyOperational(); - } - - @Test - public void notifyOperational_throws_IAE_if_process_index_property_not_set() { - ProcessCommandWrapperImpl processCommandWrapper = new ProcessCommandWrapperImpl(settings.asConfig()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Property process.index is not set"); - - processCommandWrapper.notifyOperational(); - } - - @Test - public void notifyOperational_updates_shareMemory_file() throws IOException { - File tmpDir = temp.newFolder().getAbsoluteFile(); - settings.setProperty(PROPERTY_SHARED_PATH, tmpDir.getAbsolutePath()); - settings.setProperty(PROPERTY_PROCESS_INDEX, PROCESS_NUMBER); - - ProcessCommandWrapperImpl underTest = new ProcessCommandWrapperImpl(settings.asConfig()); - underTest.notifyOperational(); - - try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tmpDir, PROCESS_NUMBER)) { - assertThat(processCommands.isOperational()).isTrue(); - } - } - - @Test - public void isCeOperational_reads_shared_memory_operational_flag_in_location_3() throws IOException { - File tmpDir = temp.newFolder().getAbsoluteFile(); - settings.setProperty(PROPERTY_SHARED_PATH, tmpDir.getAbsolutePath()); - - boolean expected = new Random().nextBoolean(); - if (expected) { - try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(tmpDir, 3)) { - processCommands.setOperational(); - } - } - - ProcessCommandWrapperImpl underTest = new ProcessCommandWrapperImpl(settings.asConfig()); - - assertThat(underTest.isCeOperational()).isEqualTo(expected); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureProxyImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureProxyImplTest.java deleted file mode 100644 index 6fb3d9a6449..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureProxyImplTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.branch; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class BranchFeatureProxyImplTest { - - private BranchFeatureExtension branchFeatureExtension = mock(BranchFeatureExtension.class); - - @Test - public void return_false_when_no_extension() { - assertThat(new BranchFeatureProxyImpl().isEnabled()).isFalse(); - } - - @Test - public void return_false_when_extension_returns_false() { - when(branchFeatureExtension.isEnabled()).thenReturn(false); - assertThat(new BranchFeatureProxyImpl(branchFeatureExtension).isEnabled()).isFalse(); - } - - @Test - public void return_true_when_extension_returns_ftrue() { - when(branchFeatureExtension.isEnabled()).thenReturn(true); - assertThat(new BranchFeatureProxyImpl(branchFeatureExtension).isEnabled()).isTrue(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureRule.java b/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureRule.java deleted file mode 100644 index 2bf56463474..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/branch/BranchFeatureRule.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.branch; - -import org.junit.rules.ExternalResource; - -public class BranchFeatureRule extends ExternalResource implements BranchFeatureProxy { - - private boolean enabled; - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - protected void after() { - reset(); - } - - public void reset() { - this.enabled = false; - } - - @Override - public boolean isEnabled() { - return enabled; - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/http/CeHttpClientTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/http/CeHttpClientTest.java deleted file mode 100644 index c53cf871bf4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/http/CeHttpClientTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ce.http; - -import java.io.File; -import java.io.IOException; -import java.util.Optional; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okio.Buffer; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.process.sharedmemoryfile.DefaultProcessCommands; -import org.sonar.process.ProcessEntryPoint; -import org.sonar.process.ProcessId; -import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.test.ExceptionCauseMatcher.hasType; - -public class CeHttpClientTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public MockWebServer server = new MockWebServer(); - - private File ipcSharedDir; - private CeHttpClient underTest; - - @Before - public void setUp() throws Exception { - ipcSharedDir = temp.newFolder(); - MapSettings settings = new MapSettings(); - settings.setProperty(ProcessEntryPoint.PROPERTY_SHARED_PATH, ipcSharedDir.getAbsolutePath()); - underTest = new CeHttpClientImpl(settings.asConfig()); - } - - @Test - public void retrieveSystemInfo_returns_absent_if_process_is_down() { - Optional<ProtobufSystemInfo.SystemInfo> info = underTest.retrieveSystemInfo(); - - assertThat(info.isPresent()).isFalse(); - } - - @Test - public void retrieveSystemInfo_get_information_if_process_is_up() { - Buffer response = new Buffer(); - response.read(ProtobufSystemInfo.Section.newBuilder().build().toByteArray()); - server.enqueue(new MockResponse().setBody(response)); - - // initialize registration of process - setUpWithHttpUrl(ProcessId.COMPUTE_ENGINE); - - Optional<ProtobufSystemInfo.SystemInfo> info = underTest.retrieveSystemInfo(); - assertThat(info.get().getSectionsCount()).isEqualTo(0); - } - - @Test - public void retrieveSystemInfo_throws_ISE_if_http_error() { - server.enqueue(new MockResponse().setResponseCode(500)); - - // initialize registration of process - setUpWithHttpUrl(ProcessId.COMPUTE_ENGINE); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Failed to call HTTP server of process " + ProcessId.COMPUTE_ENGINE); - expectedException.expectCause(hasType(IOException.class) - .andMessage(format("Server returned HTTP response code: 500 for URL: http://%s:%d/systemInfo", server.getHostName(), server.getPort()))); - underTest.retrieveSystemInfo(); - } - - @Test - public void changeLogLevel_throws_NPE_if_level_argument_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("level can't be null"); - - underTest.changeLogLevel(null); - } - - @Test - public void changeLogLevel_throws_ISE_if_http_error() { - String message = "blah"; - server.enqueue(new MockResponse().setResponseCode(500).setBody(message)); - - // initialize registration of process - setUpWithHttpUrl(ProcessId.COMPUTE_ENGINE); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Failed to call HTTP server of process " + ProcessId.COMPUTE_ENGINE); - expectedException.expectCause(hasType(IOException.class) - .andMessage(format("Failed to change log level in Compute Engine. Code was '500' and response was 'blah' for url " + - "'http://%s:%s/changeLogLevel'", server.getHostName(), server.getPort()))); - - underTest.changeLogLevel(LoggerLevel.DEBUG); - } - - @Test - public void changeLogLevel_does_not_fail_when_http_code_is_200() { - server.enqueue(new MockResponse().setResponseCode(200)); - - setUpWithHttpUrl(ProcessId.COMPUTE_ENGINE); - - underTest.changeLogLevel(LoggerLevel.TRACE); - } - - @Test - public void changelogLevel_does_not_fail_if_process_is_down() { - underTest.changeLogLevel(LoggerLevel.INFO); - } - - private void setUpWithHttpUrl(ProcessId processId) { - try (DefaultProcessCommands processCommands = DefaultProcessCommands.secondary(ipcSharedDir, processId.getIpcIndex())) { - processCommands.setUp(); - processCommands.setHttpUrl(format("http://%s:%d", server.getHostName(), server.getPort())); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchReportSubmitterTest.java deleted file mode 100644 index 9768b0cb0fe..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchReportSubmitterTest.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ce.queue; - -import com.google.common.collect.ImmutableMap; -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.function.BiConsumer; -import java.util.stream.IntStream; -import org.apache.commons.io.IOUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.stubbing.Answer; -import org.sonar.api.utils.System2; -import org.sonar.ce.queue.CeQueue; -import org.sonar.ce.queue.CeQueueImpl; -import org.sonar.ce.queue.CeTaskSubmit; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.ce.CeTaskTypes; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.component.ComponentUpdater; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.favorite.FavoriteUpdater; -import org.sonar.server.permission.PermissionTemplateService; -import org.sonar.server.tester.UserSessionRule; - -import static java.util.Collections.emptyMap; -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; -import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; -import static org.sonar.db.component.ComponentTesting.newBranchDto; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; -import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; -import static org.sonar.db.permission.OrganizationPermission.SCAN; - -/** - * Tests of {@link ReportSubmitter} when branch support is installed. - */ -@RunWith(DataProviderRunner.class) -public class BranchReportSubmitterTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private CeQueue queue = mock(CeQueueImpl.class); - private ComponentUpdater componentUpdater = mock(ComponentUpdater.class); - private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); - private FavoriteUpdater favoriteUpdater = mock(FavoriteUpdater.class); - private BranchSupportDelegate branchSupportDelegate = mock(BranchSupportDelegate.class); - private BranchSupport branchSupport = spy(new BranchSupport(branchSupportDelegate)); - - private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), branchSupport); - - @Test - public void submit_does_not_use_delegate_if_characteristics_are_empty() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertMainBranch(organization); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project); - mockSuccessfulPrepareSubmitCall(); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - - underTest.submit(organization.getKey(), project.getDbKey(), project.name(), emptyMap(), reportInput); - - verifyZeroInteractions(branchSupportDelegate); - } - - @Test - public void submit_a_report_on_existing_branch() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertMainBranch(organization); - ComponentDto branch = db.components().insertProjectBranch(project); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project); - Map<String, String> randomCharacteristics = randomNonEmptyMap(); - BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(branch); - when(branchSupportDelegate.createComponentKey(project.getDbKey(), randomCharacteristics)) - .thenReturn(componentKey); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - String taskUuid = mockSuccessfulPrepareSubmitCall(); - - underTest.submit(organization.getKey(), project.getDbKey(), project.name(), randomCharacteristics, reportInput); - - verifyZeroInteractions(permissionTemplateService); - verifyZeroInteractions(favoriteUpdater); - verify(branchSupport, times(0)).createBranchComponent(any(), any(), any(), any(), any()); - verify(branchSupportDelegate).createComponentKey(project.getDbKey(), randomCharacteristics); - verify(branchSupportDelegate, times(0)).createBranchComponent(any(), any(), any(), any(), any()); - verifyNoMoreInteractions(branchSupportDelegate); - verifyQueueSubmit(project, branch, user, randomCharacteristics, taskUuid); - } - - @Test - public void submit_a_report_on_missing_branch_but_existing_project() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto existingProject = db.components().insertMainBranch(organization); - BranchDto exitingProjectMainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), existingProject.uuid()).get(); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, existingProject); - Map<String, String> randomCharacteristics = randomNonEmptyMap(); - ComponentDto createdBranch = createButDoNotInsertBranch(existingProject); - BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(createdBranch); - when(branchSupportDelegate.createComponentKey(existingProject.getDbKey(), randomCharacteristics)) - .thenReturn(componentKey); - when(branchSupportDelegate.createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(existingProject), eq(exitingProjectMainBranch))) - .thenReturn(createdBranch); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - String taskUuid = mockSuccessfulPrepareSubmitCall(); - - underTest.submit(organization.getKey(), existingProject.getDbKey(), existingProject.name(), randomCharacteristics, reportInput); - - verifyZeroInteractions(permissionTemplateService); - verifyZeroInteractions(favoriteUpdater); - verify(branchSupport).createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(existingProject), eq(exitingProjectMainBranch)); - verify(branchSupportDelegate).createComponentKey(existingProject.getDbKey(), randomCharacteristics); - verify(branchSupportDelegate).createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(existingProject), eq(exitingProjectMainBranch)); - verifyNoMoreInteractions(branchSupportDelegate); - verify(componentUpdater, times(0)).commitAndIndex(any(), any()); - verifyQueueSubmit(existingProject, createdBranch, user, randomCharacteristics, taskUuid); - } - - @Test - public void submit_report_on_missing_branch_of_missing_project_provisions_project_when_org_PROVISION_PROJECT_perm() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto nonExistingProject = newPrivateProjectDto(organization); - UserDto user = db.users().insertUser(); - userSession.logIn(user) - .addPermission(PROVISION_PROJECTS, organization) - .addPermission(SCAN, organization); - - Map<String, String> randomCharacteristics = randomNonEmptyMap(); - ComponentDto createdBranch = createButDoNotInsertBranch(nonExistingProject); - BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(createdBranch); - when(branchSupportDelegate.createComponentKey(nonExistingProject.getDbKey(), randomCharacteristics)) - .thenReturn(componentKey); - when(componentUpdater.createWithoutCommit(any(), any(), eq(user.getId()))) - .thenAnswer((Answer<ComponentDto>) invocation -> db.components().insertMainBranch(nonExistingProject)); - when(branchSupportDelegate.createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(nonExistingProject), any())) - .thenReturn(createdBranch); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(nonExistingProject.getKey()))) - .thenReturn(true); - String taskUuid = mockSuccessfulPrepareSubmitCall(); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - - underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), nonExistingProject.name(), randomCharacteristics, reportInput); - - BranchDto exitingProjectMainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), nonExistingProject.uuid()).get(); - verify(branchSupport).createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(nonExistingProject), eq(exitingProjectMainBranch)); - verify(branchSupportDelegate).createComponentKey(nonExistingProject.getDbKey(), randomCharacteristics); - verify(branchSupportDelegate).createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(nonExistingProject), eq(exitingProjectMainBranch)); - verifyNoMoreInteractions(branchSupportDelegate); - verifyQueueSubmit(nonExistingProject, createdBranch, user, randomCharacteristics, taskUuid); - verify(componentUpdater).commitAndIndex(any(DbSession.class), eq(nonExistingProject)); - } - - @Test - public void submit_fails_if_branch_support_delegate_createComponentKey_throws_an_exception() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertMainBranch(organization); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project); - Map<String, String> randomCharacteristics = randomNonEmptyMap(); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - RuntimeException expected = new RuntimeException("Faking an exception thrown by branchSupportDelegate"); - when(branchSupportDelegate.createComponentKey(any(), any())).thenThrow(expected); - - try { - underTest.submit(organization.getKey(), project.getDbKey(), project.name(), randomCharacteristics, reportInput); - fail("exception should have been thrown"); - } catch (Exception e) { - assertThat(e).isSameAs(expected); - } - } - - @DataProvider - public static Object[][] permissionsAllowingProjectProvisioning() { - BiConsumer<ComponentDto, UserSessionRule> noProjectPerm = (cpt, userSession) -> { - }; - BiConsumer<OrganizationDto, UserSessionRule> noOrgPerm = (cpt, userSession) -> { - }; - BiConsumer<ComponentDto, UserSessionRule> provisionOnProject = (cpt, userSession) -> userSession.addProjectPermission(PROVISIONING, cpt); - BiConsumer<OrganizationDto, UserSessionRule> provisionOnOrganization = (cpt, userSession) -> userSession.addPermission(PROVISION_PROJECTS, cpt); - return new Object[][] { - {provisionOnProject, noOrgPerm}, - {noProjectPerm, provisionOnOrganization}, - {provisionOnProject, provisionOnOrganization} - }; - } - - @Test - public void submit_report_on_missing_branch_of_missing_project_fails_with_ForbiddenException_if_only_scan_permission() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto nonExistingProject = newPrivateProjectDto(organization); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, nonExistingProject); - Map<String, String> randomCharacteristics = randomNonEmptyMap(); - ComponentDto createdBranch = createButDoNotInsertBranch(nonExistingProject); - BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(createdBranch); - when(branchSupportDelegate.createComponentKey(nonExistingProject.getDbKey(), randomCharacteristics)) - .thenReturn(componentKey); - when(branchSupportDelegate.createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(nonExistingProject), any())) - .thenReturn(createdBranch); - InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), nonExistingProject.name(), randomCharacteristics, reportInput); - } - - private static ComponentDto createButDoNotInsertBranch(ComponentDto project) { - BranchType randomBranchType = BranchType.values()[new Random().nextInt(BranchType.values().length)]; - BranchDto branchDto = newBranchDto(project.projectUuid(), randomBranchType); - return ComponentTesting.newProjectBranch(project, branchDto); - } - - private String mockSuccessfulPrepareSubmitCall() { - String taskUuid = randomAlphabetic(12); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(taskUuid)); - return taskUuid; - } - - private void verifyQueueSubmit(ComponentDto project, ComponentDto branch, UserDto user, Map<String, String> characteristics, String taskUuid) { - verify(queue).submit(argThat(submit -> submit.getType().equals(CeTaskTypes.REPORT) - && submit.getComponent().filter(cpt -> cpt.getUuid().equals(branch.uuid()) && cpt.getMainComponentUuid().equals(project.uuid())).isPresent() - && submit.getSubmitterUuid().equals(user.getUuid()) - && submit.getCharacteristics().equals(characteristics) - && submit.getUuid().equals(taskUuid))); - } - - private static BranchSupport.ComponentKey createComponentKeyOfBranch(ComponentDto branch) { - BranchSupport.ComponentKey mainComponentKey = mockComponentKey(branch.getKey(), branch.getKey()); - when(mainComponentKey.getMainBranchComponentKey()).thenReturn(mainComponentKey); - - BranchSupport.ComponentKey componentKey = mockComponentKey(branch.getKey(), branch.getDbKey()); - when(componentKey.getBranch()).thenReturn(Optional.ofNullable(branch).map(b -> new BranchSupport.Branch(b.name(), BranchType.LONG))); - when(componentKey.getMainBranchComponentKey()).thenReturn(mainComponentKey); - - return componentKey; - } - - private static BranchSupport.ComponentKey mockComponentKey(String key, String dbKey) { - BranchSupport.ComponentKey componentKey = mock(BranchSupport.ComponentKey.class); - when(componentKey.getKey()).thenReturn(key); - when(componentKey.getDbKey()).thenReturn(dbKey); - return componentKey; - } - - private static ImmutableMap<String, String> randomNonEmptyMap() { - return IntStream.range(0, 1 + new Random().nextInt(5)) - .boxed() - .collect(uniqueIndex(i -> "key_" + i, i -> "val_" + i)); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchSupportTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchSupportTest.java deleted file mode 100644 index af798ce77aa..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchSupportTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ce.queue; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import java.util.Collections; -import java.util.Map; -import java.util.Random; -import java.util.stream.IntStream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.db.DbSession; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.ce.queue.BranchSupport.ComponentKey; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; - -@RunWith(DataProviderRunner.class) -public class BranchSupportTest { - private static final Map<String, String> NO_CHARACTERISTICS = Collections.emptyMap(); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private BranchSupportDelegate branchSupportDelegate = mock(BranchSupportDelegate.class); - private BranchSupport underTestNoBranch = new BranchSupport(); - private BranchSupport underTestWithBranch = new BranchSupport(branchSupportDelegate); - - @Test - public void createComponentKey_of_main_branch() { - String projectKey = randomAlphanumeric(12); - - ComponentKey componentKey = underTestNoBranch.createComponentKey(projectKey, NO_CHARACTERISTICS); - - assertThat(componentKey) - .isEqualTo(underTestWithBranch.createComponentKey(projectKey, NO_CHARACTERISTICS)); - assertThat(componentKey.getKey()).isEqualTo(projectKey); - assertThat(componentKey.getDbKey()).isEqualTo(projectKey); - assertThat(componentKey.getMainBranchComponentKey()).isSameAs(componentKey); - assertThat(componentKey.getBranch()).isEmpty(); - assertThat(componentKey.getPullRequestKey()).isEmpty(); - } - - @Test - public void createComponentKey_delegates_to_delegate_if_characteristics_is_not_empty() { - String projectKey = randomAlphanumeric(12); - Map<String, String> nonEmptyMap = newRandomNonEmptyMap(); - ComponentKey expected = mock(ComponentKey.class); - when(branchSupportDelegate.createComponentKey(projectKey, nonEmptyMap)).thenReturn(expected); - - ComponentKey componentKey = underTestWithBranch.createComponentKey(projectKey, nonEmptyMap); - - assertThat(componentKey).isSameAs(expected); - } - - @Test - public void createBranchComponent_fails_with_ISE_if_delegate_is_null() { - DbSession dbSession = mock(DbSession.class); - ComponentKey componentKey = mock(ComponentKey.class); - OrganizationDto organization = new OrganizationDto(); - ComponentDto mainComponentDto = new ComponentDto(); - BranchDto mainComponentBranchDto = new BranchDto(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Current edition does not support branch feature"); - - underTestNoBranch.createBranchComponent(dbSession, componentKey, organization, mainComponentDto, mainComponentBranchDto); - } - - @Test - public void createBranchComponent_delegates_to_delegate() { - DbSession dbSession = mock(DbSession.class); - ComponentKey componentKey = mock(ComponentKey.class); - OrganizationDto organization = new OrganizationDto(); - ComponentDto mainComponentDto = new ComponentDto(); - ComponentDto expected = new ComponentDto(); - BranchDto mainComponentBranchDto = new BranchDto(); - when(branchSupportDelegate.createBranchComponent(dbSession, componentKey, organization, mainComponentDto, mainComponentBranchDto)) - .thenReturn(expected); - - ComponentDto dto = underTestWithBranch.createBranchComponent(dbSession, componentKey, organization, mainComponentDto, mainComponentBranchDto); - - assertThat(dto).isSameAs(expected); - } - - @DataProvider - public static Object[][] nullOrNonEmpty() { - return new Object[][] { - {null}, - {randomAlphabetic(5)}, - }; - } - - private static Map<String, String> newRandomNonEmptyMap() { - return IntStream.range(0, 1 + new Random().nextInt(10)).boxed().collect(uniqueIndex(i -> "key_" + i, i -> "val_" + i)); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/CeQueueCleanerTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/queue/CeQueueCleanerTest.java deleted file mode 100644 index f8c78ae07dc..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/CeQueueCleanerTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ce.queue; - -import java.util.Optional; -import org.apache.commons.io.IOUtils; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.platform.ServerUpgradeStatus; -import org.sonar.api.utils.System2; -import org.sonar.ce.queue.CeQueue; -import org.sonar.db.DbTester; -import org.sonar.db.ce.CeQueueDto; -import org.sonar.db.ce.CeTaskInputDao; -import org.sonar.db.ce.CeTaskTypes; -import org.sonar.process.ProcessProperties; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class CeQueueCleanerTest { - - @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - - private ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class); - private CeQueue queue = mock(CeQueue.class); - private MapSettings settings = new MapSettings(); - - @Test - public void start_does_not_reset_in_progress_tasks_to_pending() { - insertInQueue("TASK_1", CeQueueDto.Status.PENDING); - insertInQueue("TASK_2", CeQueueDto.Status.IN_PROGRESS); - - runCleaner(); - - assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.PENDING)).isEqualTo(1); - assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.IN_PROGRESS)).isEqualTo(1); - } - - @Test - public void start_clears_queue_if_version_upgrade() { - when(serverUpgradeStatus.isUpgraded()).thenReturn(true); - - runCleaner(); - - verify(queue).clear(); - } - - @Test - public void start_does_not_clear_queue_if_version_upgrade_but_blue_green_deployment() { - when(serverUpgradeStatus.isUpgraded()).thenReturn(true); - settings.setProperty(ProcessProperties.Property.BLUE_GREEN_ENABLED.getKey(), true); - - runCleaner(); - - verify(queue, never()).clear(); - } - - @Test - public void start_deletes_orphan_report_files() { - // analysis reports are persisted but the associated - // task is not in the queue - insertInQueue("TASK_1", CeQueueDto.Status.PENDING); - insertTaskData("TASK_1"); - insertTaskData("TASK_2"); - - runCleaner(); - - CeTaskInputDao dataDao = dbTester.getDbClient().ceTaskInputDao(); - Optional<CeTaskInputDao.DataStream> task1Data = dataDao.selectData(dbTester.getSession(), "TASK_1"); - assertThat(task1Data).isPresent(); - task1Data.get().close(); - - assertThat(dataDao.selectData(dbTester.getSession(), "TASK_2")).isNotPresent(); - } - - private CeQueueDto insertInQueue(String taskUuid, CeQueueDto.Status status) { - CeQueueDto dto = new CeQueueDto(); - dto.setTaskType(CeTaskTypes.REPORT); - dto.setComponentUuid("PROJECT_1"); - dto.setUuid(taskUuid); - dto.setStatus(status); - dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), dto); - dbTester.getSession().commit(); - return dto; - } - - private void insertTaskData(String taskUuid) { - dbTester.getDbClient().ceTaskInputDao().insert(dbTester.getSession(), taskUuid, IOUtils.toInputStream("{binary}")); - dbTester.getSession().commit(); - } - - private void runCleaner() { - CeQueueCleaner cleaner = new CeQueueCleaner(dbTester.getDbClient(), serverUpgradeStatus, queue, settings.asConfig()); - cleaner.start(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java deleted file mode 100644 index a874f2b6071..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ce.queue; - -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Random; -import java.util.stream.IntStream; -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.ce.queue.CeQueue; -import org.sonar.ce.queue.CeQueueImpl; -import org.sonar.ce.queue.CeTaskSubmit; -import org.sonar.core.i18n.I18n; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.ce.CeTaskTypes; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.permission.OrganizationPermission; -import org.sonar.db.user.UserDto; -import org.sonar.server.component.ComponentUpdater; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.favorite.FavoriteUpdater; -import org.sonar.server.permission.PermissionTemplateService; -import org.sonar.server.tester.UserSessionRule; - -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.emptyMap; -import static java.util.stream.IntStream.rangeClosed; -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; -import static org.sonar.db.component.ComponentTesting.newModuleDto; -import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; -import static org.sonar.db.permission.OrganizationPermission.SCAN; - -public class ReportSubmitterTest { - - private static final String PROJECT_KEY = "MY_PROJECT"; - private static final String PROJECT_UUID = "P1"; - private static final String PROJECT_NAME = "My Project"; - private static final String TASK_UUID = "TASK_1"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public DbTester db = DbTester.create(); - - private String defaultOrganizationKey; - private String defaultOrganizationUuid; - - private CeQueue queue = mock(CeQueueImpl.class); - private TestProjectIndexers projectIndexers = new TestProjectIndexers(); - private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); - private ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), mock(System2.class), permissionTemplateService, - new FavoriteUpdater(db.getDbClient()), projectIndexers); - private BranchSupport ossEditionBranchSupport = new BranchSupport(); - - private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport); - - @Before - public void setUp() throws Exception { - defaultOrganizationKey = db.getDefaultOrganization().getKey(); - defaultOrganizationUuid = db.getDefaultOrganization().getUuid(); - } - - @Test - public void submit_with_characteristics_fails_with_ISE_when_no_branch_support_delegate() { - userSession - .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid()) - .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization()); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY))) - .thenReturn(true); - Map<String, String> nonEmptyCharacteristics = IntStream.range(0, 1 + new Random().nextInt(5)) - .boxed() - .collect(uniqueIndex(i -> randomAlphabetic(i + 10), i -> randomAlphabetic(i + 20))); - InputStream reportInput = IOUtils.toInputStream("{binary}", UTF_8); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Current edition does not support branch feature"); - - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, nonEmptyCharacteristics, reportInput); - } - - @Test - public void submit_stores_report() { - userSession - .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid()) - .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization()); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY))) - .thenReturn(true); - - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}", UTF_8)); - - verifyReportIsPersisted(TASK_UUID); - } - - @Test - public void submit_a_report_on_existing_project() { - ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization()); - UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project); - mockSuccessfulPrepareSubmitCall(); - - underTest.submit(defaultOrganizationKey, project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8)); - - verifyReportIsPersisted(TASK_UUID); - verifyZeroInteractions(permissionTemplateService); - verify(queue).submit(argThat(submit -> submit.getType().equals(CeTaskTypes.REPORT) - && submit.getComponent().filter(cpt -> cpt.getUuid().equals(project.uuid()) && cpt.getMainComponentUuid().equals(project.uuid())).isPresent() - && submit.getSubmitterUuid().equals(user.getUuid()) - && submit.getUuid().equals(TASK_UUID))); - } - - @Test - public void provision_project_if_does_not_exist() { - OrganizationDto organization = db.organizations().insert(); - userSession - .addPermission(OrganizationPermission.SCAN, organization.getUuid()) - .addPermission(PROVISION_PROJECTS, organization); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); - - underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - - ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get(); - verifyReportIsPersisted(TASK_UUID); - verify(queue).submit(argThat(submit -> submit.getType().equals(CeTaskTypes.REPORT) - && submit.getComponent().filter(cpt -> cpt.getUuid().equals(createdProject.uuid()) && cpt.getMainComponentUuid().equals(createdProject.uuid())).isPresent() - && submit.getUuid().equals(TASK_UUID))); - } - - @Test - public void add_project_as_favorite_when_project_creator_permission_on_permission_template() { - UserDto user = db.users().insertUser(); - OrganizationDto organization = db.organizations().insert(); - userSession - .logIn(user) - .addPermission(OrganizationPermission.SCAN, organization.getUuid()) - .addPermission(PROVISION_PROJECTS, organization); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); - - underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - - ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get(); - assertThat(db.favorites().hasFavorite(createdProject, user.getId())).isTrue(); - } - - @Test - public void do_no_add_favorite_when_no_project_creator_permission_on_permission_template() { - userSession - .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid()) - .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization()); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY))) - .thenReturn(true); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(false); - mockSuccessfulPrepareSubmitCall(); - - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - - ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get(); - assertThat(db.favorites().hasNoFavorite(createdProject)).isTrue(); - } - - @Test - public void do_no_add_favorite_when_already_100_favorite_projects_and_no_project_creator_permission_on_permission_template() { - UserDto user = db.users().insertUser(); - rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject(), user.getId())); - OrganizationDto organization = db.organizations().insert(); - userSession - .logIn(user) - .addPermission(OrganizationPermission.SCAN, organization.getUuid()) - .addPermission(PROVISION_PROJECTS, organization); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); - - underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - - ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get(); - assertThat(db.favorites().hasNoFavorite(createdProject)).isTrue(); - } - - @Test - public void submit_a_report_on_new_project_with_scan_permission_on_organization() { - userSession - .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid()) - .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization()); - mockSuccessfulPrepareSubmitCall(); - when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY))) - .thenReturn(true); - - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - - verify(queue).submit(any(CeTaskSubmit.class)); - } - - @Test - public void user_with_scan_permission_on_organization_is_allowed_to_submit_a_report_on_existing_project() { - OrganizationDto org = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(org); - userSession.addPermission(SCAN, org); - mockSuccessfulPrepareSubmitCall(); - - underTest.submit(org.getKey(), project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}")); - - verify(queue).submit(any(CeTaskSubmit.class)); - } - - @Test - public void submit_a_report_on_existing_project_with_project_scan_permission() { - ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization()); - userSession.addProjectPermission(SCAN_EXECUTION, project); - mockSuccessfulPrepareSubmitCall(); - - underTest.submit(defaultOrganizationKey, project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}")); - - verify(queue).submit(any(CeTaskSubmit.class)); - } - - @Test - public void fail_with_NotFoundException_if_organization_with_specified_key_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Organization with key 'fop' does not exist"); - - underTest.submit("fop", PROJECT_KEY, null, emptyMap(), null /* method will fail before parameter is used */); - } - - @Test - public void fail_with_organizationKey_does_not_match_organization_of_specified_component() { - userSession.logIn().setRoot(); - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organization); - mockSuccessfulPrepareSubmitCall(); - - underTest.submit(organization.getKey(), project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}")); - } - - @Test - public void fail_if_component_is_not_a_project() { - ComponentDto component = db.components().insertPublicPortfolio(db.getDefaultOrganization()); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, component); - mockSuccessfulPrepareSubmitCall(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Component '%s' is not a project", component.getKey())); - - underTest.submit(defaultOrganizationKey, component.getDbKey(), component.name(), emptyMap(), IOUtils.toInputStream("{binary}")); - } - - @Test - public void fail_if_project_key_already_exists_as_module() { - ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization()); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - mockSuccessfulPrepareSubmitCall(); - - try { - underTest.submit(defaultOrganizationKey, module.getDbKey(), module.name(), emptyMap(), IOUtils.toInputStream("{binary}")); - fail(); - } catch (BadRequestException e) { - assertThat(e.errors()).contains( - format("The project '%s' is already defined in SonarQube but as a module of project '%s'. " + - "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.", - module.getKey(), project.getKey(), project.getKey(), module.getKey())); - } - } - - @Test - public void fail_with_forbidden_exception_when_no_scan_permission() { - expectedException.expect(ForbiddenException.class); - - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - } - - @Test - public void fail_with_forbidden_exception_on_new_project_when_only_project_scan_permission() { - ComponentDto component = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID); - userSession.addProjectPermission(SCAN_EXECUTION, component); - mockSuccessfulPrepareSubmitCall(); - - expectedException.expect(ForbiddenException.class); - underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}")); - } - - private void verifyReportIsPersisted(String taskUuid) { - assertThat(db.selectFirst("select task_uuid from ce_task_input where task_uuid='" + taskUuid + "'")).isNotNull(); - } - - private void mockSuccessfulPrepareSubmitCall() { - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java deleted file mode 100644 index 744cf1847d6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.component.SnapshotDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.webhook.WebhookDto; -import org.sonar.server.es.TestProjectIndexers; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_DELETION; - -public class ComponentCleanerServiceTest { - - private System2 system2 = System2.INSTANCE; - - @Rule - public DbTester db = DbTester.create(system2); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - private TestProjectIndexers projectIndexers = new TestProjectIndexers(); - private ResourceTypes mockResourceTypes = mock(ResourceTypes.class); - private ComponentCleanerService underTest = new ComponentCleanerService(dbClient, mockResourceTypes, projectIndexers); - - @Test - public void delete_project_from_db_and_index() { - DbData data1 = insertData(); - DbData data2 = insertData(); - - underTest.delete(dbSession, data1.project); - - assertNotExists(data1); - assertExists(data2); - } - - @Test - public void delete_list_of_projects_from_db_and_index() { - DbData data1 = insertData(); - DbData data2 = insertData(); - DbData data3 = insertData(); - - underTest.delete(dbSession, asList(data1.project, data2.project)); - dbSession.commit(); - - assertNotExists(data1); - assertNotExists(data2); - assertExists(data3); - } - - @Test - public void delete_branch() { - DbData data1 = insertData(); - DbData data2 = insertData(); - DbData data3 = insertData(); - - underTest.deleteBranch(dbSession, data1.project); - dbSession.commit(); - - assertNotExists(data1); - assertExists(data2); - assertExists(data3); - } - - @Test - public void delete_webhooks_from_projects() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project1 = db.components().insertPrivateProject(organization); - WebhookDto webhook1 = db.webhooks().insertWebhook(project1); - db.webhookDelivery().insert(webhook1); - ComponentDto project2 = db.components().insertPrivateProject(organization); - WebhookDto webhook2 = db.webhooks().insertWebhook(project2); - db.webhookDelivery().insert(webhook2); - ComponentDto projectNotToBeDeleted = db.components().insertPrivateProject(organization); - WebhookDto webhook3 = db.webhooks().insertWebhook(projectNotToBeDeleted); - db.webhookDelivery().insert(webhook3); - mockResourceTypeAsValidProject(); - - underTest.delete(dbSession, asList(project1, project2)); - - assertThat(db.countRowsOfTable(db.getSession(), "webhooks")).isEqualTo(1); - assertThat(db.countRowsOfTable(db.getSession(), "webhook_deliveries")).isEqualTo(1); - } - - @Test - public void fail_with_IAE_if_not_a_project() { - mockResourceTypeAsValidProject(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); - dbClient.componentDao().insert(dbSession, project); - ComponentDto file = newFileDto(project, null); - dbClient.componentDao().insert(dbSession, file); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - underTest.delete(dbSession, file); - } - - @Test - public void fail_to_delete_not_deletable_resource_type() { - ResourceType resourceType = mock(ResourceType.class); - when(resourceType.getBooleanProperty("deletable")).thenReturn(false); - when(mockResourceTypes.get(anyString())).thenReturn(resourceType); - ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); - dbClient.componentDao().insert(dbSession, project); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - underTest.delete(dbSession, project); - } - - @Test - public void fail_to_delete_null_resource_type() { - when(mockResourceTypes.get(anyString())).thenReturn(null); - ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); - dbClient.componentDao().insert(dbSession, project); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - underTest.delete(dbSession, project); - } - - @Test - public void fail_to_delete_project_when_branch() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(IllegalArgumentException.class); - - underTest.delete(dbSession, branch); - } - - private DbData insertData() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organization); - RuleDefinitionDto rule = db.rules().insert(); - IssueDto issue = db.issues().insert(rule, project, project); - SnapshotDto analysis = db.components().insertSnapshot(project); - mockResourceTypeAsValidProject(); - return new DbData(project, analysis, issue); - } - - private void mockResourceTypeAsValidProject() { - ResourceType resourceType = mock(ResourceType.class); - when(resourceType.getBooleanProperty(anyString())).thenReturn(true); - when(mockResourceTypes.get(anyString())).thenReturn(resourceType); - } - - private void assertNotExists(DbData data) { - assertDataInDb(data, false); - - assertThat(projectIndexers.hasBeenCalled(data.project.uuid(), PROJECT_DELETION)).isTrue(); - } - - private void assertExists(DbData data) { - assertDataInDb(data, true); - assertThat(projectIndexers.hasBeenCalled(data.project.uuid(), PROJECT_DELETION)).isFalse(); - } - - private void assertDataInDb(DbData data, boolean exists) { - assertThat(dbClient.componentDao().selectByUuid(dbSession, data.project.uuid()).isPresent()).isEqualTo(exists); - assertThat(dbClient.snapshotDao().selectByUuid(dbSession, data.snapshot.getUuid()).isPresent()).isEqualTo(exists); - assertThat(dbClient.issueDao().selectByKey(dbSession, data.issue.getKey()).isPresent()).isEqualTo(exists); - } - - private static class DbData { - final ComponentDto project; - final SnapshotDto snapshot; - final IssueDto issue; - - DbData(ComponentDto project, SnapshotDto snapshot, IssueDto issue) { - this.project = project; - this.snapshot = snapshot; - this.issue = issue; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java deleted file mode 100644 index dfcae499d22..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.server.exceptions.NotFoundException; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.db.component.BranchType.PULL_REQUEST; -import static org.sonar.db.component.ComponentTesting.newDirectory; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.component.ComponentTesting.newModuleDto; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; -import static org.sonar.server.component.ComponentFinder.ParamNames.ID_AND_KEY; - -public class ComponentFinderTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private final DbSession dbSession = db.getSession(); - private ComponentFinder underTest = TestComponentFinder.from(db); - - @Test - public void fail_when_the_uuid_and_key_are_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Either 'id' or 'key' must be provided"); - - underTest.getByUuidOrKey(dbSession, null, null, ID_AND_KEY); - } - - @Test - public void fail_when_the_uuid_and_key_are_provided() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Either 'id' or 'key' must be provided"); - - underTest.getByUuidOrKey(dbSession, "project-uuid", "project-key", ID_AND_KEY); - } - - @Test - public void fail_when_the_uuid_is_empty() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The 'id' parameter must not be empty"); - - underTest.getByUuidOrKey(dbSession, "", null, ID_AND_KEY); - } - - @Test - public void fail_when_the_key_is_empty() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The 'key' parameter must not be empty"); - - underTest.getByUuidOrKey(dbSession, null, "", ID_AND_KEY); - } - - @Test - public void fail_when_component_uuid_not_found() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Component id 'project-uuid' not found"); - - underTest.getByUuidOrKey(dbSession, "project-uuid", null, ID_AND_KEY); - } - - @Test - public void fail_when_component_key_not_found() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Component key 'project-key' not found"); - - underTest.getByUuidOrKey(dbSession, null, "project-key", ID_AND_KEY); - } - - @Test - public void fail_to_getByUuidOrKey_when_using_branch_uuid() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component id '%s' not found", branch.uuid())); - - underTest.getByUuidOrKey(dbSession, branch.uuid(), null, ID_AND_KEY); - } - - @Test - public void fail_to_getByUuidOrKey_when_using_branch_key() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey())); - - underTest.getByUuidOrKey(dbSession, null, branch.getDbKey(), ID_AND_KEY); - } - - @Test - public void fail_when_component_uuid_is_removed() { - ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization())); - db.components().insertComponent(newFileDto(project, null, "file-uuid").setEnabled(false)); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Component id 'file-uuid' not found"); - - underTest.getByUuid(dbSession, "file-uuid"); - } - - @Test - public void fail_to_getByUuid_on_branch() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component id '%s' not found", branch.uuid())); - - underTest.getByUuid(dbSession, branch.uuid()); - } - - @Test - public void fail_when_component_key_is_removed() { - ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization())); - db.components().insertComponent(newFileDto(project).setDbKey("file-key").setEnabled(false)); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Component key 'file-key' not found"); - - underTest.getByKey(dbSession, "file-key"); - } - - @Test - public void fail_getByKey_on_branch() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey())); - - underTest.getByKey(dbSession, branch.getDbKey()); - } - - @Test - public void get_component_by_uuid() { - db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid")); - - ComponentDto component = underTest.getByUuidOrKey(dbSession, "project-uuid", null, ID_AND_KEY); - - assertThat(component.uuid()).isEqualTo("project-uuid"); - } - - @Test - public void get_component_by_key() { - db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()).setDbKey("project-key")); - - ComponentDto component = underTest.getByUuidOrKey(dbSession, null, "project-key", ID_AND_KEY); - - assertThat(component.getDbKey()).isEqualTo("project-key"); - } - - @Test - public void get_by_key_and_branch() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - ComponentDto module = db.components().insertComponent(newModuleDto(branch)); - ComponentDto directory = db.components().insertComponent(newDirectory(module, "scr")); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - - assertThat(underTest.getByKeyAndBranch(dbSession, project.getKey(), "my_branch").uuid()).isEqualTo(branch.uuid()); - assertThat(underTest.getByKeyAndBranch(dbSession, module.getKey(), "my_branch").uuid()).isEqualTo(module.uuid()); - assertThat(underTest.getByKeyAndBranch(dbSession, file.getKey(), "my_branch").uuid()).isEqualTo(file.uuid()); - assertThat(underTest.getByKeyAndBranch(dbSession, directory.getKey(), "my_branch").uuid()).isEqualTo(directory.uuid()); - } - - @Test - public void get_by_key_and_pull_request() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("pr-123").setBranchType(PULL_REQUEST).setMergeBranchUuid(project.uuid())); - ComponentDto module = db.components().insertComponent(newModuleDto(branch)); - ComponentDto directory = db.components().insertComponent(newDirectory(module, "scr")); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - - assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, project.getKey(), null, "pr-123").uuid()).isEqualTo(branch.uuid()); - assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, module.getKey(), null, "pr-123").uuid()).isEqualTo(module.uuid()); - assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, file.getKey(), null, "pr-123").uuid()).isEqualTo(file.uuid()); - assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, directory.getKey(), null, "pr-123").uuid()).isEqualTo(directory.uuid()); - } - - @Test - public void fail_when_pull_request_branch_provided() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setKey("pr-123").setBranchType(PULL_REQUEST)); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Either branch or pull request can be provided, not both"); - - assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, project.getKey(), "pr-123", "pr-123").uuid()).isEqualTo(pullRequest.uuid()); - } - - @Test - public void get_by_key_and_branch_accept_main_branch() { - ComponentDto project = db.components().insertMainBranch(); - - assertThat(underTest.getByKeyAndBranch(dbSession, project.getKey(), "master").uuid()).isEqualTo(project.uuid()); - } - - @Test - public void fail_to_get_by_key_and_branch_when_branch_does_not_exist() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - ComponentDto file = db.components().insertComponent(newFileDto(branch)); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component '%s' on branch 'other_branch' not found", file.getKey())); - - underTest.getByKeyAndBranch(dbSession, file.getKey(), "other_branch"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java deleted file mode 100644 index 4f330773992..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.project.ProjectLifeCycleListeners; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.component.ComponentTesting.newModuleDto; - -public class ComponentServiceTest { - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - - private ComponentDbTester componentDb = new ComponentDbTester(dbTester); - private DbClient dbClient = dbTester.getDbClient(); - private DbSession dbSession = dbTester.getSession(); - private TestProjectIndexers projectIndexers = new TestProjectIndexers(); - private ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class); - - private ComponentService underTest = new ComponentService(dbClient, userSession, projectIndexers, projectLifeCycleListeners); - - @Test - public void bulk_update() { - ComponentDto project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert()).setDbKey("my_project")); - ComponentDto module = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:module")); - ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:inactive_module").setEnabled(false)); - ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo")); - ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false)); - - underTest.bulkUpdateKey(dbSession, project, "my_", "your_"); - - assertComponentKeyUpdated(project.getDbKey(), "your_project"); - assertComponentKeyUpdated(module.getDbKey(), "your_project:root:module"); - assertComponentKeyUpdated(file.getDbKey(), "your_project:root:module:src/File.xoo"); - assertComponentKeyUpdated(inactiveModule.getDbKey(), "your_project:root:inactive_module"); - assertComponentKeyUpdated(inactiveFile.getDbKey(), "your_project:root:module:src/InactiveFile.xoo"); - } - - private void assertComponentKeyUpdated(String oldKey, String newKey) { - assertThat(dbClient.componentDao().selectByKey(dbSession, oldKey)).isEmpty(); - assertThat(dbClient.componentDao().selectByKey(dbSession, newKey)).isPresent(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java deleted file mode 100644 index 66583ddfbf2..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import com.google.common.collect.ImmutableSet; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.server.es.ProjectIndexer; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.project.Project; -import org.sonar.server.project.ProjectLifeCycleListeners; -import org.sonar.server.project.RekeyedProject; -import org.sonar.server.tester.UserSessionRule; - -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.component.ComponentTesting.newModuleDto; - -public class ComponentServiceUpdateKeyTest { - - private System2 system2 = System2.INSTANCE; - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(system2); - - private ComponentDbTester componentDb = new ComponentDbTester(db); - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - private TestProjectIndexers projectIndexers = new TestProjectIndexers(); - private ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class); - private ComponentService underTest = new ComponentService(dbClient, userSession, projectIndexers, projectLifeCycleListeners); - - @Test - public void update_project_key() { - ComponentDto project = insertSampleRootProject(); - ComponentDto file = componentDb.insertComponent(ComponentTesting.newFileDto(project, null).setDbKey("sample:root:src/File.xoo")); - ComponentDto inactiveFile = componentDb.insertComponent(ComponentTesting.newFileDto(project, null).setDbKey("sample:root:src/InactiveFile.xoo").setEnabled(false)); - - dbSession.commit(); - - logInAsProjectAdministrator(project); - underTest.updateKey(dbSession, project, "sample2:root"); - dbSession.commit(); - - // Check project key has been updated - assertThat(db.getDbClient().componentDao().selectByKey(dbSession, project.getDbKey())).isEmpty(); - assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root")).isNotNull(); - - // Check file key has been updated - assertThat(db.getDbClient().componentDao().selectByKey(dbSession, file.getDbKey())).isEmpty(); - assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root:src/File.xoo")).isNotNull(); - assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root:src/InactiveFile.xoo")).isNotNull(); - - assertThat(dbClient.componentDao().selectByKey(dbSession, inactiveFile.getDbKey())).isEmpty(); - - assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue(); - } - - @Test - public void update_module_key() { - ComponentDto project = insertSampleRootProject(); - ComponentDto module = ComponentTesting.newModuleDto(project).setDbKey("sample:root:module"); - db.components().insertComponent(module); - ComponentDto file = ComponentTesting.newFileDto(module, null).setDbKey("sample:root:module:src/File.xoo"); - db.components().insertComponent(file); - logInAsProjectAdministrator(project); - - underTest.updateKey(dbSession, module, "sample:root2:module"); - dbSession.commit(); - - assertThat(dbClient.componentDao().selectByKey(dbSession, project.getDbKey())).isPresent(); - assertComponentKeyHasBeenUpdated(module.getDbKey(), "sample:root2:module"); - assertComponentKeyHasBeenUpdated(file.getDbKey(), "sample:root2:module:src/File.xoo"); - - // do not index the module but the project - assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue(); - } - - @Test - public void update_provisioned_project_key() { - ComponentDto provisionedProject = insertProject("provisionedProject"); - - dbSession.commit(); - - logInAsProjectAdministrator(provisionedProject); - underTest.updateKey(dbSession, provisionedProject, "provisionedProject2"); - dbSession.commit(); - - assertComponentKeyHasBeenUpdated(provisionedProject.getDbKey(), "provisionedProject2"); - assertThat(projectIndexers.hasBeenCalled(provisionedProject.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue(); - } - - @Test - public void fail_to_update_project_key_without_admin_permission() { - expectedException.expect(ForbiddenException.class); - - ComponentDto project = insertSampleRootProject(); - userSession.logIn("john").addProjectPermission(UserRole.USER, project); - - underTest.updateKey(dbSession, project, "sample2:root"); - } - - @Test - public void fail_if_old_key_and_new_key_are_the_same() { - ComponentDto project = insertSampleRootProject(); - ComponentDto anotherProject = componentDb.insertPrivateProject(); - logInAsProjectAdministrator(project); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Impossible to update key: a component with key \"" + anotherProject.getDbKey() + "\" already exists."); - - underTest.updateKey(dbSession, project, anotherProject.getDbKey()); - } - - @Test - public void fail_if_new_key_is_empty() { - ComponentDto project = insertSampleRootProject(); - logInAsProjectAdministrator(project); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Malformed key for ''. It cannot be empty nor contain whitespaces."); - - underTest.updateKey(dbSession, project, ""); - } - - @Test - public void fail_if_new_key_is_invalid() { - ComponentDto project = insertSampleRootProject(); - logInAsProjectAdministrator(project); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Malformed key for 'sample root'. It cannot be empty nor contain whitespaces."); - - underTest.updateKey(dbSession, project, "sample root"); - } - - @Test - public void fail_if_update_is_not_on_module_or_project() { - ComponentDto project = insertSampleRootProject(); - ComponentDto file = componentDb.insertComponent(newFileDto(project, null)); - logInAsProjectAdministrator(project); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Component updated must be a module or a key"); - - underTest.updateKey(dbSession, file, "file:key"); - } - - @Test - public void bulk_update_key() { - ComponentDto project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey("my_project")); - ComponentDto module = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:module")); - ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:inactive_module").setEnabled(false)); - ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo")); - ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false)); - - underTest.bulkUpdateKey(dbSession, project, "my_", "your_"); - - assertComponentKeyUpdated(project.getDbKey(), "your_project"); - assertComponentKeyUpdated(module.getDbKey(), "your_project:root:module"); - assertComponentKeyUpdated(file.getDbKey(), "your_project:root:module:src/File.xoo"); - assertComponentKeyUpdated(inactiveModule.getDbKey(), "your_project:root:inactive_module"); - assertComponentKeyUpdated(inactiveFile.getDbKey(), "your_project:root:module:src/InactiveFile.xoo"); - verify(projectLifeCycleListeners).onProjectsRekeyed(ImmutableSet.of( - new RekeyedProject(new Project(project.uuid(), "your_project", project.name(), project.uuid(), emptyList()), "my_project") - )); - } - - @Test - public void bulk_update_key_with_branch_and_pr() { - ComponentDto project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey("my_project")); - ComponentDto branch = componentDb.insertProjectBranch(project); - ComponentDto module = componentDb.insertComponent(newModuleDto(branch).setDbKey("my_project:root:module")); - ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo")); - - underTest.bulkUpdateKey(dbSession, project, "my_", "your_"); - - assertComponentKeyUpdated(project.getDbKey(), "your_project"); - assertComponentKeyUpdated(module.getDbKey(), "your_project:root:module"); - assertComponentKeyUpdated(file.getDbKey(), "your_project:root:module:src/File.xoo"); - verify(projectLifeCycleListeners).onProjectsRekeyed(ImmutableSet.of( - new RekeyedProject(new Project(project.uuid(), "your_project", project.name(), project.uuid(), emptyList()), "my_project") - )); - } - - private void assertComponentKeyUpdated(String oldKey, String newKey) { - assertThat(dbClient.componentDao().selectByKey(dbSession, oldKey)).isEmpty(); - assertThat(dbClient.componentDao().selectByKey(dbSession, newKey)).isPresent(); - } - - private ComponentDto insertSampleRootProject() { - return insertProject("sample:root"); - } - - private ComponentDto insertProject(String key) { - ComponentDto project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey(key)); - return project; - } - - private void assertComponentKeyHasBeenUpdated(String oldKey, String newKey) { - assertThat(dbClient.componentDao().selectByKey(dbSession, oldKey)).isEmpty(); - assertThat(dbClient.componentDao().selectByKey(dbSession, newKey)).isPresent(); - } - - private void logInAsProjectAdministrator(ComponentDto provisionedProject) { - userSession.logIn("john").addProjectPermission(UserRole.ADMIN, provisionedProject); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java deleted file mode 100644 index c8edc8156fa..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import java.util.Optional; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Scopes; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.es.ProjectIndexer; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.favorite.FavoriteUpdater; -import org.sonar.server.l18n.I18nRule; -import org.sonar.server.permission.PermissionTemplateService; - -import static java.util.stream.IntStream.rangeClosed; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.api.resources.Qualifiers.APP; -import static org.sonar.api.resources.Qualifiers.VIEW; - -public class ComponentUpdaterTest { - - private static final String DEFAULT_PROJECT_KEY = "project-key"; - private static final String DEFAULT_PROJECT_NAME = "project-name"; - - private System2 system2 = System2.INSTANCE; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project"); - - private TestProjectIndexers projectIndexers = new TestProjectIndexers(); - private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); - - private ComponentUpdater underTest = new ComponentUpdater(db.getDbClient(), i18n, system2, - permissionTemplateService, - new FavoriteUpdater(db.getDbClient()), - projectIndexers); - - @Test - public void persist_and_index_when_creating_project() { - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .setPrivate(true) - .build(); - ComponentDto returned = underTest.create(db.getSession(), project, null); - - ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid()); - assertThat(loaded.getDbKey()).isEqualTo(DEFAULT_PROJECT_KEY); - assertThat(loaded.name()).isEqualTo(DEFAULT_PROJECT_NAME); - assertThat(loaded.longName()).isEqualTo(DEFAULT_PROJECT_NAME); - assertThat(loaded.qualifier()).isEqualTo(Qualifiers.PROJECT); - assertThat(loaded.scope()).isEqualTo(Scopes.PROJECT); - assertThat(loaded.getOrganizationUuid()).isEqualTo(db.getDefaultOrganization().getUuid()); - assertThat(loaded.uuid()).isNotNull(); - assertThat(loaded.projectUuid()).isEqualTo(loaded.uuid()); - assertThat(loaded.moduleUuid()).isNull(); - assertThat(loaded.moduleUuidPath()).isEqualTo("." + loaded.uuid() + "."); - assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate()); - assertThat(loaded.getCreatedAt()).isNotNull(); - assertThat(db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY)).isNotNull(); - - assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue(); - - Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), returned.uuid()); - assertThat(branch).isPresent(); - assertThat(branch.get().getKey()).isEqualTo(BranchDto.DEFAULT_MAIN_BRANCH_NAME); - assertThat(branch.get().getMergeBranchUuid()).isNull(); - assertThat(branch.get().getBranchType()).isEqualTo(BranchType.LONG); - assertThat(branch.get().getUuid()).isEqualTo(returned.uuid()); - assertThat(branch.get().getProjectUuid()).isEqualTo(returned.uuid()); - } - - @Test - public void persist_private_flag_true_when_creating_project() { - OrganizationDto organization = db.organizations().insert(); - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(organization.getUuid()) - .setPrivate(true) - .build(); - ComponentDto returned = underTest.create(db.getSession(), project, null); - ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid()); - assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate()); - } - - @Test - public void persist_private_flag_false_when_creating_project() { - OrganizationDto organization = db.organizations().insert(); - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(organization.getUuid()) - .setPrivate(false) - .build(); - ComponentDto returned = underTest.create(db.getSession(), project, null); - ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid()); - assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate()); - } - - @Test - public void create_view() { - NewComponent view = NewComponent.newComponentBuilder() - .setKey("view-key") - .setName("view-name") - .setQualifier(VIEW) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(); - - ComponentDto returned = underTest.create(db.getSession(), view, null); - - ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid()); - assertThat(loaded.getDbKey()).isEqualTo("view-key"); - assertThat(loaded.name()).isEqualTo("view-name"); - assertThat(loaded.qualifier()).isEqualTo("VW"); - assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue(); - Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), returned.uuid()); - assertThat(branch).isNotPresent(); - } - - @Test - public void create_application() { - NewComponent application = NewComponent.newComponentBuilder() - .setKey("app-key") - .setName("app-name") - .setQualifier(APP) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(); - - ComponentDto returned = underTest.create(db.getSession(), application, null); - - ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid()); - assertThat(loaded.getDbKey()).isEqualTo("app-key"); - assertThat(loaded.name()).isEqualTo("app-name"); - assertThat(loaded.qualifier()).isEqualTo("APP"); - assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue(); - Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), returned.uuid()); - assertThat(branch).isPresent(); - assertThat(branch.get().getKey()).isEqualTo(BranchDto.DEFAULT_MAIN_BRANCH_NAME); - assertThat(branch.get().getMergeBranchUuid()).isNull(); - assertThat(branch.get().getBranchType()).isEqualTo(BranchType.LONG); - assertThat(branch.get().getUuid()).isEqualTo(returned.uuid()); - assertThat(branch.get().getProjectUuid()).isEqualTo(returned.uuid()); - } - - @Test - public void apply_default_permission_template() { - int userId = 42; - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(); - ComponentDto dto = underTest.create(db.getSession(), project, userId); - - verify(permissionTemplateService).applyDefault(db.getSession(), dto, userId); - } - - @Test - public void add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template() { - UserDto userDto = db.users().insertUser(); - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))) - .thenReturn(true); - - ComponentDto dto = underTest.create(db.getSession(), project, userDto.getId()); - - assertThat(db.favorites().hasFavorite(dto, userDto.getId())).isTrue(); - } - - @Test - public void do_not_add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template_and_already_100_favorites() { - UserDto user = db.users().insertUser(); - rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject(), user.getId())); - NewComponent project = NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(); - when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(eq(db.getSession()), any(ComponentDto.class))) - .thenReturn(true); - - ComponentDto dto = underTest.create(db.getSession(), - project, - user.getId()); - - assertThat(db.favorites().hasFavorite(dto, user.getId())).isFalse(); - } - - @Test - public void does_not_add_project_to_favorite_when_anonymously_created() { - ComponentDto project = underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(), - null); - - assertThat(db.favorites().hasNoFavorite(project)).isTrue(); - } - - @Test - public void does_not_add_project_to_favorite_when_project_has_no_permission_on_template() { - ComponentDto project = underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(DEFAULT_PROJECT_KEY) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(), - null); - - assertThat(db.favorites().hasNoFavorite(project)).isTrue(); - } - - @Test - public void fail_when_project_key_already_exists() { - ComponentDto existing = db.components().insertPrivateProject(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Could not create Project, key already exists: " + existing.getDbKey()); - - underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(existing.getDbKey()) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(existing.getOrganizationUuid()) - .build(), - null); - } - - @Test - public void fail_when_project_key_already_exists_on_other_organization() { - ComponentDto existing = db.components().insertPrivateProject(db.organizations().insert()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Could not create Project, key already exists: " + existing.getDbKey()); - - underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(existing.getDbKey()) - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(existing.getOrganizationUuid()) - .build(), - null); - } - - @Test - public void fail_when_key_has_bad_format() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Malformed key for Project: ' '"); - - underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(" ") - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(), - null); - } - - @Test - public void properly_fail_when_key_contains_percent_character() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Malformed key for Project: ' '"); - - underTest.create(db.getSession(), - NewComponent.newComponentBuilder() - .setKey(" ") - .setName(DEFAULT_PROJECT_NAME) - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .build(), - null); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java deleted file mode 100644 index 10b8505dedb..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static com.google.common.base.Strings.repeat; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.resources.Qualifiers.PROJECT; -import static org.sonar.server.component.NewComponent.newComponentBuilder; - -public class NewComponentTest { - private static final String ORGANIZATION_UUID = "org1"; - private static final String KEY = "key"; - private static final String NAME = "name"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private NewComponent.Builder underTest = newComponentBuilder(); - - @Test - public void build_throws_NPE_if_organizationUuid_is_null() { - expectBuildException(NullPointerException.class, "organization uuid can't be null"); - } - - @Test - public void build_throws_IAE_when_key_is_null() { - underTest.setOrganizationUuid(ORGANIZATION_UUID); - - expectBuildException(IllegalArgumentException.class, "Component key can't be empty"); - } - - @Test - public void build_throws_IAE_when_key_is_empty() { - underTest - .setKey("") - .setOrganizationUuid(ORGANIZATION_UUID); - - expectBuildException(IllegalArgumentException.class, "Component key can't be empty"); - } - - @Test - public void build_throws_IAE_when_key_is_longer_than_400_characters() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(repeat("a", 400 + 1)); - - expectBuildException( - IllegalArgumentException.class, - "Component key length (401) is longer than the maximum authorized (400)"); - } - - @Test - public void build_fails_with_IAE_when_name_is_null() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY); - - expectBuildException(IllegalArgumentException.class, "Component name can't be empty"); - } - - @Test - public void build_fails_with_IAE_when_name_is_empty() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(""); - - expectBuildException(IllegalArgumentException.class, "Component name can't be empty"); - } - - @Test - public void build_fails_with_IAE_when_name_is_longer_than_2000_characters() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(repeat("a", 501)); - - expectBuildException( - IllegalArgumentException.class, - "Component name length (501) is longer than the maximum authorized (500)"); - } - - @Test - public void build_fails_with_IAE_when_qualifier_is_null() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(NAME) - .setQualifier(null); - - expectBuildException(IllegalArgumentException.class, "Component qualifier can't be empty"); - } - - @Test - public void build_fails_with_IAE_when_qualifier_is_empty() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(NAME) - .setQualifier(""); - - expectBuildException(IllegalArgumentException.class, "Component qualifier can't be empty"); - } - - @Test - public void build_fails_with_IAE_when_qualifier_is_longer_than_10_characters() { - underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(NAME) - .setQualifier(repeat("a", 10 + 1)); - - expectBuildException( - IllegalArgumentException.class, - "Component qualifier length (11) is longer than the maximum authorized (10)"); - } - - @Test - public void getQualifier_returns_PROJECT_when_no_set_in_builder() { - NewComponent newComponent = underTest.setOrganizationUuid(ORGANIZATION_UUID) - .setKey(KEY) - .setName(NAME) - .build(); - - assertThat(newComponent.qualifier()).isEqualTo(PROJECT); - } - - private void expectBuildException(Class<? extends Exception> expectedExceptionType, String expectedMessage) { - expectedException.expect(expectedExceptionType); - expectedException.expectMessage(expectedMessage); - - underTest.build(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/TestComponentFinder.java b/server/sonar-server/src/test/java/org/sonar/server/component/TestComponentFinder.java deleted file mode 100644 index 2e2a9fcc787..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/TestComponentFinder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.component; - -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ResourceTypesRule; - -public class TestComponentFinder extends ComponentFinder { - private TestComponentFinder(DbClient dbClient, ResourceTypes resourceTypes) { - super(dbClient, resourceTypes); - } - - public static TestComponentFinder from(DbTester dbTester) { - return new TestComponentFinder(dbTester.getDbClient(), new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT)); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/favorite/FavoriteModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/favorite/FavoriteModuleTest.java deleted file mode 100644 index 790c4863c17..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/favorite/FavoriteModuleTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.favorite; - -import org.junit.Test; -import org.sonar.core.platform.ComponentContainer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; - -public class FavoriteModuleTest { - @Test - public void verify_count_of_added_components() { - ComponentContainer container = new ComponentContainer(); - new FavoriteModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 2); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/AppNodeClusterCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/AppNodeClusterCheckTest.java deleted file mode 100644 index c629a4a7bf6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/AppNodeClusterCheckTest.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.Arrays; -import java.util.Random; -import java.util.Set; -import java.util.stream.IntStream; -import java.util.stream.Stream; -import org.junit.Test; -import org.sonar.process.cluster.health.NodeDetails; -import org.sonar.process.cluster.health.NodeHealth; - -import static java.util.stream.Collectors.toSet; -import static java.util.stream.Stream.of; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.sonar.process.cluster.health.NodeHealth.Status.GREEN; -import static org.sonar.process.cluster.health.NodeHealth.Status.RED; -import static org.sonar.process.cluster.health.NodeHealth.Status.YELLOW; -import static org.sonar.server.health.HealthAssert.assertThat; - -public class AppNodeClusterCheckTest { - private final Random random = new Random(); - - private AppNodeClusterCheck underTest = new AppNodeClusterCheck(); - - @Test - public void status_RED_when_no_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths().collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.RED) - .andCauses("No application node"); - } - - @Test - public void status_RED_when_single_RED_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(RED).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.RED) - .andCauses("Status of all application nodes is RED", - "There should be at least two application nodes"); - } - - @Test - public void status_YELLOW_when_single_YELLOW_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(YELLOW).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses( - "Status of all application nodes is YELLOW", - "There should be at least two application nodes"); - } - - @Test - public void status_YELLOW_when_single_GREEN_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(GREEN).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("There should be at least two application nodes"); - } - - @Test - public void status_RED_when_two_RED_application_nodes() { - Set<NodeHealth> nodeHealths = nodeHealths(RED, RED).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.RED) - .andCauses("Status of all application nodes is RED"); - } - - @Test - public void status_YELLOW_when_two_YELLOW_application_nodes() { - Set<NodeHealth> nodeHealths = nodeHealths(YELLOW, YELLOW).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("Status of all application nodes is YELLOW"); - } - - @Test - public void status_YELLOW_when_one_RED_node_and_one_YELLOW_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(RED, YELLOW).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses( - "At least one application node is RED", - "At least one application node is YELLOW"); - } - - @Test - public void status_YELLOW_when_one_RED_node_and_one_GREEN_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(RED, GREEN).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("At least one application node is RED"); - } - - @Test - public void status_YELLOW_when_one_YELLOW_node_and_one_GREEN_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(YELLOW, GREEN).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("At least one application node is YELLOW"); - } - - @Test - public void status_GREEN_when_two_GREEN_application_node() { - Set<NodeHealth> nodeHealths = nodeHealths(GREEN, GREEN).collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.GREEN) - .andCauses(); - } - - @Test - public void status_GREEN_when_two_GREEN_application_node_and_any_number_of_other_is_GREEN() { - Set<NodeHealth> nodeHealths = of( - // at least 1 extra GREEN - of(appNodeHealth(GREEN)), - // 0 to 10 GREEN - randomNumberOfAppNodeHealthOfAnyStatus(GREEN), - // 2 GREEN - nodeHealths(GREEN, GREEN)) - .flatMap(s -> s) - .collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.GREEN) - .andCauses(); - } - - @Test - public void status_YELLOW_when_two_GREEN_application_node_and_any_number_of_other_is_YELLOW_or_GREEN() { - Set<NodeHealth> nodeHealths = of( - // at least 1 YELLOW - of(appNodeHealth(YELLOW)), - // 0 to 10 YELLOW/GREEN - randomNumberOfAppNodeHealthOfAnyStatus(GREEN, YELLOW), - // 2 GREEN - nodeHealths(GREEN, GREEN)) - .flatMap(s -> s) - .collect(toSet()); - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("At least one application node is YELLOW"); - } - - @Test - public void status_YELLOW_when_two_GREEN_application_node_and_any_number_of_other_is_RED_or_GREEN() { - Set<NodeHealth> nodeHealths = of( - // at least 1 RED - of(appNodeHealth(RED)), - // 0 to 10 RED/GREEN - randomNumberOfAppNodeHealthOfAnyStatus(GREEN, RED), - // 2 GREEN - nodeHealths(GREEN, GREEN)) - .flatMap(s -> s) - .collect(toSet()); - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses("At least one application node is RED"); - } - - @Test - public void status_YELLOW_when_two_GREEN_application_node_and_any_number_of_other_is_either_RED_or_YELLOW() { - Set<NodeHealth> nodeHealths = of( - // at least 1 RED - of(appNodeHealth(RED)), - // at least 1 YELLOW - of(appNodeHealth(YELLOW)), - // 0 to 10 RED/YELLOW/GREEN - randomNumberOfAppNodeHealthOfAnyStatus(RED, YELLOW, GREEN), - // 2 GREEN - nodeHealths(GREEN, GREEN)) - .flatMap(s -> s) - .collect(toSet()); - - Health check = underTest.check(nodeHealths); - - assertThat(check) - .forInput(nodeHealths) - .hasStatus(Health.Status.YELLOW) - .andCauses( - "At least one application node is YELLOW", - "At least one application node is RED"); - } - - /** - * Between 0 and 10 NodeHealth of Application node with any of the specified statuses. - */ - private Stream<NodeHealth> randomNumberOfAppNodeHealthOfAnyStatus(NodeHealth.Status... randomStatuses) { - return IntStream.range(0, random.nextInt(10)) - .mapToObj(i -> appNodeHealth(randomStatuses[random.nextInt(randomStatuses.length)])); - } - - private Stream<NodeHealth> nodeHealths(NodeHealth.Status... appNodeStatuses) { - return of( - // random number of Search nodes with random status - IntStream.range(0, random.nextInt(3)) - .mapToObj(i -> appNodeHealth(NodeDetails.Type.SEARCH, NodeHealth.Status.values()[random.nextInt(NodeHealth.Status.values().length)])), - Arrays.stream(appNodeStatuses).map(this::appNodeHealth)) - .flatMap(s -> s); - } - - private NodeHealth appNodeHealth(NodeHealth.Status status) { - return appNodeHealth(NodeDetails.Type.APPLICATION, status); - } - - private NodeHealth appNodeHealth(NodeDetails.Type type, NodeHealth.Status status) { - return NodeHealth.newNodeHealthBuilder() - .setStatus(status) - .setDetails(NodeDetails.newNodeDetailsBuilder() - .setType(type) - .setHost(randomAlphanumeric(32)) - .setName(randomAlphanumeric(32)) - .setPort(1 + random.nextInt(88)) - .setStartedAt(1 + random.nextInt(54)) - .build()) - .build(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/CeStatusNodeCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/CeStatusNodeCheckTest.java deleted file mode 100644 index 82e315e19ec..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/CeStatusNodeCheckTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import org.junit.Test; -import org.sonar.server.app.ProcessCommandWrapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class CeStatusNodeCheckTest { - private ProcessCommandWrapper processCommandWrapper = mock(ProcessCommandWrapper.class); - private CeStatusNodeCheck underTest = new CeStatusNodeCheck(processCommandWrapper); - - @Test - public void check_returns_GREEN_status_without_cause_if_ce_is_operational() { - when(processCommandWrapper.isCeOperational()).thenReturn(true); - - Health health = underTest.check(); - - assertThat(health).isEqualTo(Health.GREEN); - } - - @Test - public void check_returns_RED_status_with_cause_if_ce_is_not_operational() { - when(processCommandWrapper.isCeOperational()).thenReturn(false); - - Health health = underTest.check(); - - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("Compute Engine is not operational"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/ClusterHealthTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/ClusterHealthTest.java deleted file mode 100644 index 1265cf8e218..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/ClusterHealthTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; -import java.util.stream.IntStream; -import java.util.stream.Stream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.process.cluster.health.NodeDetails; -import org.sonar.process.cluster.health.NodeHealth; - -import static java.util.stream.Collectors.toSet; -import static java.util.stream.Stream.concat; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.process.cluster.health.NodeHealth.newNodeHealthBuilder; -import static org.sonar.server.health.Health.newHealthCheckBuilder; - -public class ClusterHealthTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private final Random random = new Random(); - - @Test - public void constructor_fails_with_NPE_if_Health_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("health can't be null"); - - new ClusterHealth(null, Collections.emptySet()); - } - - @Test - public void constructor_fails_with_NPE_if_NodeHealth_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("nodes can't be null"); - - new ClusterHealth(Health.GREEN, null); - } - - @Test - public void verify_getters() { - Health health = randomHealth(); - Set<NodeHealth> nodeHealths = randomNodeHealths(); - ClusterHealth underTest = new ClusterHealth(health, nodeHealths); - - assertThat(underTest.getHealth()).isSameAs(health); - assertThat(underTest.getNodes()).isEqualTo(nodeHealths); - } - - @Test - public void equals_is_based_on_content() { - Health health = randomHealth(); - Set<NodeHealth> nodeHealths = randomNodeHealths(); - ClusterHealth underTest = new ClusterHealth(health, nodeHealths); - - assertThat(underTest) - .isEqualTo(underTest) - .isEqualTo(new ClusterHealth(health, nodeHealths)) - .isNotEqualTo(new Object()) - .isNotEqualTo(null) - .isNotEqualTo(new ClusterHealth( - newHealthCheckBuilder() - .setStatus(health.getStatus()) - .addCause("foo_bar") - .build(), - randomNodeHealths())) - .isNotEqualTo(new ClusterHealth( - health, - concat(nodeHealths.stream(), Stream.of(randomNodeHealth())).collect(toSet()))); - } - - @Test - public void hashcode_is_based_on_content() { - Health health = randomHealth(); - Set<NodeHealth> nodeHealths = randomNodeHealths(); - ClusterHealth underTest = new ClusterHealth(health, nodeHealths); - - assertThat(underTest.hashCode()).isEqualTo(underTest.hashCode()); - } - - @Test - public void verify_toString() { - Health health = randomHealth(); - Set<NodeHealth> nodeHealths = randomNodeHealths(); - - ClusterHealth underTest = new ClusterHealth(health, nodeHealths); - - assertThat(underTest.toString()).isEqualTo("ClusterHealth{health=" + health + ", nodes=" + nodeHealths + "}"); - } - - @Test - public void test_getNodeHealth() { - Health health = randomHealth(); - Set<NodeHealth> nodeHealths = new HashSet<>(Arrays.asList(newNodeHealth("foo"), newNodeHealth("bar"))); - - ClusterHealth underTest = new ClusterHealth(health, nodeHealths); - - assertThat(underTest.getNodeHealth("does_not_exist")).isEmpty(); - assertThat(underTest.getNodeHealth("bar")).isPresent(); - } - - private Health randomHealth() { - Health.Builder healthBuilder = newHealthCheckBuilder(); - healthBuilder.setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]); - IntStream.range(0, random.nextInt(3)).mapToObj(i -> randomAlphanumeric(3)).forEach(healthBuilder::addCause); - return healthBuilder.build(); - } - - private Set<NodeHealth> randomNodeHealths() { - return IntStream.range(0, random.nextInt(4)).mapToObj(i -> randomNodeHealth()).collect(toSet()); - } - - private NodeHealth randomNodeHealth() { - return newNodeHealthBuilder() - .setStatus(NodeHealth.Status.values()[random.nextInt(NodeHealth.Status.values().length)]) - .setDetails( - NodeDetails.newNodeDetailsBuilder() - .setType(random.nextBoolean() ? NodeDetails.Type.SEARCH : NodeDetails.Type.APPLICATION) - .setName(randomAlphanumeric(3)) - .setHost(randomAlphanumeric(4)) - .setPort(1 + random.nextInt(344)) - .setStartedAt(1 + random.nextInt(999)) - .build()) - .build(); - } - - private static NodeHealth newNodeHealth(String nodeName) { - return newNodeHealthBuilder() - .setStatus(NodeHealth.Status.YELLOW) - .setDetails(randomNodeDetails(nodeName)) - .build(); - } - - private static NodeDetails randomNodeDetails(String nodeName) { - return NodeDetails.newNodeDetailsBuilder() - .setType(NodeDetails.Type.APPLICATION) - .setName(nodeName) - .setHost(randomAlphanumeric(4)) - .setPort(3000) - .setStartedAt(1_000L) - .build(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/DbConnectionNodeCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/DbConnectionNodeCheckTest.java deleted file mode 100644 index 4bdc794e71a..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/DbConnectionNodeCheckTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.IsAliveMapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class DbConnectionNodeCheckTest { - private DbClient dbClient = mock(DbClient.class); - private DbSession dbSession = mock(DbSession.class); - private IsAliveMapper isAliveMapper = mock(IsAliveMapper.class); - - private DbConnectionNodeCheck underTest = new DbConnectionNodeCheck(dbClient); - - @Before - public void wireMocks() { - when(dbClient.openSession(anyBoolean())).thenReturn(dbSession); - when(dbSession.getMapper(IsAliveMapper.class)).thenReturn(isAliveMapper); - } - - @Test - public void status_is_GREEN_without_cause_if_isAlive_returns_1() { - when(isAliveMapper.isAlive()).thenReturn(1); - - Health health = underTest.check(); - - assertThat(health).isEqualTo(Health.GREEN); - } - - @Test - public void status_is_RED_with_single_cause_if_any_error_occurs_when_checking_DB() { - when(isAliveMapper.isAlive()).thenThrow(new RuntimeException("simulated runtime exception when querying DB")); - - Health health = underTest.check(); - - verifyRedStatus(health); - } - - /** - * By contract {@link IsAliveMapper#isAlive()} can not return anything but 1. Still we write this test as a - * protection against change in this contract. - */ - @Test - public void status_is_RED_with_single_cause_if_isAlive_does_not_return_1() { - when(isAliveMapper.isAlive()).thenReturn(12); - - Health health = underTest.check(); - - verifyRedStatus(health); - } - - private void verifyRedStatus(Health health) { - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("Can't connect to DB"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusClusterCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusClusterCheckTest.java deleted file mode 100644 index f8a2c288c8b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusClusterCheckTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import com.google.common.collect.ImmutableSet; -import java.util.Random; -import java.util.Set; -import org.elasticsearch.cluster.health.ClusterHealthStatus; -import org.junit.Test; -import org.mockito.Mockito; -import org.sonar.process.cluster.health.NodeDetails; -import org.sonar.process.cluster.health.NodeHealth; -import org.sonar.server.es.EsClient; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.when; - -public class EsStatusClusterCheckTest { - - private EsClient esClient = Mockito.mock(EsClient.class, RETURNS_DEEP_STUBS); - private Random random = new Random(); - private EsStatusClusterCheck underTest = new EsStatusClusterCheck(esClient); - - @Test - public void check_ignores_NodeHealth_arg_and_returns_RED_with_cause_if_an_exception_occurs_checking_ES_cluster_status() { - Set<NodeHealth> nodeHealths = ImmutableSet.of(newNodeHealth(NodeHealth.Status.GREEN)); - when(esClient.prepareClusterStats()).thenThrow(new RuntimeException("Faking an exception occurring while using the EsClient")); - - Health health = new EsStatusClusterCheck(esClient).check(nodeHealths); - - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("Elasticsearch status is RED (unavailable)"); - } - - @Test - public void check_ignores_NodeHealth_arg_and_returns_GREEN_without_cause_if_ES_cluster_status_is_GREEN() { - Set<NodeHealth> nodeHealths = ImmutableSet.of(newNodeHealth(NodeHealth.Status.YELLOW)); - when(esClient.prepareClusterStats().get().getStatus()).thenReturn(ClusterHealthStatus.GREEN); - - Health health = underTest.check(nodeHealths); - - assertThat(health).isEqualTo(Health.GREEN); - } - - private NodeHealth newNodeHealth(NodeHealth.Status status) { - return NodeHealth.newNodeHealthBuilder() - .setStatus(status) - .setDetails(NodeDetails.newNodeDetailsBuilder() - .setType(random.nextBoolean() ? NodeDetails.Type.APPLICATION : NodeDetails.Type.SEARCH) - .setName(randomAlphanumeric(23)) - .setHost(randomAlphanumeric(23)) - .setPort(1 + random.nextInt(96)) - .setStartedAt(1 + random.nextInt(966)) - .build()) - .build(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusNodeCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusNodeCheckTest.java deleted file mode 100644 index 58d9e8a1cf6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/EsStatusNodeCheckTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import org.elasticsearch.cluster.health.ClusterHealthStatus; -import org.junit.Test; -import org.mockito.Mockito; -import org.sonar.server.es.EsClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class EsStatusNodeCheckTest { - - private EsClient esClient = mock(EsClient.class, Mockito.RETURNS_DEEP_STUBS); - private EsStatusNodeCheck underTest = new EsStatusNodeCheck(esClient); - - @Test - public void check_ignores_NodeHealth_arg_and_returns_RED_with_cause_if_an_exception_occurs_checking_ES_cluster_status() { - EsClient esClient = mock(EsClient.class); - when(esClient.prepareClusterStats()).thenThrow(new RuntimeException("Faking an exception occurring while using the EsClient")); - - Health health = new EsStatusNodeCheck(esClient).check(); - - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("Elasticsearch status is RED (unavailable)"); - } - - @Test - public void check_returns_GREEN_without_cause_if_ES_cluster_status_is_GREEN() { - when(esClient.prepareClusterStats().get().getStatus()).thenReturn(ClusterHealthStatus.GREEN); - - Health health = underTest.check(); - - assertThat(health).isEqualTo(Health.GREEN); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/HealthAssert.java b/server/sonar-server/src/test/java/org/sonar/server/health/HealthAssert.java deleted file mode 100644 index ec8e06598f4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/HealthAssert.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import com.google.common.collect.ImmutableList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.assertj.core.api.AbstractAssert; -import org.sonar.process.cluster.health.NodeHealth; - -final class HealthAssert extends AbstractAssert<HealthAssert, Health> { - private Set<NodeHealth> nodeHealths; - - private HealthAssert(Health actual) { - super(actual, HealthAssert.class); - } - - public static HealthAssert assertThat(Health actual) { - return new HealthAssert(actual); - } - - public HealthAssert forInput(Set<NodeHealth> nodeHealths) { - this.nodeHealths = nodeHealths; - - return this; - } - - public HealthAssert hasStatus(Health.Status expected) { - isNotNull(); - - if (actual.getStatus() != expected) { - failWithMessage( - "Expected Status of Health to be <%s> but was <%s> for NodeHealth \n%s", - expected, - actual.getStatus(), - printStatusesAndTypes(this.nodeHealths)); - } - - return this; - } - - public HealthAssert andCauses(String... causes) { - isNotNull(); - - if (!checkCauses(causes)) { - failWithMessage( - "Expected causes of Health to contain only \n%s\n but was \n%s\n for NodeHealth \n%s", - Arrays.asList(causes), - actual.getCauses(), - printStatusesAndTypes(this.nodeHealths)); - } - - return this; - } - - private String printStatusesAndTypes(@Nullable Set<NodeHealth> nodeHealths) { - if (nodeHealths == null) { - return "<null>"; - } - return nodeHealths.stream() - // sort by type then status for debugging convenience - .sorted(Comparator.<NodeHealth>comparingInt(s1 -> s1.getDetails().getType().ordinal()) - .thenComparingInt(s -> s.getStatus().ordinal())) - .map(s -> ImmutableList.of(s.getDetails().getType().name(), s.getStatus().name())) - .map(String::valueOf) - .collect(Collectors.joining(",")); - } - - private boolean checkCauses(String... causes) { - if (causes.length != this.actual.getCauses().size()) { - return false; - } - return Objects.equals(new HashSet<>(Arrays.asList(causes)), this.actual.getCauses()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/HealthCheckerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/HealthCheckerImplTest.java deleted file mode 100644 index 84893a43792..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/HealthCheckerImplTest.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.process.cluster.health.NodeDetails; -import org.sonar.process.cluster.health.NodeHealth; -import org.sonar.process.cluster.health.SharedHealthState; -import org.sonar.server.platform.WebServer; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.process.cluster.health.NodeDetails.newNodeDetailsBuilder; -import static org.sonar.process.cluster.health.NodeHealth.newNodeHealthBuilder; -import static org.sonar.server.health.Health.newHealthCheckBuilder; -import static org.sonar.server.health.Health.Status.GREEN; -import static org.sonar.server.health.Health.Status.RED; -import static org.sonar.server.health.Health.Status.YELLOW; - -public class HealthCheckerImplTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private final WebServer webServer = mock(WebServer.class); - private final SharedHealthState sharedHealthState = mock(SharedHealthState.class); - private final Random random = new Random(); - - @Test - public void check_returns_green_status_without_any_cause_when_there_is_no_NodeHealthCheck() { - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0]); - - assertThat(underTest.checkNode()).isEqualTo(Health.GREEN); - } - - @Test - public void checkNode_returns_GREEN_status_if_only_GREEN_statuses_returned_by_NodeHealthCheck() { - List<Health.Status> statuses = IntStream.range(1, 1 + random.nextInt(20)).mapToObj(i -> GREEN).collect(Collectors.toList()); - HealthCheckerImpl underTest = newNodeHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkNode().getStatus()) - .describedAs("%s should have been computed from %s statuses", GREEN, statuses) - .isEqualTo(GREEN); - } - - @Test - public void checkNode_returns_YELLOW_status_if_only_GREEN_and_at_least_one_YELLOW_statuses_returned_by_NodeHealthCheck() { - List<Health.Status> statuses = new ArrayList<>(); - Stream.concat( - IntStream.range(0, 1 + random.nextInt(20)).mapToObj(i -> YELLOW), // at least 1 YELLOW - IntStream.range(0, random.nextInt(20)).mapToObj(i -> GREEN)).forEach(statuses::add); // between 0 and 19 GREEN - Collections.shuffle(statuses); - HealthCheckerImpl underTest = newNodeHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkNode().getStatus()) - .describedAs("%s should have been computed from %s statuses", YELLOW, statuses) - .isEqualTo(YELLOW); - } - - @Test - public void checkNode_returns_RED_status_if_at_least_one_RED_status_returned_by_NodeHealthCheck() { - List<Health.Status> statuses = new ArrayList<>(); - Stream.of( - IntStream.range(0, 1 + random.nextInt(20)).mapToObj(i -> RED), // at least 1 RED - IntStream.range(0, random.nextInt(20)).mapToObj(i -> YELLOW), // between 0 and 19 YELLOW - IntStream.range(0, random.nextInt(20)).mapToObj(i -> GREEN) // between 0 and 19 GREEN - ).flatMap(s -> s) - .forEach(statuses::add); - Collections.shuffle(statuses); - HealthCheckerImpl underTest = newNodeHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkNode().getStatus()) - .describedAs("%s should have been computed from %s statuses", RED, statuses) - .isEqualTo(RED); - } - - @Test - public void checkNode_returns_causes_of_all_NodeHealthCheck_whichever_their_status() { - NodeHealthCheck[] nodeHealthChecks = IntStream.range(0, 1 + random.nextInt(20)) - .mapToObj(s -> new HardcodedHealthNodeCheck(IntStream.range(0, random.nextInt(3)).mapToObj(i -> randomAlphanumeric(3)).toArray(String[]::new))) - .map(NodeHealthCheck.class::cast) - .toArray(NodeHealthCheck[]::new); - String[] expected = Arrays.stream(nodeHealthChecks).map(NodeHealthCheck::check).flatMap(s -> s.getCauses().stream()).toArray(String[]::new); - - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, nodeHealthChecks); - - assertThat(underTest.checkNode().getCauses()).containsOnly(expected); - } - - @Test - public void checkCluster_fails_with_ISE_in_standalone() { - when(webServer.isStandalone()).thenReturn(true); - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], new ClusterHealthCheck[0], sharedHealthState); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Clustering is not enabled"); - - underTest.checkCluster(); - } - - @Test - public void checkCluster_fails_with_ISE_in_clustering_and_HealthState_is_null() { - when(webServer.isStandalone()).thenReturn(false); - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], new ClusterHealthCheck[0], null); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("HealthState instance can't be null when clustering is enabled"); - - underTest.checkCluster(); - } - - @Test - public void checkCluster_returns_GREEN_when_there_is_no_ClusterHealthCheck() { - when(webServer.isStandalone()).thenReturn(false); - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], new ClusterHealthCheck[0], sharedHealthState); - - assertThat(underTest.checkCluster().getHealth()).isEqualTo(Health.GREEN); - } - - @Test - public void checkCluster_returns_GREEN_status_if_only_GREEN_statuses_returned_by_ClusterHealthChecks() { - when(webServer.isStandalone()).thenReturn(false); - List<Health.Status> statuses = IntStream.range(1, 1 + random.nextInt(20)).mapToObj(i -> GREEN).collect(Collectors.toList()); - HealthCheckerImpl underTest = newClusterHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkCluster().getHealth().getStatus()) - .describedAs("%s should have been computed from %s statuses", GREEN, statuses) - .isEqualTo(GREEN); - } - - @Test - public void checkCluster_returns_YELLOW_status_if_only_GREEN_and_at_least_one_YELLOW_statuses_returned_by_ClusterHealthChecks() { - when(webServer.isStandalone()).thenReturn(false); - List<Health.Status> statuses = new ArrayList<>(); - Stream.concat( - IntStream.range(0, 1 + random.nextInt(20)).mapToObj(i -> YELLOW), // at least 1 YELLOW - IntStream.range(0, random.nextInt(20)).mapToObj(i -> GREEN)).forEach(statuses::add); // between 0 and 19 GREEN - Collections.shuffle(statuses); - HealthCheckerImpl underTest = newClusterHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkCluster().getHealth().getStatus()) - .describedAs("%s should have been computed from %s statuses", YELLOW, statuses) - .isEqualTo(YELLOW); - } - - @Test - public void checkCluster_returns_RED_status_if_at_least_one_RED_status_returned_by_ClusterHealthChecks() { - when(webServer.isStandalone()).thenReturn(false); - List<Health.Status> statuses = new ArrayList<>(); - Stream.of( - IntStream.range(0, 1 + random.nextInt(20)).mapToObj(i -> RED), // at least 1 RED - IntStream.range(0, random.nextInt(20)).mapToObj(i -> YELLOW), // between 0 and 19 YELLOW - IntStream.range(0, random.nextInt(20)).mapToObj(i -> GREEN) // between 0 and 19 GREEN - ).flatMap(s -> s) - .forEach(statuses::add); - Collections.shuffle(statuses); - HealthCheckerImpl underTest = newClusterHealthCheckerImpl(statuses.stream()); - - assertThat(underTest.checkCluster().getHealth().getStatus()) - .describedAs("%s should have been computed from %s statuses", RED, statuses) - .isEqualTo(RED); - } - - @Test - public void checkCluster_returns_causes_of_all_ClusterHealthChecks_whichever_their_status() { - when(webServer.isStandalone()).thenReturn(false); - List<String[]> causesGroups = IntStream.range(0, 1 + random.nextInt(20)) - .mapToObj(s -> IntStream.range(0, random.nextInt(3)).mapToObj(i -> randomAlphanumeric(3)).toArray(String[]::new)) - .collect(Collectors.toList()); - ClusterHealthCheck[] clusterHealthChecks = causesGroups.stream() - .map(HardcodedHealthClusterCheck::new) - .map(ClusterHealthCheck.class::cast) - .toArray(ClusterHealthCheck[]::new); - String[] expectedCauses = causesGroups.stream().flatMap(Arrays::stream).collect(Collectors.toSet()).stream().toArray(String[]::new); - - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], clusterHealthChecks, sharedHealthState); - - assertThat(underTest.checkCluster().getHealth().getCauses()).containsOnly(expectedCauses); - } - - @Test - public void checkCluster_passes_set_of_NodeHealth_returns_by_HealthState_to_all_ClusterHealthChecks() { - when(webServer.isStandalone()).thenReturn(false); - ClusterHealthCheck[] mockedClusterHealthChecks = IntStream.range(0, 1 + random.nextInt(3)) - .mapToObj(i -> mock(ClusterHealthCheck.class)) - .toArray(ClusterHealthCheck[]::new); - Set<NodeHealth> nodeHealths = IntStream.range(0, 1 + random.nextInt(4)).mapToObj(i -> randomNodeHealth()).collect(Collectors.toSet()); - when(sharedHealthState.readAll()).thenReturn(nodeHealths); - for (ClusterHealthCheck mockedClusterHealthCheck : mockedClusterHealthChecks) { - when(mockedClusterHealthCheck.check(same(nodeHealths))).thenReturn(Health.GREEN); - } - - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], mockedClusterHealthChecks, sharedHealthState); - underTest.checkCluster(); - - for (ClusterHealthCheck mockedClusterHealthCheck : mockedClusterHealthChecks) { - verify(mockedClusterHealthCheck).check(same(nodeHealths)); - } - } - - @Test - public void checkCluster_returns_NodeHealths_returned_by_HealthState() { - when(webServer.isStandalone()).thenReturn(false); - Set<NodeHealth> nodeHealths = IntStream.range(0, 1 + random.nextInt(4)).mapToObj(i -> randomNodeHealth()).collect(Collectors.toSet()); - when(sharedHealthState.readAll()).thenReturn(nodeHealths); - - HealthCheckerImpl underTest = new HealthCheckerImpl(webServer, new NodeHealthCheck[0], new ClusterHealthCheck[0], sharedHealthState); - - ClusterHealth clusterHealth = underTest.checkCluster(); - assertThat(clusterHealth.getNodes()).isEqualTo(nodeHealths); - } - - private NodeHealth randomNodeHealth() { - return newNodeHealthBuilder() - .setStatus(NodeHealth.Status.values()[random.nextInt(NodeHealth.Status.values().length)]) - .setDetails(newNodeDetailsBuilder() - .setType(random.nextBoolean() ? NodeDetails.Type.APPLICATION : NodeDetails.Type.SEARCH) - .setName(randomAlphanumeric(10)) - .setHost(randomAlphanumeric(5)) - .setPort(1 + random.nextInt(333)) - .setStartedAt(1 + random.nextInt(444)) - .build()) - .build(); - } - - private HealthCheckerImpl newNodeHealthCheckerImpl(Stream<Health.Status> statuses) { - Stream<HardcodedHealthNodeCheck> staticHealthCheckStream = statuses.map(HardcodedHealthNodeCheck::new); - return new HealthCheckerImpl( - webServer, - staticHealthCheckStream.map(NodeHealthCheck.class::cast).toArray(NodeHealthCheck[]::new)); - } - - private HealthCheckerImpl newClusterHealthCheckerImpl(Stream<Health.Status> statuses) { - Stream<HardcodedHealthClusterCheck> staticHealthCheckStream = statuses.map(HardcodedHealthClusterCheck::new); - return new HealthCheckerImpl( - webServer, - new NodeHealthCheck[0], - staticHealthCheckStream.map(ClusterHealthCheck.class::cast).toArray(ClusterHealthCheck[]::new), - sharedHealthState); - } - - private class HardcodedHealthNodeCheck implements NodeHealthCheck { - private final Health health; - - public HardcodedHealthNodeCheck(Health.Status status) { - this.health = newHealthCheckBuilder().setStatus(status).build(); - } - - public HardcodedHealthNodeCheck(String... causes) { - Health.Builder builder = newHealthCheckBuilder().setStatus(Health.Status.values()[random.nextInt(3)]); - Stream.of(causes).forEach(builder::addCause); - this.health = builder.build(); - } - - @Override - public Health check() { - return health; - } - } - - private class HardcodedHealthClusterCheck implements ClusterHealthCheck { - private final Health health; - - public HardcodedHealthClusterCheck(Health.Status status) { - this.health = newHealthCheckBuilder().setStatus(status).build(); - } - - public HardcodedHealthClusterCheck(String... causes) { - Health.Builder builder = newHealthCheckBuilder().setStatus(Health.Status.values()[random.nextInt(3)]); - Stream.of(causes).forEach(builder::addCause); - this.health = builder.build(); - } - - @Override - public Health check(Set<NodeHealth> nodeHealths) { - return health; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/HealthTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/HealthTest.java deleted file mode 100644 index 00452fc0fc5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/HealthTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import com.google.common.base.Strings; -import java.util.Random; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.assertj.core.api.AbstractCharSequenceAssert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.health.Health.newHealthCheckBuilder; - -public class HealthTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private final Random random = new Random(); - private final Health.Status anyStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)]; - private final Set<String> randomCauses = IntStream.range(0, random.nextInt(5)).mapToObj(s -> randomAlphanumeric(3)).collect(Collectors.toSet()); - - @Test - public void build_throws_NPE_if_status_is_null() { - Health.Builder builder = newHealthCheckBuilder(); - - expectStatusNotNullNPE(); - - builder.build(); - } - - @Test - public void setStatus_throws_NPE_if_status_is_null() { - Health.Builder builder = newHealthCheckBuilder(); - - expectStatusNotNullNPE(); - - builder.setStatus(null); - } - - @Test - public void getStatus_returns_status_from_builder() { - Health underTest = newHealthCheckBuilder().setStatus(anyStatus).build(); - - assertThat(underTest.getStatus()).isEqualTo(anyStatus); - } - - @Test - public void addCause_throws_NPE_if_arg_is_null() { - Health.Builder builder = newHealthCheckBuilder(); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("cause can't be null"); - - builder.addCause(null); - } - - @Test - public void addCause_throws_IAE_if_arg_is_empty() { - Health.Builder builder = newHealthCheckBuilder(); - - expectCauseCannotBeEmptyIAE(); - - builder.addCause(""); - } - - @Test - public void addCause_throws_IAE_if_arg_contains_only_spaces() { - Health.Builder builder = newHealthCheckBuilder(); - - expectCauseCannotBeEmptyIAE(); - - builder.addCause(Strings.repeat(" ", 1 + random.nextInt(5))); - } - - @Test - public void getCause_returns_causes_from_builder() { - Health.Builder builder = newHealthCheckBuilder().setStatus(anyStatus); - randomCauses.forEach(builder::addCause); - Health underTest = builder.build(); - - assertThat(underTest.getCauses()) - .isEqualTo(randomCauses); - } - - @Test - public void green_constant() { - assertThat(Health.GREEN).isEqualTo(newHealthCheckBuilder().setStatus(Health.Status.GREEN).build()); - } - - @Test - public void equals_is_based_on_status_and_causes() { - Health.Builder builder1 = newHealthCheckBuilder(); - Health.Builder builder2 = newHealthCheckBuilder(); - - builder1.setStatus(anyStatus); - builder2.setStatus(anyStatus); - randomCauses.forEach(s -> { - builder1.addCause(s); - builder2.addCause(s); - }); - - assertThat(builder1.build()) - .isEqualTo(builder1.build()) - .isEqualTo(builder2.build()) - .isEqualTo(builder2.build()); - } - - @Test - public void not_equals_to_null_nor_other_type() { - assertThat(Health.GREEN).isNotEqualTo(null); - assertThat(Health.GREEN).isNotEqualTo(new Object()); - assertThat(Health.GREEN).isNotEqualTo(Health.Status.GREEN); - } - - @Test - public void hashcode_is_based_on_status_and_causes() { - Health.Builder builder1 = newHealthCheckBuilder(); - Health.Builder builder2 = newHealthCheckBuilder(); - builder1.setStatus(anyStatus); - builder2.setStatus(anyStatus); - randomCauses.forEach(s -> { - builder1.addCause(s); - builder2.addCause(s); - }); - - assertThat(builder1.build().hashCode()) - .isEqualTo(builder1.build().hashCode()) - .isEqualTo(builder2.build().hashCode()) - .isEqualTo(builder2.build().hashCode()); - } - - @Test - public void verify_toString() { - assertThat(Health.GREEN.toString()).isEqualTo("Health{GREEN, causes=[]}"); - Health.Builder builder = newHealthCheckBuilder().setStatus(anyStatus); - randomCauses.forEach(builder::addCause); - - String underTest = builder.build().toString(); - - AbstractCharSequenceAssert<?, String> a = assertThat(underTest) - .describedAs("toString for status %s and causes %s", anyStatus, randomCauses); - if (randomCauses.isEmpty()) { - a.isEqualTo("Health{" + anyStatus + ", causes=[]}"); - } else if (randomCauses.size() == 1) { - a.isEqualTo("Health{" + anyStatus + ", causes=[" + randomCauses.iterator().next() + "]}"); - } else { - a.startsWith("Health{" + anyStatus + ", causes=[") - .endsWith("]}") - .contains(randomCauses); - } - } - - private void expectStatusNotNullNPE() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("status can't be null"); - } - - private void expectCauseCannotBeEmptyIAE() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("cause can't be empty"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthModuleTest.java deleted file mode 100644 index 4e278877bad..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthModuleTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; -import org.junit.Test; -import org.picocontainer.ComponentAdapter; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.platform.Server; -import org.sonar.api.utils.System2; -import org.sonar.core.platform.ComponentContainer; -import org.sonar.process.NetworkUtils; -import org.sonar.process.cluster.health.SharedHealthStateImpl; -import org.sonar.process.cluster.hz.HazelcastMember; - -import static java.lang.String.valueOf; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class NodeHealthModuleTest { - private Random random = new Random(); - private MapSettings mapSettings = new MapSettings(); - private NodeHealthModule underTest = new NodeHealthModule(); - - @Test - public void no_broken_dependencies() { - ComponentContainer container = new ComponentContainer(); - Server server = mock(Server.class); - NetworkUtils networkUtils = mock(NetworkUtils.class); - // settings required by NodeHealthProvider - mapSettings.setProperty("sonar.cluster.node.name", randomAlphanumeric(3)); - mapSettings.setProperty("sonar.cluster.node.port", valueOf(1 + random.nextInt(10))); - when(server.getStartedAt()).thenReturn(new Date()); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(12)); - // upper level dependencies - container.add( - mock(System2.class), - mapSettings.asConfig(), - server, - networkUtils, - mock(HazelcastMember.class)); - // HealthAction dependencies - container.add(mock(HealthChecker.class)); - - underTest.configure(container); - - container.startComponents(); - } - - @Test - public void provides_implementation_of_SharedHealthState() { - ComponentContainer container = new ComponentContainer(); - - underTest.configure(container); - - assertThat(classesAddedToContainer(container)) - .contains(SharedHealthStateImpl.class); - } - - private List<Class<?>> classesAddedToContainer(ComponentContainer container) { - Collection<ComponentAdapter<?>> componentAdapters = container.getPicoContainer().getComponentAdapters(); - return componentAdapters.stream().map(ComponentAdapter::getComponentImplementation).collect(Collectors.toList()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthProviderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthProviderImplTest.java deleted file mode 100644 index 72366851eb6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthProviderImplTest.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.Arrays; -import java.util.Date; -import java.util.Random; -import java.util.stream.IntStream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.platform.Server; -import org.sonar.process.NetworkUtils; -import org.sonar.process.cluster.health.NodeDetails; -import org.sonar.process.cluster.health.NodeHealth; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST; -import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME; -import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HZ_PORT; - -public class NodeHealthProviderImplTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private final Random random = new Random(); - private MapSettings mapSettings = new MapSettings(); - private HealthChecker healthChecker = mock(HealthChecker.class); - private Server server = mock(Server.class); - private NetworkUtils networkUtils = mock(NetworkUtils.class); - - @Test - public void constructor_throws_ISE_if_node_name_property_is_not_set() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Property sonar.cluster.node.name is not defined"); - - new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - } - - @Test - public void constructor_thows_NPE_if_NetworkUtils_getHostname_returns_null() { - mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3)); - - expectedException.expect(NullPointerException.class); - - new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - } - - @Test - public void constructor_throws_ISE_if_node_port_property_is_not_set() { - mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3)); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(23)); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Property sonar.cluster.node.port is not defined"); - - new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - } - - @Test - public void constructor_throws_NPE_is_Server_getStartedAt_is_null() { - setRequiredPropertiesForConstructor(); - - expectedException.expect(NullPointerException.class); - - new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - } - - @Test - public void get_returns_HEALTH_status_and_causes_from_HealthChecker_checkNode() { - setRequiredPropertiesForConstructor(); - setStartedAt(); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(4)); - Health.Status randomStatus = Health.Status.values()[random.nextInt(Health.Status.values().length)]; - String[] expected = IntStream.range(0, random.nextInt(4)).mapToObj(s -> randomAlphabetic(55)).toArray(String[]::new); - Health.Builder healthBuilder = Health.newHealthCheckBuilder() - .setStatus(randomStatus); - Arrays.stream(expected).forEach(healthBuilder::addCause); - when(healthChecker.checkNode()).thenReturn(healthBuilder.build()); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getStatus().name()).isEqualTo(randomStatus.name()); - assertThat(nodeHealth.getCauses()).containsOnly(expected); - } - - @Test - public void get_returns_APPLICATION_type() { - setRequiredPropertiesForConstructor(); - setStartedAt(); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(23)); - when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder() - .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) - .build()); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getDetails().getType()).isEqualTo(NodeDetails.Type.APPLICATION); - } - - @Test - public void get_returns_name_and_port_from_properties_at_constructor_time() { - String name = randomAlphanumeric(3); - int port = 1 + random.nextInt(4); - mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), name); - mapSettings.setProperty(CLUSTER_NODE_HZ_PORT.getKey(), port); - setStartedAt(); - when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder() - .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) - .build()); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(3)); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getDetails().getName()).isEqualTo(name); - assertThat(nodeHealth.getDetails().getPort()).isEqualTo(port); - - // change values in properties - setRequiredPropertiesForConstructor(); - - NodeHealth newNodeHealth = underTest.get(); - - assertThat(newNodeHealth.getDetails().getName()).isEqualTo(name); - assertThat(newNodeHealth.getDetails().getPort()).isEqualTo(port); - } - - @Test - public void get_returns_host_from_property_if_set_at_constructor_time() { - String host = randomAlphanumeric(4); - mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3)); - mapSettings.setProperty(CLUSTER_NODE_HZ_PORT.getKey(), 1 + random.nextInt(4)); - mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), host); - setStartedAt(); - when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder() - .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) - .build()); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getDetails().getHost()).isEqualTo(host); - - // change values in properties - mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), randomAlphanumeric(66)); - - NodeHealth newNodeHealth = underTest.get(); - - assertThat(newNodeHealth.getDetails().getHost()).isEqualTo(host); - } - - @Test - public void get_returns_hostname_from_NetworkUtils_if_property_is_not_set_at_constructor_time() { - getReturnsHostnameFromNetworkUtils(null); - } - - @Test - public void get_returns_hostname_from_NetworkUtils_if_property_is_empty_at_constructor_time() { - getReturnsHostnameFromNetworkUtils(random.nextBoolean() ? "" : " "); - } - - private void getReturnsHostnameFromNetworkUtils(String hostPropertyValue) { - String host = randomAlphanumeric(3); - setRequiredPropertiesForConstructor(); - if (hostPropertyValue != null) { - mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), hostPropertyValue); - } - setStartedAt(); - when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder() - .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) - .build()); - when(networkUtils.getHostname()).thenReturn(host); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getDetails().getHost()).isEqualTo(host); - - // change hostname - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(4)); - - NodeHealth newNodeHealth = underTest.get(); - - assertThat(newNodeHealth.getDetails().getHost()).isEqualTo(host); - } - - @Test - public void get_returns_started_from_server_startedAt_at_constructor_time() { - setRequiredPropertiesForConstructor(); - when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(4)); - Date date = new Date(); - when(server.getStartedAt()).thenReturn(date); - when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder() - .setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)]) - .build()); - NodeHealthProviderImpl underTest = new NodeHealthProviderImpl(mapSettings.asConfig(), healthChecker, server, networkUtils); - - NodeHealth nodeHealth = underTest.get(); - - assertThat(nodeHealth.getDetails().getStartedAt()).isEqualTo(date.getTime()); - - // change startedAt value - setStartedAt(); - - NodeHealth newNodeHealth = underTest.get(); - - assertThat(newNodeHealth.getDetails().getStartedAt()).isEqualTo(date.getTime()); - } - - private void setStartedAt() { - when(server.getStartedAt()).thenReturn(new Date()); - } - - private void setRequiredPropertiesForConstructor() { - mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3)); - mapSettings.setProperty(CLUSTER_NODE_HZ_PORT.getKey(), 1 + random.nextInt(4)); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/TestStandaloneHealthChecker.java b/server/sonar-server/src/test/java/org/sonar/server/health/TestStandaloneHealthChecker.java deleted file mode 100644 index 27c2e469dde..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/TestStandaloneHealthChecker.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -public class TestStandaloneHealthChecker implements HealthChecker { - - private Health health = Health.newHealthCheckBuilder().setStatus(Health.Status.GREEN).build(); - - public void setHealth(Health h) { - this.health = h; - } - - @Override - public Health checkNode() { - return health; - } - - @Override - public ClusterHealth checkCluster() { - throw new IllegalStateException(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/WebServerSafemodeNodeCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/WebServerSafemodeNodeCheckTest.java deleted file mode 100644 index a18121e0213..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/WebServerSafemodeNodeCheckTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class WebServerSafemodeNodeCheckTest { - private WebServerSafemodeNodeCheck underTest = new WebServerSafemodeNodeCheck(); - - @Test - public void always_returns_RED_status_with_cause() { - Health health = underTest.check(); - - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("SonarQube webserver is not up"); - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/health/WebServerStatusNodeCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/health/WebServerStatusNodeCheckTest.java deleted file mode 100644 index 05977854180..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/health/WebServerStatusNodeCheckTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.health; - -import java.util.Arrays; -import java.util.Random; -import org.junit.Test; -import org.sonar.server.app.RestartFlagHolder; -import org.sonar.server.platform.Platform; -import org.sonar.server.platform.db.migration.DatabaseMigrationState; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WebServerStatusNodeCheckTest { - private final DatabaseMigrationState migrationState = mock(DatabaseMigrationState.class); - private final Platform platform = mock(Platform.class); - private final RestartFlagHolder restartFlagHolder = mock(RestartFlagHolder.class); - - private final Random random = new Random(); - - private WebServerStatusNodeCheck underTest = new WebServerStatusNodeCheck(migrationState, platform, restartFlagHolder); - - @Test - public void returns_RED_status_with_cause_if_platform_status_is_not_UP() { - Platform.Status[] statusesButUp = Arrays.stream(Platform.Status.values()) - .filter(s -> s != Platform.Status.UP) - .toArray(Platform.Status[]::new); - Platform.Status randomStatusButUp = statusesButUp[random.nextInt(statusesButUp.length)]; - when(platform.status()).thenReturn(randomStatusButUp); - - Health health = underTest.check(); - - verifyRedHealthWithCause(health); - } - - @Test - public void returns_RED_status_with_cause_if_platform_status_is_UP_but_migrationStatus_is_neither_NONE_nor_SUCCEED() { - when(platform.status()).thenReturn(Platform.Status.UP); - DatabaseMigrationState.Status[] statusesButValidOnes = Arrays.stream(DatabaseMigrationState.Status.values()) - .filter(s -> s != DatabaseMigrationState.Status.NONE) - .filter(s -> s != DatabaseMigrationState.Status.SUCCEEDED) - .toArray(DatabaseMigrationState.Status[]::new); - DatabaseMigrationState.Status randomInvalidStatus = statusesButValidOnes[random.nextInt(statusesButValidOnes.length)]; - when(migrationState.getStatus()).thenReturn(randomInvalidStatus); - - Health health = underTest.check(); - - verifyRedHealthWithCause(health); - } - - @Test - public void returns_RED_with_cause_if_platform_status_is_UP_migration_status_is_valid_but_SQ_is_restarting() { - when(platform.status()).thenReturn(Platform.Status.UP); - when(migrationState.getStatus()).thenReturn(random.nextBoolean() ? DatabaseMigrationState.Status.NONE : DatabaseMigrationState.Status.SUCCEEDED); - when(restartFlagHolder.isRestarting()).thenReturn(true); - - Health health = underTest.check(); - - verifyRedHealthWithCause(health); - } - - @Test - public void returns_GREEN_without_cause_if_platform_status_is_UP_migration_status_is_valid_and_SQ_is_not_restarting() { - when(platform.status()).thenReturn(Platform.Status.UP); - when(migrationState.getStatus()).thenReturn(random.nextBoolean() ? DatabaseMigrationState.Status.NONE : DatabaseMigrationState.Status.SUCCEEDED); - when(restartFlagHolder.isRestarting()).thenReturn(false); - - Health health = underTest.check(); - - assertThat(health).isEqualTo(Health.GREEN); - } - - private void verifyRedHealthWithCause(Health health) { - assertThat(health.getStatus()).isEqualTo(Health.Status.RED); - assertThat(health.getCauses()).containsOnly("SonarQube webserver is not up"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ActionTest.java deleted file mode 100644 index 16343e1a5ae..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ActionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import java.util.Collection; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.server.user.UserSession; - -public class ActionTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void key_should_not_be_empty() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Action key must be set"); - - new FakeAction(""); - } - - @Test - public void key_should_not_be_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Action key must be set"); - - new FakeAction(null); - } - - private static class FakeAction extends Action { - - FakeAction(String key) { - super(key); - } - - @Override - public boolean verify(Map<String, Object> properties, Collection<DefaultIssue> issues, UserSession userSession) { - return false; - } - - @Override - public boolean execute(Map<String, Object> properties, Context context) { - return false; - } - - @Override - public boolean shouldRefreshMeasures() { - return false; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/AddTagsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/AddTagsActionTest.java deleted file mode 100644 index fe6a79e456f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/AddTagsActionTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableSet; -import java.util.HashMap; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; -import org.sonar.core.issue.DefaultIssue; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AddTagsActionTest { - - @Rule - public ExpectedException throwable = ExpectedException.none(); - - private IssueFieldsSetter issueUpdater = new IssueFieldsSetter(); - private AddTagsAction underTest = new AddTagsAction(issueUpdater); - - @Test - @SuppressWarnings("unchecked") - public void should_execute() { - Map<String, Object> properties = new HashMap<>(); - properties.put("tags", "tag2,tag3"); - - DefaultIssue issue = mock(DefaultIssue.class); - when(issue.tags()).thenReturn(ImmutableSet.of("tag1", "tag3")); - - Action.Context context = mock(Action.Context.class, Mockito.RETURNS_DEEP_STUBS); - when(context.issue()).thenReturn(issue); - - underTest.execute(properties, context); - verify(issue).setTags(ImmutableSet.of("tag1", "tag2", "tag3")); - } - - @Test - public void should_fail_if_tag_is_not_valid() { - throwable.expect(IllegalArgumentException.class); - throwable.expectMessage("Tag 'th ag' is invalid. Rule tags accept only the characters: a-z, 0-9, '+', '-', '#', '.'"); - - Map<String, Object> properties = new HashMap<>(); - properties.put("tags", "th ag"); - - DefaultIssue issue = mock(DefaultIssue.class); - when(issue.tags()).thenReturn(ImmutableSet.of("tag1", "tag3")); - - Action.Context context = mock(Action.Context.class); - when(context.issue()).thenReturn(issue); - - underTest.execute(properties, context); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/AssignActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/AssignActionTest.java deleted file mode 100644 index cdfe07d39a4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/AssignActionTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableMap; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.issue.Issue; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.tester.UserSessionRule; - -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.rules.ExpectedException.none; -import static org.sonar.server.tester.UserSessionRule.standalone; - -public class AssignActionTest { - - private static final String ISSUE_CURRENT_ASSIGNEE_UUID = "current assignee uuid"; - - @Rule - public ExpectedException expectedException = none(); - - @Rule - public UserSessionRule userSession = standalone(); - - @Rule - public DbTester db = DbTester.create(); - - private IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), "user_uuid"); - private DefaultIssue issue = new DefaultIssue().setKey("ABC").setAssigneeUuid(ISSUE_CURRENT_ASSIGNEE_UUID); - private ComponentDto project; - private Action.Context context; - private OrganizationDto issueOrganizationDto; - - private AssignAction underTest = new AssignAction(db.getDbClient(), new IssueFieldsSetter()); - - @Before - public void setUp() throws Exception { - issueOrganizationDto = db.organizations().insert(); - project = db.components().insertPrivateProject(issueOrganizationDto); - context = new ActionContext(issue, issueChangeContext, project); - } - - @Test - public void assign_issue() { - UserDto assignee = db.users().insertUser("john"); - db.organizations().addMember(issueOrganizationDto, assignee); - Map<String, Object> properties = new HashMap<>(ImmutableMap.of("assignee", "john")); - - underTest.verify(properties, Collections.emptyList(), userSession); - boolean executeResult = underTest.execute(properties, context); - - assertThat(executeResult).isTrue(); - assertThat(issue.assignee()).isEqualTo(assignee.getUuid()); - } - - @Test - public void unassign_issue_if_assignee_is_empty() { - Map<String, Object> properties = new HashMap<>(ImmutableMap.of("assignee", "")); - - underTest.verify(properties, Collections.emptyList(), userSession); - boolean executeResult = underTest.execute(properties, context); - - assertThat(executeResult).isTrue(); - assertThat(issue.assignee()).isNull(); - } - - @Test - public void unassign_issue_if_assignee_is_null() { - Map<String, Object> properties = new HashMap<>(); - properties.put("assignee", null); - - underTest.verify(properties, Collections.emptyList(), userSession); - boolean executeResult = underTest.execute(properties, context); - - assertThat(executeResult).isTrue(); - assertThat(issue.assignee()).isNull(); - } - - @Test - public void does_not_assign_issue_when_assignee_is_not_member_of_project_issue_organization() { - OrganizationDto otherOrganizationDto = db.organizations().insert(); - UserDto assignee = db.users().insertUser("john"); - // User is not member of the organization of the issue - db.organizations().addMember(otherOrganizationDto, assignee); - Map<String, Object> properties = new HashMap<>(ImmutableMap.of("assignee", "john")); - - underTest.verify(properties, Collections.emptyList(), userSession); - boolean executeResult = underTest.execute(properties, context); - - assertThat(executeResult).isFalse(); - } - - @Test - public void fail_if_assignee_is_not_verified() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Assignee is missing from the execution parameters"); - - underTest.execute(emptyMap(), context); - } - - @Test - public void fail_if_assignee_does_not_exists() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Unknown user: arthur"); - - underTest.verify(ImmutableMap.of("assignee", "arthur"), singletonList(issue), userSession); - } - - @Test - public void fail_if_assignee_is_disabled() { - db.users().insertUser(user -> user.setLogin("arthur").setActive(false)); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Unknown user: arthur"); - - underTest.verify(new HashMap<>(ImmutableMap.of("assignee", "arthur")), singletonList(issue), userSession); - } - - @Test - public void support_only_unresolved_issues() { - assertThat(underTest.supports(new DefaultIssue().setResolution(null))).isTrue(); - assertThat(underTest.supports(new DefaultIssue().setResolution(Issue.RESOLUTION_FIXED))).isFalse(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/CommentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/CommentActionTest.java deleted file mode 100644 index 2e1d68afb1f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/CommentActionTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.Lists; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.issue.Issue; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.server.tester.AnonymousMockUserSession; - -import static com.google.common.collect.Maps.newHashMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class CommentActionTest { - - private CommentAction action; - - private IssueFieldsSetter issueUpdater = mock(IssueFieldsSetter.class); - - @Before - public void before() { - action = new CommentAction(issueUpdater); - } - - @Test - public void should_execute() { - String comment = "My bulk change comment"; - Map<String, Object> properties = newHashMap(); - properties.put("comment", comment); - DefaultIssue issue = mock(DefaultIssue.class); - - Action.Context context = mock(Action.Context.class); - when(context.issue()).thenReturn(issue); - - action.execute(properties, context); - verify(issueUpdater).addComment(eq(issue), eq(comment), any()); - } - - @Test - public void should_verify_fail_if_parameter_not_found() { - Map<String, Object> properties = newHashMap(); - properties.put("unknwown", "unknown value"); - try { - action.verify(properties, Lists.newArrayList(), new AnonymousMockUserSession()); - fail(); - } catch (Exception e) { - assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Missing parameter : 'comment'"); - } - verifyZeroInteractions(issueUpdater); - } - - @Test - public void should_support_all_issues() { - assertThat(action.supports(new DefaultIssue().setResolution(null))).isTrue(); - assertThat(action.supports(new DefaultIssue().setResolution(Issue.RESOLUTION_FIXED))).isTrue(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueFinderTest.java deleted file mode 100644 index 51f1566f9d0..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueFinderTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueDbTester; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.rule.RuleDbTester; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.issue.IssueTesting.newDto; -import static org.sonar.db.rule.RuleTesting.newRuleDto; - -public class IssueFinderTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private RuleDbTester ruleDbTester = new RuleDbTester(db); - private IssueDbTester issueDbTester = new IssueDbTester(db); - private ComponentDbTester componentDbTester = new ComponentDbTester(db); - - private IssueFinder underTest = new IssueFinder(db.getDbClient(), userSession); - - @Test - public void get_by_issue_key() { - IssueDto issueDto = insertIssue(); - String permission = USER; - addProjectPermission(issueDto, permission); - - IssueDto result = underTest.getByKey(db.getSession(), issueDto.getKey()); - - assertThat(result).isNotNull(); - assertThat(result.getKey()).isEqualTo(issueDto.getKey()); - } - - @Test - public void fail_when_issue_key_does_not_exist() { - IssueDto issueDto = insertIssue(); - addProjectPermission(issueDto, USER); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Issue with key 'UNKNOWN' does not exist"); - underTest.getByKey(db.getSession(), "UNKNOWN"); - } - - @Test - public void fail_when_not_enough_permission() { - IssueDto issueDto = insertIssue(); - addProjectPermission(issueDto, CODEVIEWER); - - expectedException.expect(ForbiddenException.class); - underTest.getByKey(db.getSession(), issueDto.getKey()); - } - - private IssueDto insertIssue() { - RuleDto rule = ruleDbTester.insertRule(newRuleDto()); - ComponentDto project = componentDbTester.insertPrivateProject(); - ComponentDto file = componentDbTester.insertComponent(newFileDto(project)); - return issueDbTester.insertIssue(newDto(rule, file, project)); - } - - private void addProjectPermission(IssueDto issueDto, String permission) { - userSession.addProjectPermission(permission, db.getDbClient().componentDao().selectByUuid(db.getSession(), issueDto.getProjectUuid()).get()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java deleted file mode 100644 index 7d7e2a4bb65..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import java.util.Date; -import java.util.List; -import org.apache.commons.lang.time.DateUtils; -import org.junit.Test; -import org.sonar.db.issue.IssueDto; -import org.sonar.server.issue.index.IssueQuery; - -import static com.google.common.collect.Lists.newArrayList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class IssuesFinderSortTest { - - @Test - public void should_sort_by_status() { - IssueDto issue1 = new IssueDto().setId(1L).setStatus("CLOSED"); - IssueDto issue2 = new IssueDto().setId(2L).setStatus("REOPENED"); - IssueDto issue3 = new IssueDto().setId(3L).setStatus("OPEN"); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_STATUS).asc(false).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getStatus()).isEqualTo("REOPENED"); - assertThat(result.get(1).getStatus()).isEqualTo("OPEN"); - assertThat(result.get(2).getStatus()).isEqualTo("CLOSED"); - } - - @Test - public void should_sort_by_severity() { - IssueDto issue1 = new IssueDto().setId(1L).setSeverity("INFO"); - IssueDto issue2 = new IssueDto().setId(2L).setSeverity("BLOCKER"); - IssueDto issue3 = new IssueDto().setId(3L).setSeverity("MAJOR"); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_SEVERITY).asc(true).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getSeverity()).isEqualTo("INFO"); - assertThat(result.get(1).getSeverity()).isEqualTo("MAJOR"); - assertThat(result.get(2).getSeverity()).isEqualTo("BLOCKER"); - } - - @Test - public void should_sort_by_desc_severity() { - IssueDto issue1 = new IssueDto().setId(1L).setSeverity("INFO"); - IssueDto issue2 = new IssueDto().setId(2L).setSeverity("BLOCKER"); - IssueDto issue3 = new IssueDto().setId(3L).setSeverity("MAJOR"); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_SEVERITY).asc(false).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getSeverity()).isEqualTo("BLOCKER"); - assertThat(result.get(1).getSeverity()).isEqualTo("MAJOR"); - assertThat(result.get(2).getSeverity()).isEqualTo("INFO"); - } - - @Test - public void should_sort_by_creation_date() { - Date date = new Date(); - Date date1 = DateUtils.addDays(date, -3); - Date date2 = DateUtils.addDays(date, -2); - Date date3 = DateUtils.addDays(date, -1); - IssueDto issue1 = new IssueDto().setId(1L).setIssueCreationDate(date1); - IssueDto issue2 = new IssueDto().setId(2L).setIssueCreationDate(date3); - IssueDto issue3 = new IssueDto().setId(3L).setIssueCreationDate(date2); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_CREATION_DATE).asc(false).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getIssueCreationDate()).isEqualTo(date3); - assertThat(result.get(1).getIssueCreationDate()).isEqualTo(date2); - assertThat(result.get(2).getIssueCreationDate()).isEqualTo(date1); - } - - @Test - public void should_sort_by_update_date() { - Date date = new Date(); - Date date1 = DateUtils.addDays(date, -3); - Date date2 = DateUtils.addDays(date, -2); - Date date3 = DateUtils.addDays(date, -1); - IssueDto issue1 = new IssueDto().setId(1L).setIssueUpdateDate(date1); - IssueDto issue2 = new IssueDto().setId(2L).setIssueUpdateDate(date3); - IssueDto issue3 = new IssueDto().setId(3L).setIssueUpdateDate(date2); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_UPDATE_DATE).asc(false).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getIssueUpdateDate()).isEqualTo(date3); - assertThat(result.get(1).getIssueUpdateDate()).isEqualTo(date2); - assertThat(result.get(2).getIssueUpdateDate()).isEqualTo(date1); - } - - @Test - public void should_sort_by_close_date() { - Date date = new Date(); - Date date1 = DateUtils.addDays(date, -3); - Date date2 = DateUtils.addDays(date, -2); - Date date3 = DateUtils.addDays(date, -1); - IssueDto issue1 = new IssueDto().setId(1L).setIssueCloseDate(date1); - IssueDto issue2 = new IssueDto().setId(2L).setIssueCloseDate(date3); - IssueDto issue3 = new IssueDto().setId(3L).setIssueCloseDate(date2); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.SORT_BY_CLOSE_DATE).asc(false).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(3); - assertThat(result.get(0).getIssueCloseDate()).isEqualTo(date3); - assertThat(result.get(1).getIssueCloseDate()).isEqualTo(date2); - assertThat(result.get(2).getIssueCloseDate()).isEqualTo(date1); - } - - @Test - public void should_not_sort_with_null_sort() { - IssueDto issue1 = new IssueDto().setId(1L).setAssigneeUuid("perceval"); - IssueDto issue2 = new IssueDto().setId(2L).setAssigneeUuid("arthur"); - IssueDto issue3 = new IssueDto().setId(3L).setAssigneeUuid("vincent"); - IssueDto issue4 = new IssueDto().setId(4L).setAssigneeUuid(null); - List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3, issue4); - - IssueQuery query = IssueQuery.builder().sort(null).build(); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); - - List<IssueDto> result = newArrayList(issuesFinderSort.sort()); - - assertThat(result).hasSize(4); - assertThat(result.get(0).getAssigneeUuid()).isEqualTo("perceval"); - assertThat(result.get(1).getAssigneeUuid()).isEqualTo("arthur"); - assertThat(result.get(2).getAssigneeUuid()).isEqualTo("vincent"); - assertThat(result.get(3).getAssigneeUuid()).isNull(); - } - - @Test - public void should_fail_to_sort_with_unknown_sort() { - IssueQuery query = mock(IssueQuery.class); - when(query.sort()).thenReturn("unknown"); - IssuesFinderSort issuesFinderSort = new IssuesFinderSort(null, query); - try { - issuesFinderSort.sort(); - } catch (Exception e) { - assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Cannot sort on field : unknown"); - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/RemoveTagsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/RemoveTagsActionTest.java deleted file mode 100644 index 9ad3bc3d751..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/RemoveTagsActionTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableSet; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; -import org.sonar.core.issue.DefaultIssue; - -import static com.google.common.collect.Maps.newHashMap; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class RemoveTagsActionTest { - - @Rule - public ExpectedException throwable = ExpectedException.none(); - - private IssueFieldsSetter issueUpdater = new IssueFieldsSetter(); - private RemoveTagsAction action = new RemoveTagsAction(issueUpdater); - - @Test - @SuppressWarnings("unchecked") - public void should_execute() { - Map<String, Object> properties = newHashMap(); - properties.put("tags", "tag2,tag3"); - - DefaultIssue issue = mock(DefaultIssue.class); - when(issue.tags()).thenReturn(ImmutableSet.of("tag1", "tag3")); - - Action.Context context = mock(Action.Context.class, Mockito.RETURNS_DEEP_STUBS); - when(context.issue()).thenReturn(issue); - - action.execute(properties, context); - verify(issue).setTags(ImmutableSet.of("tag1")); - } - - @Test - public void should_fail_if_tag_is_not_valid() { - throwable.expect(IllegalArgumentException.class); - throwable.expectMessage("Tag 'th ag' is invalid. Rule tags accept only the characters: a-z, 0-9, '+', '-', '#', '.'"); - - Map<String, Object> properties = newHashMap(); - properties.put("tags", "th ag"); - - DefaultIssue issue = mock(DefaultIssue.class); - when(issue.tags()).thenReturn(ImmutableSet.of("tag1", "tag3")); - - Action.Context context = mock(Action.Context.class); - when(context.issue()).thenReturn(issue); - - action.execute(properties, context); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ResultTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ResultTest.java deleted file mode 100644 index 9cf037551cb..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ResultTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ResultTest { - @Test - public void test_default_result() { - Result<Object> result = Result.of(); - assertThat(result.ok()).isTrue(); - assertThat(result.errors()).isEmpty(); - assertThat(result.httpStatus()).isEqualTo(200); - assertThat(result.get()).isNull(); - - Object obj = new Object(); - result.set(obj); - assertThat(result.get()).isSameAs(obj); - } - - @Test - public void test_error() { - Result<Object> result = Result.of(); - result.addError("Something goes wrong"); - - assertThat(result.ok()).isFalse(); - assertThat(result.errors()).hasSize(1).contains(Result.Message.of("Something goes wrong")); - assertThat(result.httpStatus()).isEqualTo(400); - assertThat(result.get()).isNull(); - } - - @Test - public void test_l10n_errors() { - Result<Object> result = Result.of(); - Result.Message message = Result.Message.ofL10n("issue.error.123", "10"); - result.addError(message); - - assertThat(result.ok()).isFalse(); - assertThat(result.errors()).hasSize(1).containsOnly(message); - - message = result.errors().get(0); - assertThat(message.text()).isNull(); - assertThat(message.l10nKey()).isEqualTo("issue.error.123"); - assertThat(message.l10nParams()).hasSize(1); - assertThat(message.l10nParams()[0]).isEqualTo("10"); - } - - @Test - public void test_text_message() { - Result.Message txtMessage = Result.Message.of("the error"); - Result.Message sameMessage = Result.Message.of("the error"); - Result.Message otherMessage = Result.Message.of("other"); - - assertThat(txtMessage.toString()).contains("the error"); - assertThat(txtMessage).isEqualTo(txtMessage); - assertThat(txtMessage).isEqualTo(sameMessage); - assertThat(txtMessage.hashCode()).isEqualTo(txtMessage.hashCode()); - assertThat(txtMessage.hashCode()).isEqualTo(sameMessage.hashCode()); - assertThat(txtMessage).isNotEqualTo(otherMessage); - assertThat(txtMessage).isNotEqualTo("the error"); - } - - @Test - public void test_l10n_message() { - Result.Message msg = Result.Message.ofL10n("issue.error.123", "10"); - Result.Message sameMsg = Result.Message.ofL10n("issue.error.123", "10"); - Result.Message msg2 = Result.Message.ofL10n("issue.error.123", "200"); - Result.Message msg3 = Result.Message.ofL10n("issue.error.50"); - - assertThat(msg.toString()).contains("issue.error.123").contains("10"); - assertThat(msg).isEqualTo(msg); - assertThat(msg).isEqualTo(sameMsg); - assertThat(msg.hashCode()).isEqualTo(msg.hashCode()); - assertThat(msg.hashCode()).isEqualTo(sameMsg.hashCode()); - - assertThat(msg).isNotEqualTo(msg2); - assertThat(msg).isNotEqualTo(msg3); - assertThat(msg).isNotEqualTo("issue.error.123"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregation.java b/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregation.java deleted file mode 100644 index fc14607055e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregation.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.HashMultiset; -import com.google.common.collect.Multiset; -import java.util.Collection; -import org.sonar.api.rule.RuleKey; -import org.sonar.db.rule.RuleDefinitionDto; - -public class RulesAggregation { - - private Multiset<Rule> rules; - - public RulesAggregation() { - this.rules = HashMultiset.create(); - } - - public RulesAggregation add(RuleDefinitionDto ruleDto) { - rules.add(new Rule(ruleDto.getKey(), ruleDto.getName())); - return this; - } - - public Collection<Rule> rules() { - return rules.elementSet(); - } - - public int countRule(Rule rule) { - return rules.count(rule); - } - - public static class Rule { - - private RuleKey ruleKey; - private String name; - - public Rule(RuleKey ruleKey, String name) { - this.ruleKey = ruleKey; - this.name = name; - } - - public RuleKey ruleKey() { - return ruleKey; - } - - public String name() { - return name; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Rule rule = (Rule) o; - - return ruleKey.equals(rule.ruleKey); - } - - @Override - public int hashCode() { - return ruleKey.hashCode(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregationTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregationTest.java deleted file mode 100644 index a22a654980a..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/RulesAggregationTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleTesting; - -import static org.assertj.core.api.Assertions.assertThat; - -public class RulesAggregationTest { - - @Test - public void empty() { - RulesAggregation rulesAggregation = new RulesAggregation(); - assertThat(rulesAggregation.rules()).isEmpty(); - } - - @Test - public void count_rules() { - RulesAggregation rulesAggregation = new RulesAggregation(); - RuleKey ruleKey = RuleKey.of("xoo", "S001"); - RuleDefinitionDto ruleDto = RuleTesting.newRule(ruleKey).setName("Rule name"); - rulesAggregation.add(ruleDto); - rulesAggregation.add(ruleDto); - - RulesAggregation.Rule rule = new RulesAggregation.Rule(ruleKey, "Rule name"); - - assertThat(rulesAggregation.rules()).hasSize(1); - assertThat(rulesAggregation.rules().iterator().next().name()).isEqualTo("Rule name"); - assertThat(rulesAggregation.countRule(rule)).isEqualTo(2); - } - - @Test - public void count_rules_with_different_rules() { - RulesAggregation rulesAggregation = new RulesAggregation(); - - RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("xoo", "S001")).setName("Rule name 1"); - rulesAggregation.add(ruleDto); - rulesAggregation.add(ruleDto); - rulesAggregation.add(RuleTesting.newRule(RuleKey.of("xoo", "S002")).setName("Rule name 2")); - - assertThat(rulesAggregation.rules()).hasSize(2); - } - - @Test - public void test_equals_and_hash_code() { - RulesAggregation.Rule rule = new RulesAggregation.Rule(RuleKey.of("xoo", "S001"), "S001"); - RulesAggregation.Rule ruleSameRuleKey = new RulesAggregation.Rule(RuleKey.of("xoo", "S001"), "S001"); - RulesAggregation.Rule ruleWithDifferentRuleKey = new RulesAggregation.Rule(RuleKey.of("xoo", "S002"), "S002"); - - assertThat(rule).isEqualTo(rule); - assertThat(rule).isEqualTo(ruleSameRuleKey); - assertThat(rule).isNotEqualTo(ruleWithDifferentRuleKey); - - assertThat(rule.hashCode()).isEqualTo(rule.hashCode()); - assertThat(rule.hashCode()).isEqualTo(ruleSameRuleKey.hashCode()); - assertThat(rule.hashCode()).isNotEqualTo(ruleWithDifferentRuleKey.hashCode()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java deleted file mode 100644 index 3021160d7ef..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import java.util.Date; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.FieldDiffs; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.tester.AnonymousMockUserSession; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.issue.IssueTesting.newDto; -import static org.sonar.db.rule.RuleTesting.newRuleDto; - -public class SetSeverityActionTest { - - private static final Date NOW = new Date(10_000_000_000L); - private static final String USER_LOGIN = "john"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - @Rule - public DbTester db = DbTester.create(); - - private IssueFieldsSetter issueUpdater = new IssueFieldsSetter(); - - private SetSeverityAction action = new SetSeverityAction(issueUpdater, userSession); - - @Test - public void set_severity() { - IssueDto issueDto = newIssue().setSeverity(MAJOR); - DefaultIssue issue = issueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(issueDto); - Action.Context context = new ActionContext(issue, IssueChangeContext.createUser(NOW, userSession.getUuid()), null); - - action.execute(ImmutableMap.of("severity", MINOR), context); - - assertThat(issue.severity()).isEqualTo(MINOR); - assertThat(issue.isChanged()).isTrue(); - assertThat(issue.manualSeverity()).isTrue(); - assertThat(issue.updateDate()).isEqualTo(NOW); - assertThat(issue.mustSendNotifications()).isTrue(); - Map<String, FieldDiffs.Diff> change = issue.currentChange().diffs(); - assertThat(change.get("severity").newValue()).isEqualTo(MINOR); - assertThat(change.get("severity").oldValue()).isEqualTo(MAJOR); - } - - @Test - public void fail_if_parameter_not_found() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Missing parameter : 'severity'"); - - action.verify(ImmutableMap.of("unknwown", MINOR), Lists.newArrayList(), new AnonymousMockUserSession()); - } - - @Test - public void support_only_unresolved_issues() { - IssueDto issueDto = newIssue().setSeverity(MAJOR); - DefaultIssue issue = issueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(issueDto); - - assertThat(action.supports(issue.setResolution(null))).isTrue(); - assertThat(action.supports(issue.setResolution(Issue.RESOLUTION_FIXED))).isFalse(); - } - - @Test - public void doesnt_support_security_hotspots() { - IssueDto issueDto = newIssue().setSeverity(MAJOR); - DefaultIssue issue = issueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(issueDto); - - assertThat(action.supports(issue.setType(RuleType.CODE_SMELL))).isTrue(); - assertThat(action.supports(issue.setType(RuleType.SECURITY_HOTSPOT))).isFalse(); - } - - @Test - public void support_only_issues_with_issue_admin_permission() { - IssueDto authorizedIssue = newIssue().setSeverity(MAJOR); - setUserWithBrowseAndAdministerIssuePermission(authorizedIssue); - IssueDto unauthorizedIssue = newIssue().setSeverity(MAJOR); - - assertThat(action.supports(authorizedIssue.toDefaultIssue().setResolution(null))).isTrue(); - assertThat(action.supports(unauthorizedIssue.toDefaultIssue().setResolution(null))).isFalse(); - } - - private void setUserWithBrowseAndAdministerIssuePermission(IssueDto issue) { - ComponentDto project = db.getDbClient().componentDao().selectByUuid(db.getSession(), issue.getProjectUuid()).get(); - ComponentDto component = db.getDbClient().componentDao().selectByUuid(db.getSession(), issue.getComponentUuid()).get(); - userSession.logIn(USER_LOGIN) - .addProjectPermission(ISSUE_ADMIN, project, component) - .addProjectPermission(USER, project, component); - } - - private IssueDto newIssue() { - RuleDto rule = db.rules().insertRule(newRuleDto()); - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - return newDto(rule, file, project); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/SetTypeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/SetTypeActionTest.java deleted file mode 100644 index 2585b44f5b9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/SetTypeActionTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import java.util.Date; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.issue.Issue; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.FieldDiffs; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.VULNERABILITY; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.issue.IssueTesting.newDto; -import static org.sonar.db.rule.RuleTesting.newRuleDto; - -public class SetTypeActionTest { - - private static final Date NOW = new Date(10_000_000_000L); - private static final String USER_LOGIN = "john"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - @Rule - public DbTester db = DbTester.create(); - - private IssueFieldsSetter issueUpdater = new IssueFieldsSetter(); - - private SetTypeAction action = new SetTypeAction(issueUpdater, userSession); - - @Test - public void set_type() { - IssueDto issueDto = newIssue().setType(BUG); - DefaultIssue issue = issueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(issueDto); - - action.execute(ImmutableMap.of("type", VULNERABILITY.name()), - new ActionContext(issue, IssueChangeContext.createUser(NOW, userSession.getUuid()), null)); - - assertThat(issue.type()).isEqualTo(VULNERABILITY); - assertThat(issue.isChanged()).isTrue(); - assertThat(issue.updateDate()).isEqualTo(NOW); - assertThat(issue.mustSendNotifications()).isFalse(); - Map<String, FieldDiffs.Diff> change = issue.currentChange().diffs(); - assertThat(change.get("type").newValue()).isEqualTo(VULNERABILITY); - assertThat(change.get("type").oldValue()).isEqualTo(BUG); - } - - @Test - public void verify_fail_if_parameter_not_found() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Missing parameter : 'type'"); - - action.verify(ImmutableMap.of("unknwown", VULNERABILITY.name()), Lists.newArrayList(), userSession); - } - - @Test - public void verify_fail_if_type_is_invalid() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Unknown type : unknown"); - - action.verify(ImmutableMap.of("type", "unknown"), Lists.newArrayList(), userSession); - } - - @Test - public void support_only_unresolved_issues() { - IssueDto issueDto = newIssue().setType(BUG); - DefaultIssue issue = issueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(issueDto); - - assertThat(action.supports(issue.setResolution(null))).isTrue(); - assertThat(action.supports(issue.setResolution(Issue.RESOLUTION_FIXED))).isFalse(); - } - - @Test - public void support_only_issues_with_issue_admin_permission() { - IssueDto authorizedIssueDto = newIssue().setType(BUG); - DefaultIssue authorizedIssue = authorizedIssueDto.toDefaultIssue(); - setUserWithBrowseAndAdministerIssuePermission(authorizedIssueDto); - DefaultIssue unauthorizedIssue = newIssue().setType(BUG).toDefaultIssue(); - - assertThat(action.supports(authorizedIssue.setResolution(null))).isTrue(); - assertThat(action.supports(unauthorizedIssue.setResolution(null))).isFalse(); - } - - private void setUserWithBrowseAndAdministerIssuePermission(IssueDto issueDto) { - ComponentDto project = db.getDbClient().componentDao().selectByUuid(db.getSession(), issueDto.getProjectUuid()).get(); - ComponentDto component = db.getDbClient().componentDao().selectByUuid(db.getSession(), issueDto.getComponentUuid()).get(); - userSession.logIn(USER_LOGIN) - .addProjectPermission(ISSUE_ADMIN, project, component) - .addProjectPermission(USER, project, component); - } - - private IssueDto newIssue() { - RuleDto rule = db.rules().insertRule(newRuleDto()); - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - return newDto(rule, file, project); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/TestIssueChangePostProcessor.java b/server/sonar-server/src/test/java/org/sonar/server/issue/TestIssueChangePostProcessor.java deleted file mode 100644 index 59c1cc8d8b9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/TestIssueChangePostProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; - -public class TestIssueChangePostProcessor implements IssueChangePostProcessor { - - private boolean called = false; - private final List<ComponentDto> calledComponents = new ArrayList<>(); - - @Override - public void process(DbSession dbSession, List<DefaultIssue> changedIssues, Collection<ComponentDto> components) { - called = true; - calledComponents.addAll(components); - } - - public boolean wasCalled() { - return called; - } - - public List<ComponentDto> calledComponents() { - return calledComponents; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionActionTest.java deleted file mode 100644 index 8a2866dfd97..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionActionTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import java.util.Date; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.issue.Issue; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.organization.OrganizationTesting; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.issue.workflow.FunctionExecutor; -import org.sonar.server.issue.workflow.IssueWorkflow; -import org.sonar.server.tester.UserSessionRule; - -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.issue.Issue.STATUS_CLOSED; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.issue.IssueTesting.newDto; -import static org.sonar.db.rule.RuleTesting.newRuleDto; - -public class TransitionActionTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - private IssueFieldsSetter updater = new IssueFieldsSetter(); - private IssueWorkflow workflow = new IssueWorkflow(new FunctionExecutor(updater), updater); - private TransitionService transitionService = new TransitionService(userSession, workflow); - - private Action.Context context = mock(Action.Context.class); - private DefaultIssue issue = newIssue().toDefaultIssue(); - - private TransitionAction action = new TransitionAction(transitionService); - - @Before - public void setUp() throws Exception { - workflow.start(); - when(context.issue()).thenReturn(issue); - when(context.issueChangeContext()).thenReturn(IssueChangeContext.createUser(new Date(), "user_uuid")); - } - - @Test - public void execute() { - loginAndAddProjectPermission("john", ISSUE_ADMIN); - issue.setStatus(Issue.STATUS_RESOLVED); - issue.setResolution(Issue.RESOLUTION_FIXED); - - action.execute(ImmutableMap.of("transition", "reopen"), context); - - assertThat(issue.status()).isEqualTo(Issue.STATUS_REOPENED); - assertThat(issue.resolution()).isNull(); - } - - @Test - public void does_not_execute_if_transition_is_not_available() { - loginAndAddProjectPermission("john", ISSUE_ADMIN); - issue.setStatus(STATUS_CLOSED); - - action.execute(ImmutableMap.of("transition", "reopen"), context); - - assertThat(issue.status()).isEqualTo(STATUS_CLOSED); - } - - @Test - public void test_verify() { - assertThat(action.verify(ImmutableMap.of("transition", "reopen"), emptyList(), userSession)).isTrue(); - assertThat(action.verify(ImmutableMap.of("transition", "close"), emptyList(), userSession)).isTrue(); - } - - @Test - public void fail_to_verify_when_parameter_not_found() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Missing parameter : 'transition'"); - action.verify(ImmutableMap.of("unknwown", "reopen"), Lists.newArrayList(), userSession); - } - - @Test - public void should_support_all_issues() { - assertThat(action.supports(new DefaultIssue().setResolution(null))).isTrue(); - assertThat(action.supports(new DefaultIssue().setResolution(Issue.RESOLUTION_FIXED))).isTrue(); - } - - private IssueDto newIssue() { - RuleDto rule = newRuleDto().setId(10); - ComponentDto project = ComponentTesting.newPrivateProjectDto(OrganizationTesting.newOrganizationDto()); - ComponentDto file = (newFileDto(project)); - return newDto(rule, file, project); - } - - private void loginAndAddProjectPermission(String login, String permission) { - userSession.logIn(login).addProjectPermission(permission, ComponentTesting.newPrivateProjectDto(OrganizationTesting.newOrganizationDto(), issue.projectUuid())); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionServiceTest.java deleted file mode 100644 index 69729235480..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/TransitionServiceTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import java.util.Date; -import java.util.List; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.issue.workflow.FunctionExecutor; -import org.sonar.server.issue.workflow.IssueWorkflow; -import org.sonar.server.issue.workflow.Transition; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.issue.Issue.STATUS_CONFIRMED; -import static org.sonar.api.issue.Issue.STATUS_OPEN; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.db.component.ComponentTesting.newFileDto; - -public class TransitionServiceTest { - - @Rule - public DbTester db = DbTester.create(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private IssueFieldsSetter updater = new IssueFieldsSetter(); - private IssueWorkflow workflow = new IssueWorkflow(new FunctionExecutor(updater), updater); - - private TransitionService underTest = new TransitionService(userSession, workflow); - - @Before - public void setUp() throws Exception { - workflow.start(); - } - - @Test - public void list_transitions() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto rule = db.rules().insert(); - IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - userSession.logIn().addProjectPermission(ISSUE_ADMIN, project); - - List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); - - assertThat(result).extracting(Transition::key).containsOnly("confirm", "resolve", "falsepositive", "wontfix"); - } - - @Test - public void list_transitions_returns_empty_list_on_external_issue() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); - IssueDto externalIssue = db.issues().insert(externalRule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - userSession.logIn().addProjectPermission(ISSUE_ADMIN, project); - - List<Transition> result = underTest.listTransitions(externalIssue.toDefaultIssue()); - - assertThat(result).isEmpty(); - } - - @Test - public void list_transitions_returns_only_transitions_that_do_not_requires_issue_admin_permission() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto rule = db.rules().insert(); - IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - userSession.logIn(); - - List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); - - assertThat(result).extracting(Transition::key).containsOnly("confirm"); - } - - @Test - public void list_transitions_returns_nothing_when_not_logged() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto rule = db.rules().insert(); - IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - - List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); - - assertThat(result).isEmpty(); - } - - @Test - public void do_transition() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto rule = db.rules().insert(); - IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - - DefaultIssue defaultIssue = issue.toDefaultIssue(); - boolean result = underTest.doTransition(defaultIssue, IssueChangeContext.createUser(new Date(), "user_uuid"), "confirm"); - - assertThat(result).isTrue(); - assertThat(defaultIssue.status()).isEqualTo(STATUS_CONFIRMED); - } - - @Test - public void do_transition_fail_on_external_issue() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); - IssueDto externalIssue = db.issues().insert(externalRule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null).setType(CODE_SMELL)); - DefaultIssue defaultIssue = externalIssue.toDefaultIssue(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Transition is not allowed on issues imported from external rule engines"); - - underTest.doTransition(defaultIssue, IssueChangeContext.createUser(new Date(), "user_uuid"), "confirm"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/WebIssueStorageTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/WebIssueStorageTest.java deleted file mode 100644 index f103c91017e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/WebIssueStorageTest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.issue; - -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; -import org.junit.Test; -import org.sonar.api.rules.RuleType; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.Duration; -import org.sonar.api.utils.System2; -import org.sonar.api.impl.utils.TestSystem2; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.core.issue.DefaultIssueComment; -import org.sonar.core.issue.IssueChangeContext; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.issue.index.IssueIndexer; -import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.rule.DefaultRuleFinder; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.api.rule.RuleStatus.REMOVED; -import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.component.ComponentTesting.newModuleDto; -import static org.sonar.db.issue.IssueTesting.newIssue; - -public class WebIssueStorageTest { - - private System2 system2 = new TestSystem2().setNow(2_000_000_000L); - - @org.junit.Rule - public DbTester db = DbTester.create(system2); - - private DbClient dbClient = db.getDbClient(); - - private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - - private IssueIndexer issueIndexer = mock(IssueIndexer.class); - private WebIssueStorage underTest = new WebIssueStorage(system2, dbClient, new DefaultRuleFinder(db.getDbClient(), defaultOrganizationProvider), issueIndexer); - - @Test - public void load_component_id_from_db() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - - long componentId = underTest.component(db.getSession(), new DefaultIssue().setComponentUuid(file.uuid())).getId(); - - assertThat(componentId).isEqualTo(file.getId()); - } - - @Test - public void load_project_id_from_db() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - ComponentDto file = db.components().insertComponent(newFileDto(project)); - - long projectId = underTest.project(db.getSession(), new DefaultIssue().setProjectUuid(project.uuid())).getId(); - - assertThat(projectId).isEqualTo(project.getId()); - } - - @Test - public void insert_new_issues() { - RuleDefinitionDto rule = db.rules().insert(); - ComponentDto project = db.components().insertMainBranch(); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - - String issueKey = "ABCDE"; - DefaultIssueComment comment = DefaultIssueComment.create(issueKey, "user_uuid", "the comment"); - // override generated key - comment.setKey("FGHIJ"); - - Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000"); - DefaultIssue issue = new DefaultIssue() - .setKey(issueKey) - .setType(RuleType.BUG) - .setNew(true) - .setRuleKey(rule.getKey()) - .setProjectUuid(project.uuid()) - .setComponentUuid(file.uuid()) - .setLine(5000) - .setEffort(Duration.create(10L)) - .setResolution("OPEN") - .setStatus("OPEN") - .setSeverity("BLOCKER") - .setAttribute("foo", "bar") - .addComment(comment) - .setCreationDate(date) - .setUpdateDate(date) - .setCloseDate(date); - - underTest.save(db.getSession(), singletonList(issue)); - - assertThat(db.countRowsOfTable("issues")).isEqualTo(1); - assertThat(db.selectFirst("select * from issues")) - .containsEntry("PROJECT_UUID", project.uuid()) - .containsEntry("COMPONENT_UUID", file.uuid()) - .containsEntry("KEE", issue.key()) - .containsEntry("RESOLUTION", issue.resolution()) - .containsEntry("STATUS", issue.status()) - .containsEntry("SEVERITY", issue.severity()); - - assertThat(db.countRowsOfTable("issue_changes")).isEqualTo(1); - assertThat(db.selectFirst("select * from issue_changes")) - .containsEntry("KEE", comment.key()) - .containsEntry("ISSUE_KEY", issue.key()) - .containsEntry("CHANGE_DATA", comment.markdownText()) - .containsEntry("USER_LOGIN", comment.userUuid()); - } - - @Test - public void update_issues() { - RuleDefinitionDto rule = db.rules().insert(); - ComponentDto project = db.components().insertMainBranch(); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - - Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000"); - DefaultIssue issue = new DefaultIssue() - .setKey("ABCDE") - .setType(RuleType.BUG) - .setNew(true) - .setRuleKey(rule.getKey()) - .setProjectUuid(project.uuid()) - .setComponentUuid(file.uuid()) - .setLine(5000) - .setEffort(Duration.create(10L)) - .setResolution("OPEN") - .setStatus("OPEN") - .setSeverity("BLOCKER") - .setAttribute("foo", "bar") - .setCreationDate(date) - .setUpdateDate(date) - .setCloseDate(date); - - underTest.save(db.getSession(), singletonList(issue)); - - assertThat(db.countRowsOfTable("issues")).isEqualTo(1); - assertThat(db.countRowsOfTable("issue_changes")).isEqualTo(0); - - DefaultIssue updated = new DefaultIssue() - .setKey(issue.key()) - .setType(RuleType.VULNERABILITY) - .setNew(false) - .setChanged(true) - - // updated fields - .setLine(issue.getLine() + 10) - .setProjectUuid("foo") - .setEffort(Duration.create(issue.effortInMinutes() + 10L)) - .setChecksum("FFFFF") - .setAuthorLogin("simon") - .setAssigneeUuid("loic") - .setFieldChange(IssueChangeContext.createUser(new Date(), "user_uuid"), "severity", "INFO", "BLOCKER") - .addComment(DefaultIssueComment.create("ABCDE", "user_uuid", "the comment")) - .setResolution("FIXED") - .setStatus("RESOLVED") - .setSeverity("MAJOR") - .setAttribute("fox", "bax") - .setCreationDate(DateUtils.addDays(date, 1)) - .setUpdateDate(DateUtils.addDays(date, 1)) - .setCloseDate(DateUtils.addDays(date, 1)) - - // unmodifiable fields - .setRuleKey(rule.getKey()) - .setComponentKey("struts:Action") - .setProjectKey("struts"); - - underTest.save(db.getSession(), singletonList(updated)); - - assertThat(db.countRowsOfTable("issues")).isEqualTo(1); - assertThat(db.selectFirst("select * from issues")) - .containsEntry("ASSIGNEE", updated.assignee()) - .containsEntry("AUTHOR_LOGIN", updated.authorLogin()) - .containsEntry("CHECKSUM", updated.checksum()) - .containsEntry("COMPONENT_UUID", issue.componentUuid()) - .containsEntry("EFFORT", updated.effortInMinutes()) - .containsEntry("ISSUE_ATTRIBUTES", "fox=bax") - .containsEntry("ISSUE_TYPE", 3) - .containsEntry("KEE", issue.key()) - .containsEntry("LINE", (long) updated.line()) - .containsEntry("PROJECT_UUID", updated.projectUuid()) - .containsEntry("RESOLUTION", updated.resolution()) - .containsEntry("STATUS", updated.status()) - .containsEntry("SEVERITY", updated.severity()); - - List<Map<String, Object>> rows = db.select("select * from issue_changes order by id"); - assertThat(rows).hasSize(2); - assertThat(rows.get(0)) - .extracting("CHANGE_DATA", "CHANGE_TYPE", "USER_LOGIN") - .containsExactlyInAnyOrder("the comment", "comment", "user_uuid"); - assertThat(rows.get(1)) - .extracting("CHANGE_DATA", "CHANGE_TYPE", "USER_LOGIN") - .containsExactlyInAnyOrder("severity=INFO|BLOCKER", "diff", "user_uuid"); - } - - @Test - public void rule_id_is_set_on_updated_issue() { - RuleDefinitionDto rule = db.rules().insert(); - ComponentDto project = db.components().insertMainBranch(); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - DefaultIssue issue = newIssue(rule, project, file).toDefaultIssue(); - - Collection<IssueDto> results = underTest.save(db.getSession(), singletonList(issue)); - - assertThat(results).hasSize(1); - assertThat(results.iterator().next().getRuleId()).isEqualTo(rule.getId()); - } - - @Test - public void rule_id_is_not_set_on_updated_issue_when_rule_is_removed() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setStatus(REMOVED)); - ComponentDto project = db.components().insertMainBranch(); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto file = db.components().insertComponent(newFileDto(module)); - DefaultIssue issue = newIssue(rule, project, file).toDefaultIssue(); - - Collection<IssueDto> results = underTest.save(db.getSession(), singletonList(issue)); - - assertThat(results).hasSize(1); - assertThat(results.iterator().next().getRuleId()).isNull(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java deleted file mode 100644 index 5051f4305f7..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java +++ /dev/null @@ -1,879 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.issue.Issue; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Metric; -import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.issue.IssueGroupDto; -import org.sonar.server.measure.DebtRatingGrid; -import org.sonar.server.measure.Rating; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; - -public class IssueMetricFormulaFactoryImplTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private IssueMetricFormulaFactoryImpl underTest = new IssueMetricFormulaFactoryImpl(); - - @Test - public void getFormulaMetrics_include_the_dependent_metrics() { - for (IssueMetricFormula formula : underTest.getFormulas()) { - assertThat(underTest.getFormulaMetrics()).contains(formula.getMetric()); - for (Metric dependentMetric : formula.getDependentMetrics()) { - assertThat(underTest.getFormulaMetrics()).contains(dependentMetric); - } - } - } - - @Test - public void test_violations() { - withNoIssues().assertThatValueIs(CoreMetrics.VIOLATIONS, 0); - with(newGroup(), newGroup().setCount(4)).assertThatValueIs(CoreMetrics.VIOLATIONS, 5); - - // exclude resolved - IssueGroupDto resolved = newResolvedGroup(Issue.RESOLUTION_FIXED, Issue.STATUS_RESOLVED); - with(newGroup(), newGroup(), resolved).assertThatValueIs(CoreMetrics.VIOLATIONS, 2); - - // include issues on leak - IssueGroupDto onLeak = newGroup().setCount(11).setInLeak(true); - with(newGroup(), newGroup(), onLeak).assertThatValueIs(CoreMetrics.VIOLATIONS, 1 + 1 + 11); - } - - @Test - public void test_bugs() { - withNoIssues().assertThatValueIs(CoreMetrics.BUGS, 0); - with( - newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(5), - // exclude resolved - newResolvedGroup(RuleType.BUG).setCount(7), - // not bugs - newGroup(RuleType.CODE_SMELL).setCount(11)) - .assertThatValueIs(CoreMetrics.BUGS, 3 + 5); - } - - @Test - public void test_code_smells() { - withNoIssues().assertThatValueIs(CoreMetrics.CODE_SMELLS, 0); - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setCount(5), - // exclude resolved - newResolvedGroup(RuleType.CODE_SMELL).setCount(7), - // not code smells - newGroup(RuleType.BUG).setCount(11)) - .assertThatValueIs(CoreMetrics.CODE_SMELLS, 3 + 5); - } - - @Test - public void test_vulnerabilities() { - withNoIssues().assertThatValueIs(CoreMetrics.VULNERABILITIES, 0); - with( - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(5), - // exclude resolved - newResolvedGroup(RuleType.VULNERABILITY).setCount(7), - // not vulnerabilities - newGroup(RuleType.BUG).setCount(11)) - .assertThatValueIs(CoreMetrics.VULNERABILITIES, 3 + 5); - } - - @Test - public void test_security_hotspots() { - withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 0); - with( - newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.CRITICAL).setCount(5), - // exclude resolved - newResolvedGroup(RuleType.SECURITY_HOTSPOT).setCount(7), - // not hotspots - newGroup(RuleType.BUG).setCount(11)) - .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 3 + 5); - } - - @Test - public void test_security_review_rating() { - withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_REVIEW_RATING, Rating.A); - - with(CoreMetrics.SECURITY_HOTSPOTS, 12.0) - .and(CoreMetrics.NCLOC, 1000.0) - .assertThatValueIs(CoreMetrics.SECURITY_REVIEW_RATING, Rating.C); - } - - @Test - public void count_unresolved_by_severity() { - withNoIssues() - .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 0) - .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 0) - .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 0) - .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0) - .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0); - - with( - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(5), - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(7), - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(11), - // exclude security hotspot - newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.CRITICAL).setCount(15), - // include leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(13), - // exclude resolved - newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setCount(17), - newResolvedGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(19), - newResolvedGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.INFO).setCount(21)) - .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 11 + 13) - .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 7) - .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 3 + 5) - .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0) - .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0); - } - - @Test - public void count_resolved() { - withNoIssues() - .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 0) - .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 0); - - with( - newResolvedGroup(Issue.RESOLUTION_FIXED, Issue.STATUS_RESOLVED).setCount(3), - newResolvedGroup(Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED).setCount(5), - newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_CLOSED).setSeverity(Severity.MAJOR).setCount(7), - newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_CLOSED).setSeverity(Severity.BLOCKER).setCount(11), - newResolvedGroup(Issue.RESOLUTION_REMOVED, Issue.STATUS_CLOSED).setCount(13), - // exclude security hotspot - newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_RESOLVED).setCount(15).setRuleType(RuleType.SECURITY_HOTSPOT.getDbConstant()), - // exclude unresolved - newGroup(RuleType.VULNERABILITY).setCount(17), - newGroup(RuleType.BUG).setCount(19)) - .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 5) - .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 7 + 11); - } - - @Test - public void count_by_status() { - withNoIssues() - .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 0) - .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 0) - .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 0); - - with( - newGroup().setStatus(Issue.STATUS_CONFIRMED).setSeverity(Severity.BLOCKER).setCount(3), - newGroup().setStatus(Issue.STATUS_CONFIRMED).setSeverity(Severity.INFO).setCount(5), - newGroup().setStatus(Issue.STATUS_REOPENED).setCount(7), - newGroup(RuleType.CODE_SMELL).setStatus(Issue.STATUS_OPEN).setCount(9), - newGroup(RuleType.BUG).setStatus(Issue.STATUS_OPEN).setCount(11), - // exclude security hotspot - newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN).setCount(12), - newResolvedGroup(Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED).setCount(13)) - .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 3 + 5) - .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 9 + 11) - .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 7); - } - - @Test - public void test_technical_debt() { - withNoIssues().assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 0); - - with( - newGroup(RuleType.CODE_SMELL).setEffort(3.0).setInLeak(false), - newGroup(RuleType.CODE_SMELL).setEffort(5.0).setInLeak(true), - // exclude security hotspot - newGroup(RuleType.SECURITY_HOTSPOT).setEffort(9).setInLeak(true), - newGroup(RuleType.SECURITY_HOTSPOT).setEffort(11).setInLeak(false), - // not code smells - newGroup(RuleType.BUG).setEffort(7.0), - // exclude resolved - newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0)) - .assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 3.0 + 5.0); - } - - @Test - public void test_reliability_remediation_effort() { - withNoIssues().assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 0); - - with( - newGroup(RuleType.BUG).setEffort(3.0), - newGroup(RuleType.BUG).setEffort(5.0).setSeverity(Severity.BLOCKER), - // not bugs - newGroup(RuleType.CODE_SMELL).setEffort(7.0), - // exclude resolved - newResolvedGroup(RuleType.BUG).setEffort(17.0)) - .assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 3.0 + 5.0); - } - - @Test - public void test_security_remediation_effort() { - withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 0); - - with( - newGroup(RuleType.VULNERABILITY).setEffort(3.0), - newGroup(RuleType.VULNERABILITY).setEffort(5.0).setSeverity(Severity.BLOCKER), - // not vulnerability - newGroup(RuleType.CODE_SMELL).setEffort(7.0), - // exclude resolved - newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0)) - .assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 3.0 + 5.0); - } - - @Test - public void test_sqale_debt_ratio_and_sqale_rating() { - withNoIssues() - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - // technical_debt not computed - with(CoreMetrics.DEVELOPMENT_COST, 0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - with(CoreMetrics.DEVELOPMENT_COST, 20) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - // development_cost not computed - with(CoreMetrics.TECHNICAL_DEBT, 0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - with(CoreMetrics.TECHNICAL_DEBT, 20) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - // input measures are available - with(CoreMetrics.TECHNICAL_DEBT, 20.0) - .and(CoreMetrics.DEVELOPMENT_COST, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - with(CoreMetrics.TECHNICAL_DEBT, 20.0) - .and(CoreMetrics.DEVELOPMENT_COST, 160.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 12.5) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.C); - - with(CoreMetrics.TECHNICAL_DEBT, 20.0) - .and(CoreMetrics.DEVELOPMENT_COST, 10.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 200.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.E); - - // A is 5% --> min debt is exactly 200*0.05=10 - with(CoreMetrics.DEVELOPMENT_COST, 200.0) - .and(CoreMetrics.TECHNICAL_DEBT, 10.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 5.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - with(CoreMetrics.TECHNICAL_DEBT, 0.0) - .and(CoreMetrics.DEVELOPMENT_COST, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - with(CoreMetrics.TECHNICAL_DEBT, 0.0) - .and(CoreMetrics.DEVELOPMENT_COST, 80.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0); - - with(CoreMetrics.TECHNICAL_DEBT, -20.0) - .and(CoreMetrics.DEVELOPMENT_COST, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - // bug, debt can't be negative - with(CoreMetrics.TECHNICAL_DEBT, -20.0) - .and(CoreMetrics.DEVELOPMENT_COST, 80.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - - // bug, cost can't be negative - with(CoreMetrics.TECHNICAL_DEBT, 20.0) - .and(CoreMetrics.DEVELOPMENT_COST, -80.0) - .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0) - .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A); - } - - @Test - public void test_effort_to_reach_maintainability_rating_A() { - withNoIssues() - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - - // technical_debt not computed - with(CoreMetrics.DEVELOPMENT_COST, 0.0) - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - with(CoreMetrics.DEVELOPMENT_COST, 20.0) - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - - // development_cost not computed - with(CoreMetrics.TECHNICAL_DEBT, 0.0) - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - with(CoreMetrics.TECHNICAL_DEBT, 20.0) - // development cost is considered as zero, so the effort is to reach... zero - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 20.0); - - // B to A - with(CoreMetrics.DEVELOPMENT_COST, 200.0) - .and(CoreMetrics.TECHNICAL_DEBT, 40.0) - // B is 5% --> goal is to reach 200*0.05=10 --> effort is 40-10=30 - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 40.0 - (200.0 * 0.05)); - - // E to A - with(CoreMetrics.DEVELOPMENT_COST, 200.0) - .and(CoreMetrics.TECHNICAL_DEBT, 180.0) - // B is 5% --> goal is to reach 200*0.05=10 --> effort is 180-10=170 - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 180.0 - (200.0 * 0.05)); - - // already A - with(CoreMetrics.DEVELOPMENT_COST, 200.0) - .and(CoreMetrics.TECHNICAL_DEBT, 8.0) - // B is 5% --> goal is to reach 200*0.05=10 --> debt is already at 8 --> effort to reach A is zero - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - - // exactly lower range of B - with(CoreMetrics.DEVELOPMENT_COST, 200.0) - .and(CoreMetrics.TECHNICAL_DEBT, 10.0) - // B is 5% --> goal is to reach 200*0.05=10 --> debt is 10 --> effort to reach A is zero - // FIXME need zero to reach A but effective rating is B ! - .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0); - } - - @Test - public void test_reliability_rating() { - withNoIssues() - .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A); - - with( - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(1), - newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setCount(5), - // excluded, not a bug - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3)) - // highest severity of bugs is CRITICAL --> D - .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.D); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(5)) - // no bugs --> A - .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A); - } - - @Test - public void test_security_rating() { - withNoIssues() - .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A); - - with( - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(1), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setCount(5), - // excluded, not a vulnerability - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3)) - // highest severity of vulnerabilities is CRITICAL --> D - .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.D); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(5)) - // no vulnerabilities --> A - .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A); - } - - @Test - public void test_new_bugs() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 0.0); - - with( - newGroup(RuleType.BUG).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.BUG).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5), - newGroup(RuleType.BUG).setInLeak(true).setSeverity(Severity.MINOR).setCount(7), - // not bugs - newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(9), - newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11)) - .assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 5 + 7); - } - - @Test - public void test_new_code_smells() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.CODE_SMELL).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5), - newGroup(RuleType.CODE_SMELL).setInLeak(true).setSeverity(Severity.MINOR).setCount(7), - // not code smells - newGroup(RuleType.BUG).setInLeak(true).setCount(9), - newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11)) - .assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 5 + 7); - } - - @Test - public void test_new_vulnerabilities() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 0.0); - - with( - newGroup(RuleType.VULNERABILITY).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.VULNERABILITY).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5), - newGroup(RuleType.VULNERABILITY).setInLeak(true).setSeverity(Severity.MINOR).setCount(7), - // not vulnerabilities - newGroup(RuleType.BUG).setInLeak(true).setCount(9), - newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11)) - .assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 5 + 7); - } - - @Test - public void test_new_security_hotspots() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 0.0); - - with( - newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3), - newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5), - newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(true).setSeverity(Severity.MINOR).setCount(7), - // not hotspots - newGroup(RuleType.BUG).setInLeak(true).setCount(9), - newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11)) - .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 5 + 7); - } - - @Test - public void test_new_violations() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.BUG).setInLeak(true).setCount(5), - newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(7), - newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.BUG).setInLeak(false).setCount(11), - newGroup(RuleType.CODE_SMELL).setInLeak(false).setCount(13), - newGroup(RuleType.VULNERABILITY).setInLeak(false).setCount(17)) - .assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 5 + 7 + 9); - } - - @Test - public void test_new_blocker_violations() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(5), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(7), - // not blocker - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(11), - newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(13)) - .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 3 + 5 + 7); - } - - @Test - public void test_new_critical_violations() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(5), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(7), - // not CRITICAL - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(11), - newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(13)) - .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 3 + 5 + 7); - } - - @Test - public void test_new_major_violations() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(true).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setInLeak(true).setCount(5), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setInLeak(true).setCount(7), - // not MAJOR - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(false).setCount(11), - newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setInLeak(false).setCount(13)) - .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 3 + 5 + 7); - } - - @Test - public void test_new_minor_violations() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MINOR).setInLeak(true).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setInLeak(true).setCount(5), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setInLeak(true).setCount(7), - // not MINOR - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MINOR).setInLeak(false).setCount(11), - newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setInLeak(false).setCount(13)) - .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 3 + 5 + 7); - } - - @Test - public void test_new_info_violations() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.INFO).setInLeak(true).setCount(3), - newGroup(RuleType.BUG).setSeverity(Severity.INFO).setInLeak(true).setCount(5), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setInLeak(true).setCount(7), - // not INFO - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9), - // not in leak - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.INFO).setInLeak(false).setCount(11), - newGroup(RuleType.BUG).setSeverity(Severity.INFO).setInLeak(false).setCount(13)) - .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 3 + 5 + 7); - } - - @Test - public void test_new_technical_debt() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0); - - with( - newGroup(RuleType.CODE_SMELL).setEffort(3.0).setInLeak(true), - // not in leak - newGroup(RuleType.CODE_SMELL).setEffort(5.0).setInLeak(false), - // not code smells - newGroup(RuleType.SECURITY_HOTSPOT).setEffort(9.0).setInLeak(true), - newGroup(RuleType.BUG).setEffort(7.0).setInLeak(true), - // exclude resolved - newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0).setInLeak(true)) - .assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 3.0); - } - - @Test - public void test_new_reliability_remediation_effort() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 0.0); - - with( - newGroup(RuleType.BUG).setEffort(3.0).setInLeak(true), - // not in leak - newGroup(RuleType.BUG).setEffort(5.0).setInLeak(false), - // not bugs - newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true), - // exclude resolved - newResolvedGroup(RuleType.BUG).setEffort(17.0).setInLeak(true)) - .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 3.0); - } - - @Test - public void test_new_security_remediation_effort() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 0.0); - - with( - newGroup(RuleType.VULNERABILITY).setEffort(3.0).setInLeak(true), - // not in leak - newGroup(RuleType.VULNERABILITY).setEffort(5.0).setInLeak(false), - // not vulnerability - newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true), - // exclude resolved - newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0).setInLeak(true)) - .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 3.0); - } - - @Test - public void test_new_reliability_rating() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.A); - - with( - newGroup(RuleType.BUG).setSeverity(Severity.INFO).setCount(3).setInLeak(true), - newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setCount(1).setInLeak(true), - // not in leak - newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(false), - // not bug - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true), - // exclude resolved - newResolvedGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(true)) - // highest severity of bugs on leak period is minor -> B - .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.B); - } - - @Test - public void test_new_security_rating() { - withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.A); - - with( - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setCount(3).setInLeak(true), - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setCount(1).setInLeak(true), - // not in leak - newGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(false), - // not vulnerability - newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true), - // exclude resolved - newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(true)) - // highest severity of bugs on leak period is minor -> B - .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.B); - } - - @Test - public void test_new_sqale_debt_ratio_and_new_maintainability_rating() { - withNoIssues() - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - // technical_debt not computed - withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 20) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - // development_cost not computed - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - // input measures are available - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 160.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 12.5) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.C); - - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 10.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 200.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.E); - - // A is 5% --> min debt is exactly 200*0.05=10 - withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 200.0) - .andLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 10.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 5.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 80.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0); - - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, -20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - // bug, debt can't be negative - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, -20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 80.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - - // bug, cost can't be negative - withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0) - .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, -80.0) - .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0) - .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A); - } - - private Verifier with(IssueGroupDto... groups) { - return new Verifier(groups); - } - - private Verifier withNoIssues() { - return new Verifier(new IssueGroupDto[0]); - } - - private Verifier with(Metric metric, double value) { - return new Verifier(new IssueGroupDto[0]).and(metric, value); - } - - private Verifier withLeak(Metric metric, double leakValue) { - return new Verifier(new IssueGroupDto[0]).andLeak(metric, leakValue); - } - - private class Verifier { - private final IssueGroupDto[] groups; - private final Map<Metric, Double> values = new HashMap<>(); - private final Map<Metric, Double> leakValues = new HashMap<>(); - - private Verifier(IssueGroupDto[] groups) { - this.groups = groups; - } - - Verifier and(Metric metric, double value) { - this.values.put(metric, value); - return this; - } - - Verifier andLeak(Metric metric, double value) { - this.leakValues.put(metric, value); - return this; - } - - Verifier assertThatValueIs(Metric metric, double expectedValue) { - TestContext context = run(metric, false); - assertThat(context.doubleValue).isNotNull().isEqualTo(expectedValue); - return this; - } - - Verifier assertThatLeakValueIs(Metric metric, double expectedValue) { - TestContext context = run(metric, true); - assertThat(context.doubleLeakValue).isNotNull().isEqualTo(expectedValue); - return this; - } - - Verifier assertThatLeakValueIs(Metric metric, Rating expectedRating) { - TestContext context = run(metric, true); - assertThat(context.ratingLeakValue).isNotNull().isEqualTo(expectedRating); - return this; - } - - Verifier assertThatValueIs(Metric metric, Rating expectedValue) { - TestContext context = run(metric, false); - assertThat(context.ratingValue).isNotNull().isEqualTo(expectedValue); - return this; - } - - private TestContext run(Metric metric, boolean expectLeakFormula) { - IssueMetricFormula formula = underTest.getFormulas().stream() - .filter(f -> f.getMetric().getKey().equals(metric.getKey())) - .findFirst() - .get(); - assertThat(formula.isOnLeak()).isEqualTo(expectLeakFormula); - TestContext context = new TestContext(formula.getDependentMetrics(), values, leakValues); - formula.compute(context, newIssueCounter(groups)); - return context; - } - } - - private static IssueCounter newIssueCounter(IssueGroupDto... issues) { - return new IssueCounter(asList(issues)); - } - - private static IssueGroupDto newGroup() { - return newGroup(RuleType.CODE_SMELL); - } - - private static IssueGroupDto newGroup(RuleType ruleType) { - IssueGroupDto dto = new IssueGroupDto(); - // set non-null fields - dto.setRuleType(ruleType.getDbConstant()); - dto.setCount(1); - dto.setEffort(0.0); - dto.setSeverity(Severity.INFO); - dto.setStatus(Issue.STATUS_OPEN); - dto.setInLeak(false); - return dto; - } - - private static IssueGroupDto newResolvedGroup(RuleType ruleType) { - return newGroup(ruleType).setResolution(Issue.RESOLUTION_FALSE_POSITIVE).setStatus(Issue.STATUS_CLOSED); - } - - private static IssueGroupDto newResolvedGroup(String resolution, String status) { - return newGroup().setResolution(resolution).setStatus(status); - } - - private static class TestContext implements IssueMetricFormula.Context { - private final Set<Metric> dependentMetrics; - private Double doubleValue; - private Rating ratingValue; - private Double doubleLeakValue; - private Rating ratingLeakValue; - private final Map<Metric, Double> values; - private final Map<Metric, Double> leakValues; - - private TestContext(Collection<Metric> dependentMetrics, Map<Metric, Double> values, Map<Metric, Double> leakValues) { - this.dependentMetrics = new HashSet<>(dependentMetrics); - this.values = values; - this.leakValues = leakValues; - } - - @Override - public ComponentDto getComponent() { - throw new UnsupportedOperationException(); - } - - @Override - public DebtRatingGrid getDebtRatingGrid() { - return new DebtRatingGrid(new double[] {0.05, 0.1, 0.2, 0.5}); - } - - @Override - public Optional<Double> getValue(Metric metric) { - if (!dependentMetrics.contains(metric)) { - throw new IllegalStateException("Metric " + metric.getKey() + " is not declared as a dependency"); - } - if (values.containsKey(metric)) { - return Optional.of(values.get(metric)); - } - return Optional.empty(); - } - - @Override - public Optional<Double> getLeakValue(Metric metric) { - if (!dependentMetrics.contains(metric)) { - throw new IllegalStateException("Metric " + metric.getKey() + " is not declared as a dependency"); - } - if (leakValues.containsKey(metric)) { - return Optional.of(leakValues.get(metric)); - } - return Optional.empty(); - } - - @Override - public void setValue(double value) { - this.doubleValue = value; - } - - @Override - public void setValue(Rating value) { - this.ratingValue = value; - } - - @Override - public void setLeakValue(double value) { - this.doubleLeakValue = value; - } - - @Override - public void setLeakValue(Rating value) { - this.ratingLeakValue = value; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java deleted file mode 100644 index df8fff10315..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Metric; -import org.sonar.api.resources.Qualifiers; -import org.sonar.core.config.CorePropertyDefinitions; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.es.ProjectIndexer; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.measure.Rating; -import org.sonar.server.qualitygate.EvaluatedQualityGate; -import org.sonar.server.qualitygate.QualityGate; -import org.sonar.server.qualitygate.changeevent.QGChangeEvent; -import org.sonar.server.settings.ProjectConfigurationLoader; -import org.sonar.server.settings.TestProjectConfigurationLoader; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.singleton; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.api.resources.Qualifiers.ORDERED_BOTTOM_UP; - -@RunWith(DataProviderRunner.class) -public class LiveMeasureComputerImplTest { - - @Rule - public DbTester db = DbTester.create(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private TestProjectIndexers projectIndexer = new TestProjectIndexers(); - private MetricDto intMetric; - private MetricDto ratingMetric; - private MetricDto alertStatusMetric; - private OrganizationDto organization; - private ComponentDto project; - private ComponentDto dir; - private ComponentDto file1; - private ComponentDto file2; - private ComponentDto branch; - private ComponentDto branchFile; - private LiveQualityGateComputer qGateComputer = mock(LiveQualityGateComputer.class); - private QualityGate qualityGate = mock(QualityGate.class); - private EvaluatedQualityGate newQualityGate = mock(EvaluatedQualityGate.class); - - @Before - public void setUp() throws Exception { - intMetric = db.measures().insertMetric(m -> m.setValueType(Metric.ValueType.INT.name())); - ratingMetric = db.measures().insertMetric(m -> m.setValueType(Metric.ValueType.RATING.name())); - alertStatusMetric = db.measures().insertMetric(m -> m.setKey(CoreMetrics.ALERT_STATUS_KEY)); - organization = db.organizations().insert(); - project = db.components().insertMainBranch(organization); - dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java")); - file1 = db.components().insertComponent(ComponentTesting.newFileDto(project, dir)); - file2 = db.components().insertComponent(ComponentTesting.newFileDto(project, dir)); - branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST)); - branchFile = db.components().insertComponent(ComponentTesting.newFileDto(branch)); - } - - @Test - public void compute_and_insert_measures_if_they_do_not_exist_yet() { - markProjectAsAnalyzed(project); - - List<QGChangeEvent> result = run(asList(file1, file2), newQualifierBasedIntFormula(), newRatingConstantFormula(Rating.C)); - - // 2 measures per component have been created - // Numeric value depends on qualifier (see newQualifierBasedIntFormula()) - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(8); - assertThatIntMeasureHasValue(file1, ORDERED_BOTTOM_UP.indexOf(Qualifiers.FILE)); - assertThatRatingMeasureHasValue(file1, Rating.C); - assertThatIntMeasureHasValue(file2, ORDERED_BOTTOM_UP.indexOf(Qualifiers.FILE)); - assertThatRatingMeasureHasValue(file2, Rating.C); - assertThatIntMeasureHasValue(dir, ORDERED_BOTTOM_UP.indexOf(Qualifiers.DIRECTORY)); - assertThatRatingMeasureHasValue(dir, Rating.C); - assertThatIntMeasureHasValue(project, ORDERED_BOTTOM_UP.indexOf(Qualifiers.PROJECT)); - assertThatRatingMeasureHasValue(project, Rating.C); - assertThatProjectChanged(result, project); - } - - @Test - public void compute_and_update_measures_if_they_already_exist() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, intMetric, m -> m.setValue(42.0)); - db.measures().insertLiveMeasure(dir, intMetric, m -> m.setValue(42.0)); - db.measures().insertLiveMeasure(file1, intMetric, m -> m.setValue(42.0)); - db.measures().insertLiveMeasure(file2, intMetric, m -> m.setValue(42.0)); - - // generates values 1, 2, 3 - List<QGChangeEvent> result = run(file1, newQualifierBasedIntFormula()); - - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(4); - assertThatProjectChanged(result, project); - - // Numeric value depends on qualifier (see newQualifierBasedIntFormula()) - assertThatIntMeasureHasValue(file1, ORDERED_BOTTOM_UP.indexOf(Qualifiers.FILE)); - assertThatIntMeasureHasValue(dir, ORDERED_BOTTOM_UP.indexOf(Qualifiers.DIRECTORY)); - assertThatIntMeasureHasValue(project, ORDERED_BOTTOM_UP.indexOf(Qualifiers.PROJECT)); - // untouched - assertThatIntMeasureHasValue(file2, 42.0); - } - - @Test - public void variation_is_refreshed_when_int_value_is_changed() { - markProjectAsAnalyzed(project); - // value is: - // 42 on last analysis - // 42-12=30 on beginning of leak period - db.measures().insertLiveMeasure(project, intMetric, m -> m.setValue(42.0).setVariation(12.0)); - - // new value is 44, so variation on leak period is 44-30=14 - List<QGChangeEvent> result = run(file1, newIntConstantFormula(44.0)); - - LiveMeasureDto measure = assertThatIntMeasureHasValue(project, 44.0); - assertThat(measure.getVariation()).isEqualTo(14.0); - assertThatProjectChanged(result, project); - } - - @Test - public void variation_is_refreshed_when_rating_value_is_changed() { - markProjectAsAnalyzed(project); - // value is: - // B on last analysis - // D on beginning of leak period --> variation is -2 - db.measures().insertLiveMeasure(project, ratingMetric, m -> m.setValue((double) Rating.B.getIndex()).setData("B").setVariation(-2.0)); - - // new value is C, so variation on leak period is D to C = -1 - List<QGChangeEvent> result = run(file1, newRatingConstantFormula(Rating.C)); - - LiveMeasureDto measure = assertThatRatingMeasureHasValue(project, Rating.C); - assertThat(measure.getVariation()).isEqualTo(-1.0); - assertThatProjectChanged(result, project); - } - - @Test - public void variation_does_not_change_if_rating_value_does_not_change() { - markProjectAsAnalyzed(project); - // value is: - // B on last analysis - // D on beginning of leak period --> variation is -2 - db.measures().insertLiveMeasure(project, ratingMetric, m -> m.setValue((double) Rating.B.getIndex()).setData("B").setVariation(-2.0)); - - // new value is still B, so variation on leak period is still -2 - List<QGChangeEvent> result = run(file1, newRatingConstantFormula(Rating.B)); - - LiveMeasureDto measure = assertThatRatingMeasureHasValue(project, Rating.B); - assertThat(measure.getVariation()).isEqualTo(-2.0); - assertThatProjectChanged(result, project); - } - - @Test - public void refresh_leak_measures() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, intMetric, m -> m.setVariation(42.0).setValue(null)); - db.measures().insertLiveMeasure(project, ratingMetric, m -> m.setVariation((double) Rating.E.getIndex())); - db.measures().insertLiveMeasure(dir, intMetric, m -> m.setVariation(42.0).setValue(null)); - db.measures().insertLiveMeasure(dir, ratingMetric, m -> m.setVariation((double) Rating.D.getIndex())); - db.measures().insertLiveMeasure(file1, intMetric, m -> m.setVariation(42.0).setValue(null)); - db.measures().insertLiveMeasure(file1, ratingMetric, m -> m.setVariation((double) Rating.C.getIndex())); - - // generates values 1, 2, 3 on leak measures - List<QGChangeEvent> result = run(file1, newQualifierBasedIntLeakFormula(), newRatingLeakFormula(Rating.B)); - - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(6); - - // Numeric value depends on qualifier (see newQualifierBasedIntLeakFormula()) - assertThatIntMeasureHasLeakValue(file1, ORDERED_BOTTOM_UP.indexOf(Qualifiers.FILE)); - assertThatRatingMeasureHasLeakValue(file1, Rating.B); - assertThatIntMeasureHasLeakValue(dir, ORDERED_BOTTOM_UP.indexOf(Qualifiers.DIRECTORY)); - assertThatRatingMeasureHasLeakValue(dir, Rating.B); - assertThatIntMeasureHasLeakValue(project, ORDERED_BOTTOM_UP.indexOf(Qualifiers.PROJECT)); - assertThatRatingMeasureHasLeakValue(project, Rating.B); - assertThatProjectChanged(result, project); - } - - @Test - public void calculate_new_metrics_if_it_is_pr_or_branch() { - markProjectAsAnalyzed(branch, null); - db.measures().insertLiveMeasure(branch, intMetric, m -> m.setVariation(42.0).setValue(null)); - db.measures().insertLiveMeasure(branchFile, intMetric, m -> m.setVariation(42.0).setValue(null)); - - // generates values 1, 2, 3 on leak measures - List<QGChangeEvent> result = run(branchFile, newQualifierBasedIntLeakFormula(), newRatingLeakFormula(Rating.B)); - - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(4); - - // Numeric value depends on qualifier (see newQualifierBasedIntLeakFormula()) - assertThatIntMeasureHasLeakValue(branchFile, ORDERED_BOTTOM_UP.indexOf(Qualifiers.FILE)); - assertThatRatingMeasureHasLeakValue(branchFile, Rating.B); - assertThatIntMeasureHasLeakValue(branch, ORDERED_BOTTOM_UP.indexOf(Qualifiers.PROJECT)); - assertThatRatingMeasureHasLeakValue(branch, Rating.B); - assertThatProjectChanged(result, branch); - } - - @Test - public void do_nothing_if_project_has_not_been_analyzed() { - // project has no snapshots - List<QGChangeEvent> result = run(file1, newIncrementalFormula()); - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(0); - assertThatProjectNotChanged(result, project); - } - - @Test - public void do_nothing_if_input_components_are_empty() { - List<QGChangeEvent> result = run(emptyList(), newIncrementalFormula()); - - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(0); - assertThatProjectNotChanged(result, project); - } - - @Test - public void refresh_multiple_projects_at_the_same_time() { - markProjectAsAnalyzed(project); - ComponentDto project2 = db.components().insertMainBranch(); - ComponentDto fileInProject2 = db.components().insertComponent(ComponentTesting.newFileDto(project2)); - markProjectAsAnalyzed(project2); - - List<QGChangeEvent> result = run(asList(file1, fileInProject2), newQualifierBasedIntFormula()); - - // generated values depend on position of qualifier in Qualifiers.ORDERED_BOTTOM_UP (see formula) - assertThatIntMeasureHasValue(file1, 0); - assertThatIntMeasureHasValue(dir, 2); - assertThatIntMeasureHasValue(project, 4); - assertThatIntMeasureHasValue(fileInProject2, 0); - assertThatIntMeasureHasValue(project2, 4); - - // no other measures generated - assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(5); - assertThatProjectChanged(result, project, project2); - } - - @Test - public void refresh_multiple_branches_at_the_same_time() { - // FIXME - } - - @Test - public void event_contains_no_previousStatus_if_measure_does_not_exist() { - markProjectAsAnalyzed(project); - - List<QGChangeEvent> result = run(file1); - - assertThat(result) - .extracting(QGChangeEvent::getPreviousStatus) - .containsExactly(Optional.empty()); - } - - @Test - public void event_contains_no_previousStatus_if_measure_exists_and_has_no_value() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData((String) null)); - - List<QGChangeEvent> result = run(file1); - - assertThat(result) - .extracting(QGChangeEvent::getPreviousStatus) - .containsExactly(Optional.empty()); - } - - @Test - public void event_contains_no_previousStatus_if_measure_exists_and_is_empty() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData("")); - - List<QGChangeEvent> result = run(file1); - - assertThat(result) - .extracting(QGChangeEvent::getPreviousStatus) - .containsExactly(Optional.empty()); - } - - @Test - public void event_contains_no_previousStatus_if_measure_exists_and_is_not_a_level() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData("fooBar")); - - List<QGChangeEvent> result = run(file1); - - assertThat(result) - .extracting(QGChangeEvent::getPreviousStatus) - .containsExactly(Optional.empty()); - } - - @Test - @UseDataProvider("metricLevels") - public void event_contains_previousStatus_if_measure_exists(Metric.Level level) { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData(level.name())); - db.measures().insertLiveMeasure(project, intMetric, m -> m.setVariation(42.0).setValue(null)); - - List<QGChangeEvent> result = run(file1, newQualifierBasedIntLeakFormula()); - - assertThat(result) - .extracting(QGChangeEvent::getPreviousStatus) - .containsExactly(Optional.of(level)); - } - - @DataProvider - public static Object[][] metricLevels() { - return Arrays.stream(Metric.Level.values()) - .map(l -> new Object[] {l}) - .toArray(Object[][]::new); - } - - @Test - public void event_contains_newQualityGate_computed_by_LiveQualityGateComputer() { - markProjectAsAnalyzed(project); - db.measures().insertLiveMeasure(project, alertStatusMetric, m -> m.setData(Metric.Level.ERROR.name())); - db.measures().insertLiveMeasure(project, intMetric, m -> m.setVariation(42.0).setValue(null)); - BranchDto branch = db.getDbClient().branchDao().selectByBranchKey(db.getSession(), project.projectUuid(), "master") - .orElseThrow(() -> new IllegalStateException("Can't find master branch")); - - List<QGChangeEvent> result = run(file1, newQualifierBasedIntLeakFormula()); - - assertThat(result) - .extracting(QGChangeEvent::getQualityGateSupplier) - .extracting(Supplier::get) - .containsExactly(Optional.of(newQualityGate)); - verify(qGateComputer).loadQualityGate(any(DbSession.class), eq(organization), eq(project), eq(branch)); - verify(qGateComputer).getMetricsRelatedTo(qualityGate); - verify(qGateComputer).refreshGateStatus(eq(project), same(qualityGate), any(MeasureMatrix.class)); - } - - @Test - public void exception_describes_context_when_a_formula_fails() { - markProjectAsAnalyzed(project); - Metric metric = new Metric.Builder(intMetric.getKey(), intMetric.getShortName(), Metric.ValueType.valueOf(intMetric.getValueType())).create(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Fail to compute " + metric.getKey() + " on " + project.getDbKey()); - - run(project, new IssueMetricFormula(metric, false, (context, issueCounter) -> { - throw new NullPointerException("BOOM"); - })); - } - - private List<QGChangeEvent> run(ComponentDto component, IssueMetricFormula... formulas) { - return run(singleton(component), formulas); - } - - private List<QGChangeEvent> run(Collection<ComponentDto> components, IssueMetricFormula... formulas) { - IssueMetricFormulaFactory formulaFactory = new TestIssueMetricFormulaFactory(asList(formulas)); - - when(qGateComputer.loadQualityGate(any(DbSession.class), any(OrganizationDto.class), any(ComponentDto.class), any(BranchDto.class))) - .thenReturn(qualityGate); - when(qGateComputer.getMetricsRelatedTo(qualityGate)).thenReturn(singleton(CoreMetrics.ALERT_STATUS_KEY)); - when(qGateComputer.refreshGateStatus(eq(project), same(qualityGate), any(MeasureMatrix.class))) - .thenReturn(newQualityGate); - MapSettings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all())); - ProjectConfigurationLoader configurationLoader = new TestProjectConfigurationLoader(settings.asConfig()); - - LiveMeasureComputerImpl underTest = new LiveMeasureComputerImpl(db.getDbClient(), formulaFactory, qGateComputer, configurationLoader, projectIndexer); - - return underTest.refresh(db.getSession(), components); - } - - private void markProjectAsAnalyzed(ComponentDto p) { - markProjectAsAnalyzed(p, 1_490_000_000L); - } - - private void markProjectAsAnalyzed(ComponentDto p, @Nullable Long periodDate) { - assertThat(p.qualifier()).isEqualTo(Qualifiers.PROJECT); - db.components().insertSnapshot(p, s -> s.setPeriodDate(periodDate)); - } - - private LiveMeasureDto assertThatIntMeasureHasValue(ComponentDto component, double expectedValue) { - LiveMeasureDto measure = db.getDbClient().liveMeasureDao().selectMeasure(db.getSession(), component.uuid(), intMetric.getKey()).get(); - assertThat(measure.getComponentUuid()).isEqualTo(component.uuid()); - assertThat(measure.getProjectUuid()).isEqualTo(component.projectUuid()); - assertThat(measure.getMetricId()).isEqualTo(intMetric.getId()); - assertThat(measure.getValue()).isEqualTo(expectedValue); - return measure; - } - - private LiveMeasureDto assertThatRatingMeasureHasValue(ComponentDto component, Rating expectedRating) { - LiveMeasureDto measure = db.getDbClient().liveMeasureDao().selectMeasure(db.getSession(), component.uuid(), ratingMetric.getKey()).get(); - assertThat(measure.getComponentUuid()).isEqualTo(component.uuid()); - assertThat(measure.getProjectUuid()).isEqualTo(component.projectUuid()); - assertThat(measure.getMetricId()).isEqualTo(ratingMetric.getId()); - assertThat(measure.getValue()).isEqualTo(expectedRating.getIndex()); - assertThat(measure.getDataAsString()).isEqualTo(expectedRating.name()); - return measure; - } - - private void assertThatIntMeasureHasLeakValue(ComponentDto component, double expectedValue) { - LiveMeasureDto measure = db.getDbClient().liveMeasureDao().selectMeasure(db.getSession(), component.uuid(), intMetric.getKey()).get(); - assertThat(measure.getComponentUuid()).isEqualTo(component.uuid()); - assertThat(measure.getProjectUuid()).isEqualTo(component.projectUuid()); - assertThat(measure.getMetricId()).isEqualTo(intMetric.getId()); - assertThat(measure.getValue()).isNull(); - assertThat(measure.getVariation()).isEqualTo(expectedValue); - } - - private void assertThatRatingMeasureHasLeakValue(ComponentDto component, Rating expectedValue) { - LiveMeasureDto measure = db.getDbClient().liveMeasureDao().selectMeasure(db.getSession(), component.uuid(), ratingMetric.getKey()).get(); - assertThat(measure.getComponentUuid()).isEqualTo(component.uuid()); - assertThat(measure.getProjectUuid()).isEqualTo(component.projectUuid()); - assertThat(measure.getMetricId()).isEqualTo(ratingMetric.getId()); - assertThat(measure.getVariation()).isEqualTo((double) expectedValue.getIndex()); - } - - private IssueMetricFormula newIncrementalFormula() { - Metric metric = new Metric.Builder(intMetric.getKey(), intMetric.getShortName(), Metric.ValueType.valueOf(intMetric.getValueType())).create(); - AtomicInteger counter = new AtomicInteger(); - return new IssueMetricFormula(metric, false, (ctx, issues) -> { - ctx.setValue((double) counter.incrementAndGet()); - }); - } - - private IssueMetricFormula newIntConstantFormula(double constant) { - Metric metric = new Metric.Builder(intMetric.getKey(), intMetric.getShortName(), Metric.ValueType.valueOf(intMetric.getValueType())).create(); - return new IssueMetricFormula(metric, false, (ctx, issues) -> { - ctx.setValue(constant); - }); - } - - private IssueMetricFormula newRatingConstantFormula(Rating constant) { - Metric metric = new Metric.Builder(ratingMetric.getKey(), ratingMetric.getShortName(), Metric.ValueType.valueOf(ratingMetric.getValueType())).create(); - return new IssueMetricFormula(metric, false, (ctx, issues) -> { - ctx.setValue(constant); - }); - } - - private IssueMetricFormula newRatingLeakFormula(Rating rating) { - Metric metric = new Metric.Builder(ratingMetric.getKey(), ratingMetric.getShortName(), Metric.ValueType.valueOf(ratingMetric.getValueType())).create(); - return new IssueMetricFormula(metric, true, (ctx, issues) -> { - ctx.setLeakValue(rating); - }); - } - - private IssueMetricFormula newQualifierBasedIntFormula() { - Metric metric = new Metric.Builder(intMetric.getKey(), intMetric.getShortName(), Metric.ValueType.valueOf(intMetric.getValueType())).create(); - return new IssueMetricFormula(metric, false, (ctx, issues) -> { - ctx.setValue(ORDERED_BOTTOM_UP.indexOf(ctx.getComponent().qualifier())); - }); - } - - private IssueMetricFormula newQualifierBasedIntLeakFormula() { - Metric metric = new Metric.Builder(intMetric.getKey(), intMetric.getShortName(), Metric.ValueType.valueOf(intMetric.getValueType())).create(); - return new IssueMetricFormula(metric, true, (ctx, issues) -> { - ctx.setLeakValue(ORDERED_BOTTOM_UP.indexOf(ctx.getComponent().qualifier())); - }); - } - - private void assertThatProjectChanged(List<QGChangeEvent> events, ComponentDto... projects) { - for (ComponentDto p : projects) { - assertThat(projectIndexer.hasBeenCalled(p.uuid(), ProjectIndexer.Cause.MEASURE_CHANGE)).isTrue(); - } - - assertThat(events).extracting(e -> e.getProject().uuid()) - .containsExactlyInAnyOrder(Arrays.stream(projects).map(ComponentDto::uuid).toArray(String[]::new)); - } - - private void assertThatProjectNotChanged(List<QGChangeEvent> events, ComponentDto project) { - assertThat(projectIndexer.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.MEASURE_CHANGE)).isFalse(); - assertThat(events).hasSize(0); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureModuleTest.java deleted file mode 100644 index cb271141428..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureModuleTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import org.junit.Test; -import org.sonar.core.platform.ComponentContainer; - -import static org.assertj.core.api.Assertions.assertThat; - -public class LiveMeasureModuleTest { - - @Test - public void verify_count_of_added_components() { - ComponentContainer container = new ComponentContainer(); - new LiveMeasureModule().configure(container); - assertThat(container.size()).isEqualTo(3 + 2); - } - - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveQualityGateComputerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveQualityGateComputerImplTest.java deleted file mode 100644 index 7ff3fbfdd51..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveQualityGateComputerImplTest.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import com.google.common.collect.ImmutableSet; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Metric; -import org.sonar.db.DbTester; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualitygate.QGateWithOrgDto; -import org.sonar.db.qualitygate.QualityGateConditionDto; -import org.sonar.server.qualitygate.Condition; -import org.sonar.server.qualitygate.EvaluatedCondition; -import org.sonar.server.qualitygate.EvaluatedQualityGate; -import org.sonar.server.qualitygate.QualityGate; -import org.sonar.server.qualitygate.QualityGateEvaluator; -import org.sonar.server.qualitygate.QualityGateFinder; - -import static com.google.common.base.Preconditions.checkState; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.singleton; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.groups.Tuple.tuple; -import static org.sonar.db.component.ComponentTesting.newBranchDto; -import static org.sonar.db.metric.MetricTesting.newMetricDto; -import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; - -public class LiveQualityGateComputerImplTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester db = DbTester.create(); - - private TestQualityGateEvaluator qualityGateEvaluator = new TestQualityGateEvaluator(); - private LiveQualityGateComputerImpl underTest = new LiveQualityGateComputerImpl(db.getDbClient(), new QualityGateFinder(db.getDbClient()), qualityGateEvaluator); - - @Test - public void loadQualityGate_returns_hardcoded_gate_for_short_living_branches() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertPublicProject(organization); - - BranchDto branch = newBranchDto(project).setBranchType(BranchType.SHORT); - db.components().insertProjectBranch(project, branch); - MetricDto metric1 = db.measures().insertMetric(m -> m.setKey("new_metric")); - MetricDto metric2 = db.measures().insertMetric(m -> m.setKey("metric")); - - QGateWithOrgDto gate = db.qualityGates().insertQualityGate(organization); - db.qualityGates().setDefaultQualityGate(organization, gate); - - db.qualityGates().addCondition(gate, metric1); - db.qualityGates().addCondition(gate, metric2); - - QualityGate result = underTest.loadQualityGate(db.getSession(), organization, project, branch); - assertThat(result.getConditions()).extracting(Condition::getMetricKey).containsExactly("new_metric"); - } - - @Test - public void loadQualityGate_returns_hardcoded_gate_for_pull_requests() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertPublicProject(organization); - - BranchDto branch = newBranchDto(project).setBranchType(BranchType.SHORT); - db.components().insertProjectBranch(project, branch); - MetricDto metric1 = db.measures().insertMetric(m -> m.setKey("new_metric")); - MetricDto metric2 = db.measures().insertMetric(m -> m.setKey("metric")); - - QGateWithOrgDto gate = db.qualityGates().insertQualityGate(organization); - db.qualityGates().setDefaultQualityGate(organization, gate); - - db.qualityGates().addCondition(gate, metric1); - db.qualityGates().addCondition(gate, metric2); - - QualityGate result = underTest.loadQualityGate(db.getSession(), organization, project, branch); - assertThat(result.getConditions()).extracting(Condition::getMetricKey).containsExactly("new_metric"); - } - - @Test - public void loadQualityGate_on_long_branch_returns_organization_default_gate() { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertPublicProject(organization); - BranchDto branch = newBranchDto(project).setBranchType(BranchType.LONG); - db.components().insertProjectBranch(project, branch); - - MetricDto metric = db.measures().insertMetric(); - QGateWithOrgDto gate = db.qualityGates().insertQualityGate(organization); - db.qualityGates().setDefaultQualityGate(organization, gate); - QualityGateConditionDto condition = db.qualityGates().addCondition(gate, metric); - - QualityGate result = underTest.loadQualityGate(db.getSession(), organization, project, branch); - - assertThat(result.getId()).isEqualTo("" + gate.getId()); - assertThat(result.getConditions()) - .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold) - .containsExactlyInAnyOrder( - tuple(metric.getKey(), Condition.Operator.fromDbValue(condition.getOperator()), condition.getErrorThreshold())); - } - - @Test - public void getMetricsRelatedTo() { - Condition condition = new Condition("metric1", Condition.Operator.GREATER_THAN, "10"); - QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition)); - - Set<String> result = underTest.getMetricsRelatedTo(gate); - - assertThat(result).containsExactlyInAnyOrder( - // the metrics needed to compute the status of gate - condition.getMetricKey(), - // generated metrics - CoreMetrics.ALERT_STATUS_KEY, CoreMetrics.QUALITY_GATE_DETAILS_KEY); - } - - @Test - public void refreshGateStatus_generates_gate_related_measures() { - ComponentDto project = ComponentTesting.newPublicProjectDto(newOrganizationDto()); - MetricDto conditionMetric = newMetricDto(); - MetricDto statusMetric = newMetricDto().setKey(CoreMetrics.ALERT_STATUS_KEY); - MetricDto detailsMetric = newMetricDto().setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY); - Condition condition = new Condition(conditionMetric.getKey(), Condition.Operator.GREATER_THAN, "10"); - QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition)); - MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(conditionMetric, statusMetric, detailsMetric), emptyList()); - - EvaluatedQualityGate result = underTest.refreshGateStatus(project, gate, matrix); - - QualityGateEvaluator.Measures measures = qualityGateEvaluator.getCalledMeasures(); - assertThat(measures.get(conditionMetric.getKey())).isEmpty(); - - assertThat(result.getStatus()).isEqualTo(Metric.Level.OK); - assertThat(result.getEvaluatedConditions()) - .extracting(EvaluatedCondition::getStatus) - .containsExactly(EvaluatedCondition.EvaluationStatus.OK); - assertThat(matrix.getMeasure(project, CoreMetrics.ALERT_STATUS_KEY).get().getDataAsString()).isEqualTo(Metric.Level.OK.name()); - assertThat(matrix.getMeasure(project, CoreMetrics.QUALITY_GATE_DETAILS_KEY).get().getDataAsString()) - .isNotEmpty() - // json format - .startsWith("{").endsWith("}"); - } - - @Test - public void refreshGateStatus_provides_measures_to_evaluator() { - ComponentDto project = ComponentTesting.newPublicProjectDto(newOrganizationDto()); - MetricDto numericMetric = newMetricDto().setValueType(Metric.ValueType.FLOAT.name()); - MetricDto numericNewMetric = newMetricDto().setValueType(Metric.ValueType.FLOAT.name()).setKey("new_metric"); - MetricDto stringMetric = newMetricDto().setValueType(Metric.ValueType.STRING.name()); - MetricDto statusMetric = newMetricDto().setKey(CoreMetrics.ALERT_STATUS_KEY); - MetricDto detailsMetric = newMetricDto().setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY); - QualityGate gate = new QualityGate("1", "foo", Collections.emptySet()); - LiveMeasureDto numericMeasure = new LiveMeasureDto().setMetricId(numericMetric.getId()).setValue(1.23).setVariation(4.56).setComponentUuid(project.uuid()); - LiveMeasureDto numericNewMeasure = new LiveMeasureDto().setMetricId(numericNewMetric.getId()).setValue(7.8).setVariation(8.9).setComponentUuid(project.uuid()); - LiveMeasureDto stringMeasure = new LiveMeasureDto().setMetricId(stringMetric.getId()).setData("bar").setComponentUuid(project.uuid()); - MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(statusMetric, detailsMetric, numericMetric, numericNewMetric, stringMetric), - asList(numericMeasure, numericNewMeasure, stringMeasure)); - - underTest.refreshGateStatus(project, gate, matrix); - - QualityGateEvaluator.Measures measures = qualityGateEvaluator.getCalledMeasures(); - - QualityGateEvaluator.Measure loadedStringMeasure = measures.get(stringMetric.getKey()).get(); - assertThat(loadedStringMeasure.getStringValue()).hasValue("bar"); - assertThat(loadedStringMeasure.getValue()).isEmpty(); - assertThat(loadedStringMeasure.getType()).isEqualTo(Metric.ValueType.STRING); - - QualityGateEvaluator.Measure loadedNumericMeasure = measures.get(numericMetric.getKey()).get(); - assertThat(loadedNumericMeasure.getStringValue()).isEmpty(); - assertThat(loadedNumericMeasure.getValue()).hasValue(1.23); - assertThat(loadedNumericMeasure.getType()).isEqualTo(Metric.ValueType.FLOAT); - - QualityGateEvaluator.Measure loadedNumericNewMeasure = measures.get(numericNewMetric.getKey()).get(); - assertThat(loadedNumericNewMeasure.getStringValue()).isEmpty(); - assertThat(loadedNumericNewMeasure.getNewMetricValue()).hasValue(8.9); - assertThat(loadedNumericNewMeasure.getType()).isEqualTo(Metric.ValueType.FLOAT); - } - - private static class TestQualityGateEvaluator implements QualityGateEvaluator { - private Measures measures; - - @Override - public EvaluatedQualityGate evaluate(QualityGate gate, Measures measures) { - checkState(this.measures == null); - this.measures = measures; - EvaluatedQualityGate.Builder builder = EvaluatedQualityGate.newBuilder().setQualityGate(gate).setStatus(Metric.Level.OK); - for (Condition condition : gate.getConditions()) { - builder.addEvaluatedCondition(condition, EvaluatedCondition.EvaluationStatus.OK, "bar"); - } - return builder.build(); - } - - private Measures getCalledMeasures() { - return measures; - } - - @Override - public Set<String> getMetricKeys(QualityGate gate) { - return gate.getConditions().stream().map(Condition::getMetricKey).collect(Collectors.toSet()); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/MeasureMatrixTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/MeasureMatrixTest.java deleted file mode 100644 index 35f25724504..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/MeasureMatrixTest.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.organization.OrganizationDto; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.db.metric.MetricTesting.newMetricDto; -import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; - -public class MeasureMatrixTest { - - private static final OrganizationDto ORGANIZATION = newOrganizationDto(); - private static final ComponentDto PROJECT = ComponentTesting.newPublicProjectDto(ORGANIZATION); - private static final ComponentDto FILE = ComponentTesting.newFileDto(PROJECT); - private static final MetricDto METRIC_1 = newMetricDto().setId(100); - private static final MetricDto METRIC_2 = newMetricDto().setId(200); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void getMetric() { - Collection<MetricDto> metrics = asList(METRIC_1, METRIC_2); - - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT, FILE), metrics, new ArrayList<>()); - - assertThat(underTest.getMetric(METRIC_2.getId())).isSameAs(METRIC_2); - } - - @Test - public void getMetric_fails_if_metric_is_not_registered() { - Collection<MetricDto> metrics = asList(METRIC_1); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT, FILE), metrics, new ArrayList<>()); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("Metric with id " + METRIC_2.getId() + " not found"); - - underTest.getMetric(METRIC_2.getId()); - } - - @Test - public void getValue_returns_empty_if_measure_is_absent() { - MetricDto metric = newMetricDto(); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(null); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - assertThat(underTest.getMeasure(FILE, metric.getKey())).isEmpty(); - } - - @Test - public void getMeasure_throws_IAE_if_metric_is_not_registered() { - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(METRIC_1), emptyList()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Metric with key _missing_ is not registered"); - - underTest.getMeasure(PROJECT, "_missing_"); - } - - @Test - public void setValue_double_rounds_up_and_updates_value() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(1.23); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setValue(PROJECT, metric.getKey(), 3.14159); - - assertThat(underTest.getMeasure(PROJECT, metric.getKey()).get().getValue()).isEqualTo(3.14); - assertThat(underTest.getChanged()).hasSize(1); - - underTest.setValue(PROJECT, metric.getKey(), 3.148); - verifyValue(underTest, PROJECT, metric, 3.15); - verifyVariation(underTest, PROJECT, metric, null); - } - - private void verifyValue(MeasureMatrix underTest, ComponentDto component, MetricDto metric, @Nullable Double expectedValue) { - Optional<LiveMeasureDto> measure = underTest.getMeasure(component, metric.getKey()); - assertThat(measure).isPresent(); - assertThat(measure.get().getValue()).isEqualTo(expectedValue); - } - - private void verifyVariation(MeasureMatrix underTest, ComponentDto component, MetricDto metric, @Nullable Double expectedVariation) { - assertThat(underTest.getMeasure(component, metric.getKey()).get().getVariation()).isEqualTo(expectedVariation); - } - - @Test - public void setValue_double_does_nothing_if_value_is_unchanged() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(3.14); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setValue(PROJECT, metric.getKey(), 3.14159); - - assertThat(underTest.getChanged()).isEmpty(); - verifyValue(underTest, PROJECT, metric, 3.14); - } - - @Test - public void setValue_double_updates_variation() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(3.14).setVariation(1.14); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setValue(PROJECT, metric.getKey(), 3.56); - - assertThat(underTest.getChanged()).hasSize(1); - verifyValue(underTest, PROJECT, metric, 3.56); - verifyVariation(underTest, PROJECT, metric, 3.56 - (3.14 - 1.14)); - } - - @Test - public void setValue_double_rounds_up_variation() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(3.14).setVariation(1.14); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setValue(PROJECT, metric.getKey(), 3.569); - - assertThat(underTest.getChanged()).hasSize(1); - verifyValue(underTest, PROJECT, metric, 3.57); - verifyVariation(underTest, PROJECT, metric, 1.57); - } - - @Test - public void setValue_String_does_nothing_if_value_is_not_changed() { - LiveMeasureDto measure = newMeasure(METRIC_1, PROJECT).setData("foo"); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT, FILE), asList(METRIC_1), asList(measure)); - - underTest.setValue(PROJECT, METRIC_1.getKey(), "foo"); - - assertThat(underTest.getMeasure(PROJECT, METRIC_1.getKey()).get().getDataAsString()).isEqualTo("foo"); - assertThat(underTest.getChanged()).isEmpty(); - } - - @Test - public void setValue_String_updates_value() { - LiveMeasureDto measure = newMeasure(METRIC_1, PROJECT).setData("foo"); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT, FILE), asList(METRIC_1), asList(measure)); - - underTest.setValue(PROJECT, METRIC_1.getKey(), "bar"); - - assertThat(underTest.getMeasure(PROJECT, METRIC_1.getKey()).get().getDataAsString()).isEqualTo("bar"); - assertThat(underTest.getChanged()).extracting(LiveMeasureDto::getDataAsString).containsExactly("bar"); - } - - @Test - public void setLeakValue_rounds_up_and_updates_value() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(null); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setLeakValue(PROJECT, metric.getKey(), 3.14159); - verifyVariation(underTest, PROJECT, metric, 3.14); - // do not update value - verifyValue(underTest, PROJECT, metric, null); - - underTest.setLeakValue(PROJECT, metric.getKey(), 3.148); - verifyVariation(underTest, PROJECT, metric, 3.15); - // do not update value - verifyValue(underTest, PROJECT, metric, null); - } - - @Test - public void setLeakValue_double_does_nothing_if_value_is_unchanged() { - MetricDto metric = newMetricDto().setDecimalScale(2); - LiveMeasureDto measure = newMeasure(metric, PROJECT).setValue(null).setVariation(3.14); - MeasureMatrix underTest = new MeasureMatrix(asList(PROJECT), asList(metric), asList(measure)); - - underTest.setLeakValue(PROJECT, metric.getKey(), 3.14159); - - assertThat(underTest.getChanged()).isEmpty(); - verifyVariation(underTest, PROJECT, metric, 3.14); - } - - private LiveMeasureDto newMeasure(MetricDto metric, ComponentDto component) { - return new LiveMeasureDto().setMetricId(metric.getId()).setData("foo").setComponentUuid(component.uuid()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/TestIssueMetricFormulaFactory.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/TestIssueMetricFormulaFactory.java deleted file mode 100644 index 293e68e7072..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/TestIssueMetricFormulaFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.measure.live; - -import java.util.List; -import java.util.Set; -import org.sonar.api.measures.Metric; - -class TestIssueMetricFormulaFactory implements IssueMetricFormulaFactory { - - private final List<IssueMetricFormula> formulas; - - TestIssueMetricFormulaFactory(List<IssueMetricFormula> formulas) { - this.formulas = formulas; - } - - @Override - public List<IssueMetricFormula> getFormulas() { - return formulas; - } - - @Override - public Set<Metric> getFormulaMetrics() { - return IssueMetricFormulaFactory.extractMetrics(formulas); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ApplyPermissionTemplateQueryTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ApplyPermissionTemplateQueryTest.java deleted file mode 100644 index afa4a39fd03..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ApplyPermissionTemplateQueryTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import java.util.Collections; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.server.exceptions.BadRequestException; - -import static com.google.common.collect.Lists.newArrayList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.permission.ApplyPermissionTemplateQuery.create; - -public class ApplyPermissionTemplateQueryTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void should_populate_with_params() { - ApplyPermissionTemplateQuery query = create("my_template_key", newArrayList("1", "2", "3")); - - assertThat(query.getTemplateUuid()).isEqualTo("my_template_key"); - assertThat(query.getComponentKeys()).containsOnly("1", "2", "3"); - } - - @Test - public void should_invalidate_query_with_empty_name() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission template is mandatory"); - - ApplyPermissionTemplateQuery.create("", newArrayList("1", "2", "3")); - } - - @Test - public void should_invalidate_query_with_no_components() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("No project provided. Please provide at least one project."); - - ApplyPermissionTemplateQuery.create("my_template_key", Collections.emptyList()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverImplTest.java deleted file mode 100644 index 76af5bbe7a2..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverImplTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import java.util.stream.Stream; -import org.junit.Test; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypeTree; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.db.organization.DefaultTemplates; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultTemplatesResolverImplTest { - - private static final ResourceTypes RESOURCE_TYPES_WITHOUT_VIEWS = new ResourceTypes(new ResourceTypeTree[] { - ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build() - }); - private static final ResourceTypes RESOURCE_TYPES_WITH_VIEWS = new ResourceTypes(new ResourceTypeTree[] { - ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build(), - ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.VIEW).build()).build() - }); - private DefaultTemplatesResolverImpl underTestWithoutViews = new DefaultTemplatesResolverImpl(RESOURCE_TYPES_WITHOUT_VIEWS); - private DefaultTemplatesResolverImpl underTestWithViews = new DefaultTemplatesResolverImpl(RESOURCE_TYPES_WITH_VIEWS); - - @Test - public void project_is_project_of_DefaultTemplates_no_matter_if_views_is_installed() { - Stream.of( - new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid(null), - new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid("bar")).forEach( - defaultTemplates -> { - assertThat(underTestWithoutViews.resolve(defaultTemplates).getProject()).isEqualTo("foo"); - assertThat(underTestWithViews.resolve(defaultTemplates).getProject()).isEqualTo("foo"); - }); - } - - @Test - public void view_is_empty_no_matter_view_in_DefaultTemplates_if_views_is_not_installed() { - DefaultTemplates defaultTemplatesNoView = new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid(null); - DefaultTemplates defaultTemplatesView = new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid("bar"); - - assertThat(underTestWithoutViews.resolve(defaultTemplatesNoView).getApplication()).isEmpty(); - assertThat(underTestWithoutViews.resolve(defaultTemplatesView).getApplication()).isEmpty(); - } - - @Test - public void view_is_project_of_DefaultTemplates_if_view_in_DefaultTemplates_is_null_and_views_is_installed() { - DefaultTemplates defaultTemplates = new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid(null); - - assertThat(underTestWithViews.resolve(defaultTemplates).getApplication()).contains("foo"); - } - - @Test - public void view_is_view_of_DefaultTemplates_if_view_in_DefaultTemplates_is_not_null_and_views_is_installed() { - DefaultTemplates defaultTemplates = new DefaultTemplates().setProjectUuid("foo").setApplicationsUuid("bar"); - - assertThat(underTestWithViews.resolve(defaultTemplates).getApplication()).contains("bar"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverRule.java b/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverRule.java deleted file mode 100644 index 87b5529db46..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverRule.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import org.junit.rules.ExternalResource; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypeTree; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.db.organization.DefaultTemplates; - -import static org.sonar.api.resources.Qualifiers.APP; -import static org.sonar.api.resources.Qualifiers.PROJECT; -import static org.sonar.api.resources.Qualifiers.VIEW; - -public class DefaultTemplatesResolverRule extends ExternalResource implements DefaultTemplatesResolver { - private static final DefaultTemplatesResolver WITH_GOV = new DefaultTemplatesResolverImpl( - new ResourceTypes(new ResourceTypeTree[] { - ResourceTypeTree.builder() - .addType(ResourceType.builder(PROJECT).build()) - .build(), - ResourceTypeTree.builder() - .addType(ResourceType.builder(VIEW).build()) - .build(), - ResourceTypeTree.builder() - .addType(ResourceType.builder(APP).build()) - .build() - })); - private static final DefaultTemplatesResolver WITHOUT_GOV = new DefaultTemplatesResolverImpl( - new ResourceTypes(new ResourceTypeTree[] {ResourceTypeTree.builder() - .addType(ResourceType.builder(PROJECT).build()) - .build()})); - - private final boolean governanceInitiallyInstalled; - private boolean governanceInstalled; - - private DefaultTemplatesResolverRule(boolean governanceInitiallyInstalled) { - this.governanceInitiallyInstalled = governanceInitiallyInstalled; - this.governanceInstalled = governanceInitiallyInstalled; - } - - @Override - protected void before() { - this.governanceInstalled = governanceInitiallyInstalled; - } - - public void installGovernance() { - this.governanceInstalled = true; - } - - public void uninstallGovernance() { - this.governanceInstalled = false; - } - - public static DefaultTemplatesResolverRule withoutGovernance() { - return new DefaultTemplatesResolverRule(false); - } - - public static DefaultTemplatesResolverRule withGovernance() { - return new DefaultTemplatesResolverRule(true); - } - - @Override - public DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates) { - if (governanceInstalled) { - return WITH_GOV.resolve(defaultTemplates); - } - return WITHOUT_GOV.resolve(defaultTemplates); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/GroupPermissionChangerTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/GroupPermissionChangerTest.java deleted file mode 100644 index b6f9600af1a..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/GroupPermissionChangerTest.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import org.apache.commons.lang.StringUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ResourceTypesRule; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.permission.GroupPermissionDto; -import org.sonar.db.permission.OrganizationPermission; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.BadRequestException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; -import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; - -public class GroupPermissionChangerTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT); - private PermissionService permissionService = new PermissionServiceImpl(resourceTypes); - private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient()); - private OrganizationDto org; - private GroupDto group; - private ComponentDto privateProject; - private ComponentDto publicProject; - - @Before - public void setUp() throws Exception { - org = db.organizations().insert(); - group = db.users().insertGroup(org, "a-group"); - privateProject = db.components().insertPrivateProject(org); - publicProject = db.components().insertPublicProject(org); - } - - @Test - public void apply_adds_organization_permission_to_group() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); - } - - @Test - public void apply_adds_organization_permission_to_group_AnyOne() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); - } - - @Test - public void apply_fails_with_BadRequestException_when_adding_any_permission_to_group_AnyOne_on_private_project() { - GroupIdOrAnyone anyOneGroupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - permissionService.getAllProjectPermissions() - .forEach(perm -> { - try { - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, perm, new ProjectId(privateProject), anyOneGroupId, permissionService)); - fail("a BadRequestException should have been thrown"); - } catch (BadRequestException e) { - assertThat(e).hasMessage("No permission can be granted to Anyone on a private component"); - } - }); - } - - @Test - public void apply_has_no_effect_when_removing_any_permission_to_group_AnyOne_on_private_project() { - permissionService.getAllProjectPermissions() - .forEach(this::unsafeInsertProjectPermissionOnAnyone); - - GroupIdOrAnyone anyOneGroupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - permissionService.getAllProjectPermissions() - .forEach(perm -> { - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, perm, new ProjectId(privateProject), anyOneGroupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, privateProject)).contains(perm); - }); - } - - @Test - public void apply_adds_permission_USER_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.USER); - } - - @Test - public void apply_adds_permission_CODEVIEWER_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.CODEVIEWER); - } - - @Test - public void apply_adds_permission_ADMIN_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.ADMIN); - } - - @Test - public void apply_adds_permission_ISSUE_ADMIN_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.ISSUE_ADMIN); - } - - @Test - public void apply_adds_permission_SCAN_EXECUTION_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(GlobalPermissions.SCAN_EXECUTION); - } - - private void applyAddsPermissionToGroupOnPrivateProject(String permission) { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, permission, new ProjectId(privateProject), groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission); - } - - @Test - public void apply_removes_permission_USER_from_group_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.USER); - } - - @Test - public void apply_removes_permission_CODEVIEWER_from_group_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.CODEVIEWER); - } - - @Test - public void apply_removes_permission_ADMIN_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.ADMIN); - } - - @Test - public void apply_removes_permission_ISSUE_ADMIN_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.ISSUE_ADMIN); - } - - @Test - public void apply_removes_permission_SCAN_EXECUTION_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(GlobalPermissions.SCAN_EXECUTION); - } - - private void applyRemovesPermissionFromGroupOnPrivateProject(String permission) { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertProjectPermissionOnGroup(group, permission, privateProject); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, permission, new ProjectId(privateProject), groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission); - } - - @Test - public void apply_has_no_effect_when_adding_USER_permission_to_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.USER, new ProjectId(publicProject), groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, publicProject)).isEmpty(); - } - - @Test - public void apply_has_no_effect_when_adding_CODEVIEWER_permission_to_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.CODEVIEWER, new ProjectId(publicProject), groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, publicProject)).isEmpty(); - } - - @Test - public void apply_fails_with_BadRequestException_when_adding_permission_ADMIN_to_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("It is not possible to add the 'admin' permission to group 'Anyone'"); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ADMIN, new ProjectId(publicProject), groupId, permissionService)); - } - - @Test - public void apply_adds_permission_ISSUE_ADMIN_to_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectId(publicProject), groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, publicProject)).containsOnly(UserRole.ISSUE_ADMIN); - } - - @Test - public void apply_adds_permission_SCAN_EXECUTION_to_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.SCAN_EXECUTION, new ProjectId(publicProject), groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, publicProject)).containsOnly(GlobalPermissions.SCAN_EXECUTION); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_USER_permission_from_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission user can't be removed from a public component"); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.USER, new ProjectId(publicProject), groupId, permissionService)); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_CODEVIEWER_permission_from_group_AnyOne_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission codeviewer can't be removed from a public component"); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.CODEVIEWER, new ProjectId(publicProject), groupId, permissionService)); - } - - @Test - public void apply_removes_ADMIN_permission_from_group_AnyOne_on_a_public_project() { - applyRemovesPermissionFromGroupAnyOneOnAPublicProject(UserRole.ADMIN); - } - - @Test - public void apply_removes_ISSUE_ADMIN_permission_from_group_AnyOne_on_a_public_project() { - applyRemovesPermissionFromGroupAnyOneOnAPublicProject(UserRole.ISSUE_ADMIN); - } - - @Test - public void apply_removes_SCAN_EXECUTION_permission_from_group_AnyOne_on_a_public_project() { - applyRemovesPermissionFromGroupAnyOneOnAPublicProject(GlobalPermissions.SCAN_EXECUTION); - } - - private void applyRemovesPermissionFromGroupAnyOneOnAPublicProject(String permission) { - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(org.getUuid()); - db.users().insertProjectPermissionOnAnyone(permission, publicProject); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, permission, new ProjectId(publicProject), groupId, permissionService)); - - assertThat(db.users().selectAnyonePermissions(org, publicProject)).isEmpty(); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_USER_permission_from_a_group_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission user can't be removed from a public component"); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.USER, new ProjectId(publicProject), groupId, permissionService)); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_CODEVIEWER_permission_from_a_group_on_a_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission codeviewer can't be removed from a public component"); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.CODEVIEWER, new ProjectId(publicProject), groupId, permissionService)); - } - - @Test - public void add_permission_to_anyone() { - OrganizationDto defaultOrganization = db.getDefaultOrganization(); - GroupIdOrAnyone groupId = GroupIdOrAnyone.forAnyone(defaultOrganization.getUuid()); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); - assertThat(db.users().selectAnyonePermissions(defaultOrganization, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN); - } - - @Test - public void do_nothing_when_adding_permission_that_already_exists() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); - - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, ADMINISTER_QUALITY_GATES.getKey(), null, groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(ADMINISTER_QUALITY_GATES.getKey()); - } - - @Test - public void fail_to_add_global_permission_but_SCAN_and_ADMIN_on_private_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - permissionService.getAllOrganizationPermissions().stream() - .map(OrganizationPermission::getKey) - .filter(perm -> !UserRole.ADMIN.equals(perm) && !GlobalPermissions.SCAN_EXECUTION.equals(perm)) - .forEach(perm -> { - try { - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, perm, new ProjectId(privateProject), groupId, permissionService)); - fail("a BadRequestException should have been thrown for permission " + perm); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid project permission '" + perm + - "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); - } - }); - } - - @Test - public void fail_to_add_global_permission_but_SCAN_and_ADMIN_on_public_project() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - permissionService.getAllOrganizationPermissions().stream() - .map(OrganizationPermission::getKey) - .filter(perm -> !UserRole.ADMIN.equals(perm) && !GlobalPermissions.SCAN_EXECUTION.equals(perm)) - .forEach(perm -> { - try { - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, perm, new ProjectId(publicProject), groupId, permissionService)); - fail("a BadRequestException should have been thrown for permission " + perm); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid project permission '" + perm + - "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); - } - }); - } - - @Test - public void fail_to_add_project_permission_but_SCAN_and_ADMIN_on_global_group() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - permissionService.getAllProjectPermissions() - .stream() - .filter(perm -> !GlobalPermissions.SCAN_EXECUTION.equals(perm) && !OrganizationPermission.ADMINISTER.getKey().equals(perm)) - .forEach(permission -> { - try { - apply(new GroupPermissionChange(PermissionChange.Operation.ADD, permission, null, groupId, permissionService)); - fail("a BadRequestException should have been thrown for permission " + permission); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid global permission '" + permission + "'. Valid values are [admin, gateadmin, profileadmin, provisioning, scan]"); - } - }); - } - - @Test - public void remove_permission_from_group() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); - db.users().insertPermissionOnGroup(group, PROVISION_PROJECTS); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, ADMINISTER_QUALITY_GATES.getKey(), null, groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(PROVISION_PROJECTS.getKey()); - } - - @Test - public void remove_project_permission_from_group() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); - db.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, privateProject); - db.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, privateProject); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectId(privateProject), groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(ADMINISTER_QUALITY_GATES.getKey()); - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(UserRole.CODEVIEWER); - } - - @Test - public void do_not_fail_if_removing_a_permission_that_does_not_exist() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectId(privateProject), groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); - assertThat(db.users().selectGroupPermissions(group, privateProject)).isEmpty(); - } - - @Test - public void fail_to_remove_admin_permission_if_no_more_admins() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertPermissionOnGroup(group, ADMINISTER); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Last group with permission 'admin'. Permission cannot be removed."); - - underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.REMOVE, ADMINISTER.getKey(), null, groupId, permissionService)); - } - - @Test - public void remove_admin_group_if_still_other_admins() { - GroupIdOrAnyone groupId = GroupIdOrAnyone.from(group); - db.users().insertPermissionOnGroup(group, ADMINISTER); - UserDto admin = db.users().insertUser(); - db.users().insertPermissionOnUser(org, admin, ADMINISTER); - - apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, ADMINISTER.getKey(), null, groupId, permissionService)); - - assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); - } - - private void apply(GroupPermissionChange change) { - underTest.apply(db.getSession(), change); - db.commit(); - } - - private void unsafeInsertProjectPermissionOnAnyone(String perm) { - GroupPermissionDto dto = new GroupPermissionDto() - .setOrganizationUuid(privateProject.getOrganizationUuid()) - .setGroupId(null) - .setRole(perm) - .setResourceId(privateProject.getId()); - db.getDbClient().groupPermissionDao().insert(db.getSession(), dto); - db.commit(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java deleted file mode 100644 index 2bc2f07606b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import java.util.List; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.web.UserRole; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ResourceTypesRule; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.permission.template.PermissionTemplateDbTester; -import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.es.ProjectIndexers; -import org.sonar.server.es.TestProjectIndexers; -import org.sonar.server.tester.UserSessionRule; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; -import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; -import static org.sonar.db.permission.OrganizationPermission.SCAN; - -public class PermissionTemplateServiceTest { - - @Rule - public ExpectedException throwable = ExpectedException.none(); - @Rule - public DbTester dbTester = DbTester.create(new AlwaysIncreasingSystem2()); - @Rule - public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withGovernance(); - - private ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT); - private PermissionService permissionService = new PermissionServiceImpl(resourceTypes); - - private UserSessionRule userSession = UserSessionRule.standalone(); - private PermissionTemplateDbTester templateDb = dbTester.permissionTemplates(); - private DbSession session = dbTester.getSession(); - private ProjectIndexers projectIndexers = new TestProjectIndexers(); - - private PermissionTemplateService underTest = new PermissionTemplateService(dbTester.getDbClient(), projectIndexers, userSession, defaultTemplatesResolver); - - @Test - public void apply_does_not_insert_permission_to_group_AnyOne_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(privateProject)); - - assertThat(selectProjectPermissionsOfGroup(organization, null, privateProject)).isEmpty(); - } - - @Test - public void apply_default_does_not_insert_permission_to_group_AnyOne_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - UserDto creator = dbTester.users().insertUser(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, privateProject, creator.getId()); - - assertThat(selectProjectPermissionsOfGroup(organization, null, privateProject)).isEmpty(); - } - - @Test - public void apply_inserts_permissions_to_group_AnyOne_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, perm)); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); - - assertThat(selectProjectPermissionsOfGroup(organization, null, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_permissions_to_group_AnyOne_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, perm)); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, publicProject, null); - - assertThat(selectProjectPermissionsOfGroup(organization, null, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void apply_inserts_any_permissions_to_group_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - GroupDto group = dbTester.users().insertGroup(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, perm)); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(privateProject)); - - assertThat(selectProjectPermissionsOfGroup(organization, group, privateProject)) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_any_permissions_to_group_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - GroupDto group = dbTester.users().insertGroup(organization); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, perm)); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, privateProject, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, privateProject)) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void apply_inserts_permissions_to_group_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - GroupDto group = dbTester.users().insertGroup(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, perm)); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); - - assertThat(selectProjectPermissionsOfGroup(organization, group, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_permissions_to_group_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - GroupDto group = dbTester.users().insertGroup(organization); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, perm)); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, publicProject, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void apply_inserts_permissions_to_user_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, perm)); - dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); - - assertThat(selectProjectPermissionsOfUser(user, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_permissions_to_user_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, perm)); - dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, publicProject, null); - - assertThat(selectProjectPermissionsOfUser(user, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void apply_inserts_any_permissions_to_user_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, perm)); - dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "p1"); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(privateProject)); - - assertThat(selectProjectPermissionsOfUser(user, privateProject)) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_any_permissions_to_user_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, perm)); - dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, privateProject, null); - - assertThat(selectProjectPermissionsOfUser(user, privateProject)) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_permissions_to_ProjectCreator_but_USER_and_CODEVIEWER_when_applying_template_on_public_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto publicProject = dbTester.components().insertPublicProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, perm)); - dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, publicProject, user.getId()); - - assertThat(selectProjectPermissionsOfUser(user, publicProject)) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void applyDefault_inserts_any_permissions_to_ProjectCreator_when_applying_template_on_private_project() { - OrganizationDto organization = dbTester.organizations().insert(); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - ComponentDto privateProject = dbTester.components().insertPrivateProject(organization); - UserDto user = dbTester.users().insertUser(); - permissionService.getAllProjectPermissions() - .forEach(perm -> dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, perm)); - dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, "p1"); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, privateProject, user.getId()); - - assertThat(selectProjectPermissionsOfUser(user, privateProject)) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, SCAN.getKey()); - } - - @Test - public void apply_template_on_view() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto view = dbTester.components().insertView(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, view, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, view)) - .containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_default_template_on_application() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto view = dbTester.components().insertPublicApplication(organization); - PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - PermissionTemplateDto appPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(appPermissionTemplate, group, ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(appPermissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), appPermissionTemplate.getUuid(), null); - - underTest.applyDefault(session, view, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, view)) - .containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_default_template_on_portfolio() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto view = dbTester.components().insertPublicPortfolio(organization); - PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - PermissionTemplateDto portPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(portPermissionTemplate, group, ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(portPermissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), null, portPermissionTemplate.getUuid()); - - underTest.applyDefault(session, view, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, view)) - .containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_project_default_template_on_view_when_no_view_default_template() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto view = dbTester.components().insertView(organization); - PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(projectPermissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, view, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, view)).containsOnly(PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_template_on_applications() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto application = dbTester.components().insertApplication(organization); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, application, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, application)) - .containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_default_view_template_on_application() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto application = dbTester.components().insertApplication(organization); - PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - PermissionTemplateDto appPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - PermissionTemplateDto portPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(appPermissionTemplate, group, ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(appPermissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), appPermissionTemplate.getUuid(), portPermissionTemplate.getUuid()); - - underTest.applyDefault(session, application, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, application)) - .containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_project_default_template_on_application_when_no_application_default_template() { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto application = dbTester.components().insertApplication(organization); - PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - GroupDto group = dbTester.users().insertGroup(organization); - dbTester.permissionTemplates().addGroupToTemplate(projectPermissionTemplate, group, PROVISION_PROJECTS.getKey()); - dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), null, null); - - underTest.applyDefault(session, application, null); - - assertThat(selectProjectPermissionsOfGroup(organization, group, application)).containsOnly(PROVISION_PROJECTS.getKey()); - } - - @Test - public void apply_permission_template() { - OrganizationDto organization = dbTester.organizations().insert(); - UserDto user = dbTester.users().insertUser(); - ComponentDto project = dbTester.components().insertPrivateProject(organization); - GroupDto adminGroup = dbTester.users().insertGroup(organization); - GroupDto userGroup = dbTester.users().insertGroup(organization); - dbTester.users().insertPermissionOnGroup(adminGroup, "admin"); - dbTester.users().insertPermissionOnGroup(userGroup, "user"); - dbTester.users().insertPermissionOnUser(organization, user, "admin"); - PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, "admin"); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, "issueadmin"); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, "user"); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, "codeviewer"); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "user"); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "codeviewer"); - dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "admin"); - - assertThat(selectProjectPermissionsOfGroup(organization, adminGroup, project)).isEmpty(); - assertThat(selectProjectPermissionsOfGroup(organization, userGroup, project)).isEmpty(); - assertThat(selectProjectPermissionsOfGroup(organization, null, project)).isEmpty(); - assertThat(selectProjectPermissionsOfUser(user, project)).isEmpty(); - - underTest.applyAndCommit(session, permissionTemplate, singletonList(project)); - - assertThat(selectProjectPermissionsOfGroup(organization, adminGroup, project)).containsOnly("admin", "issueadmin"); - assertThat(selectProjectPermissionsOfGroup(organization, userGroup, project)).containsOnly("user", "codeviewer"); - assertThat(selectProjectPermissionsOfGroup(organization, null, project)).isEmpty(); - assertThat(selectProjectPermissionsOfUser(user, project)).containsOnly("admin"); - } - - private List<String> selectProjectPermissionsOfGroup(OrganizationDto organizationDto, @Nullable GroupDto groupDto, ComponentDto project) { - return dbTester.getDbClient().groupPermissionDao().selectProjectPermissionsOfGroup(session, - organizationDto.getUuid(), groupDto != null ? groupDto.getId() : null, project.getId()); - } - - private List<String> selectProjectPermissionsOfUser(UserDto userDto, ComponentDto project) { - return dbTester.getDbClient().userPermissionDao().selectProjectPermissionsOfUser(session, - userDto.getId(), project.getId()); - } - - @Test - public void would_user_have_scan_permission_with_default_permission_template() { - OrganizationDto organization = dbTester.organizations().insert(); - GroupDto group = dbTester.users().insertGroup(organization); - UserDto user = dbTester.users().insertUser(); - dbTester.users().insertMember(group, user); - PermissionTemplateDto template = templateDb.insertTemplate(organization); - dbTester.organizations().setDefaultTemplates(template, null, null); - templateDb.addProjectCreatorToTemplate(template.getId(), SCAN.getKey()); - templateDb.addUserToTemplate(template.getId(), user.getId(), UserRole.USER); - templateDb.addGroupToTemplate(template.getId(), group.getId(), UserRole.CODEVIEWER); - templateDb.addGroupToTemplate(template.getId(), null, UserRole.ISSUE_ADMIN); - - // authenticated user - checkWouldUserHaveScanPermission(organization, user.getId(), true); - - // anonymous user - checkWouldUserHaveScanPermission(organization, null, false); - } - - @Test - public void would_user_have_scan_permission_with_unknown_default_permission_template() { - dbTester.organizations().setDefaultTemplates(dbTester.getDefaultOrganization(), "UNKNOWN_TEMPLATE_UUID", null, null); - - checkWouldUserHaveScanPermission(dbTester.getDefaultOrganization(), null, false); - } - - @Test - public void would_user_have_scan_permission_with_empty_template() { - PermissionTemplateDto template = templateDb.insertTemplate(dbTester.getDefaultOrganization()); - dbTester.organizations().setDefaultTemplates(template, null, null); - - checkWouldUserHaveScanPermission(dbTester.getDefaultOrganization(), null, false); - } - - private void checkWouldUserHaveScanPermission(OrganizationDto organization, @Nullable Integer userId, boolean expectedResult) { - assertThat(underTest.wouldUserHaveScanPermissionWithDefaultTemplate(session, organization.getUuid(), userId, "PROJECT_KEY")) - .isEqualTo(expectedResult); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/UserPermissionChangerTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/UserPermissionChangerTest.java deleted file mode 100644 index 41d48efd496..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/UserPermissionChangerTest.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.permission; - -import org.apache.commons.lang.StringUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ResourceTypesRule; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.permission.OrganizationPermission; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.BadRequestException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; -import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; -import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; -import static org.sonar.db.permission.OrganizationPermission.SCAN; -import static org.sonar.server.permission.PermissionChange.Operation.ADD; -import static org.sonar.server.permission.PermissionChange.Operation.REMOVE; - -public class UserPermissionChangerTest { - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT); - private PermissionService permissionService = new PermissionServiceImpl(resourceTypes); - private UserPermissionChanger underTest = new UserPermissionChanger(db.getDbClient()); - private OrganizationDto org1; - private OrganizationDto org2; - private UserDto user1; - private UserDto user2; - private ComponentDto privateProject; - private ComponentDto publicProject; - - @Before - public void setUp() throws Exception { - org1 = db.organizations().insert(); - org2 = db.organizations().insert(); - user1 = db.users().insertUser(); - user2 = db.users().insertUser(); - privateProject = db.components().insertPrivateProject(org1); - publicProject = db.components().insertPublicProject(org1); - } - - @Test - public void apply_adds_any_organization_permission_to_user() { - permissionService.getAllOrganizationPermissions().stream() - .forEach(perm -> { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), perm.getKey(), null, UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).contains(perm); - }); - } - - @Test - public void apply_removes_any_organization_permission_to_user() { - // give ADMIN perm to user2 so that user1 is not the only one with this permission and it can be removed from user1 - db.users().insertPermissionOnUser(org1, user2, OrganizationPermission.ADMINISTER); - permissionService.getAllOrganizationPermissions().stream() - .forEach(perm -> db.users().insertPermissionOnUser(org1, user1, perm)); - assertThat(db.users().selectPermissionsOfUser(user1, org1)) - .containsOnly(permissionService.getAllOrganizationPermissions().toArray(new OrganizationPermission[0])); - - permissionService.getAllOrganizationPermissions().stream() - .forEach(perm -> { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), perm.getKey(), null, UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).doesNotContain(perm); - }); - } - - @Test - public void apply_has_no_effect_when_adding_permission_USER_on_a_public_project() { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), USER, new ProjectId(publicProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, publicProject)).doesNotContain(USER); - } - - @Test - public void apply_has_no_effect_when_adding_permission_CODEVIEWER_on_a_public_project() { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), CODEVIEWER, new ProjectId(publicProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, publicProject)).doesNotContain(CODEVIEWER); - } - - @Test - public void apply_adds_permission_ADMIN_on_a_public_project() { - applyAddsPermissionOnAPublicProject(ADMIN); - } - - @Test - public void apply_adds_permission_ISSUE_ADMIN_on_a_public_project() { - applyAddsPermissionOnAPublicProject(ISSUE_ADMIN); - } - - @Test - public void apply_adds_permission_SCAN_EXECUTION_on_a_public_project() { - applyAddsPermissionOnAPublicProject(SCAN_EXECUTION); - } - - private void applyAddsPermissionOnAPublicProject(String permission) { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), permission, new ProjectId(publicProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, publicProject)).containsOnly(permission); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_permission_USER_from_a_public_project() { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), USER, new ProjectId(publicProject), UserId.from(user1), permissionService); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission user can't be removed from a public component"); - - apply(change); - } - - @Test - public void apply_fails_with_BadRequestException_when_removing_permission_CODEVIEWER_from_a_public_project() { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), CODEVIEWER, new ProjectId(publicProject), UserId.from(user1), permissionService); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Permission codeviewer can't be removed from a public component"); - - apply(change); - } - - @Test - public void apply_removes_permission_ADMIN_from_a_public_project() { - applyRemovesPermissionFromPublicProject(ADMIN); - } - - @Test - public void apply_removes_permission_ISSUE_ADMIN_from_a_public_project() { - applyRemovesPermissionFromPublicProject(ISSUE_ADMIN); - } - - @Test - public void apply_removes_permission_SCAN_EXECUTION_from_a_public_project() { - applyRemovesPermissionFromPublicProject(SCAN_EXECUTION); - } - - private void applyRemovesPermissionFromPublicProject(String permission) { - db.users().insertProjectPermissionOnUser(user1, permission, publicProject); - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), permission, new ProjectId(publicProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, publicProject)).isEmpty(); - } - - @Test - public void apply_adds_any_permission_to_a_private_project() { - permissionService.getAllProjectPermissions() - .forEach(permission -> { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), permission, new ProjectId(privateProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).contains(permission); - }); - } - - @Test - public void apply_removes_any_permission_from_a_private_project() { - permissionService.getAllProjectPermissions() - .forEach(permission -> db.users().insertProjectPermissionOnUser(user1, permission, privateProject)); - - permissionService.getAllProjectPermissions() - .forEach(permission -> { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), permission, new ProjectId(privateProject), UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).doesNotContain(permission); - }); - } - - @Test - public void add_global_permission_to_user() { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), SCAN_EXECUTION, null, UserId.from(user1), permissionService); - - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).containsOnly(SCAN); - assertThat(db.users().selectPermissionsOfUser(user1, org2)).isEmpty(); - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).isEmpty(); - assertThat(db.users().selectPermissionsOfUser(user2, org1)).isEmpty(); - assertThat(db.users().selectProjectPermissionsOfUser(user2, privateProject)).isEmpty(); - } - - @Test - public void add_project_permission_to_user() { - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), ISSUE_ADMIN, new ProjectId(privateProject), UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).isEmpty(); - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).contains(ISSUE_ADMIN); - assertThat(db.users().selectPermissionsOfUser(user2, org1)).isEmpty(); - assertThat(db.users().selectProjectPermissionsOfUser(user2, privateProject)).isEmpty(); - } - - @Test - public void do_nothing_when_adding_global_permission_that_already_exists() { - db.users().insertPermissionOnUser(org1, user1, ADMINISTER_QUALITY_GATES); - - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), QUALITY_GATE_ADMIN, null, UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).containsOnly(ADMINISTER_QUALITY_GATES); - } - - @Test - public void fail_to_add_global_permission_on_project() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Invalid project permission 'gateadmin'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); - - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), QUALITY_GATE_ADMIN, new ProjectId(privateProject), UserId.from(user1), permissionService); - apply(change); - } - - @Test - public void fail_to_add_project_permission_on_organization() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, gateadmin, profileadmin, provisioning, scan]"); - - UserPermissionChange change = new UserPermissionChange(ADD, org1.getUuid(), ISSUE_ADMIN, null, UserId.from(user1), permissionService); - apply(change); - } - - @Test - public void remove_global_permission_from_user() { - db.users().insertPermissionOnUser(org1, user1, QUALITY_GATE_ADMIN); - db.users().insertPermissionOnUser(org1, user1, SCAN_EXECUTION); - db.users().insertPermissionOnUser(org2, user1, QUALITY_GATE_ADMIN); - db.users().insertPermissionOnUser(org1, user2, QUALITY_GATE_ADMIN); - db.users().insertProjectPermissionOnUser(user1, ISSUE_ADMIN, privateProject); - - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), QUALITY_GATE_ADMIN, null, UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).containsOnly(SCAN); - assertThat(db.users().selectPermissionsOfUser(user1, org2)).containsOnly(ADMINISTER_QUALITY_GATES); - assertThat(db.users().selectPermissionsOfUser(user2, org1)).containsOnly(ADMINISTER_QUALITY_GATES); - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).containsOnly(ISSUE_ADMIN); - } - - @Test - public void remove_project_permission_from_user() { - ComponentDto project2 = db.components().insertPrivateProject(org1); - db.users().insertPermissionOnUser(user1, ADMINISTER_QUALITY_GATES); - db.users().insertProjectPermissionOnUser(user1, ISSUE_ADMIN, privateProject); - db.users().insertProjectPermissionOnUser(user1, USER, privateProject); - db.users().insertProjectPermissionOnUser(user2, ISSUE_ADMIN, privateProject); - db.users().insertProjectPermissionOnUser(user1, ISSUE_ADMIN, project2); - - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), ISSUE_ADMIN, new ProjectId(privateProject), UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).containsOnly(USER); - assertThat(db.users().selectProjectPermissionsOfUser(user2, privateProject)).containsOnly(ISSUE_ADMIN); - assertThat(db.users().selectProjectPermissionsOfUser(user1, project2)).containsOnly(ISSUE_ADMIN); - } - - @Test - public void do_not_fail_if_removing_a_global_permission_that_does_not_exist() { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), QUALITY_GATE_ADMIN, null, UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).isEmpty(); - } - - @Test - public void do_not_fail_if_removing_a_project_permission_that_does_not_exist() { - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), ISSUE_ADMIN, new ProjectId(privateProject), UserId.from(user1), permissionService); - apply(change); - - assertThat(db.users().selectProjectPermissionsOfUser(user1, privateProject)).isEmpty(); - } - - @Test - public void fail_to_remove_admin_global_permission_if_no_more_admins() { - db.users().insertPermissionOnUser(org1, user1, SYSTEM_ADMIN); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Last user with permission 'admin'. Permission cannot be removed."); - - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), SYSTEM_ADMIN, null, UserId.from(user1), permissionService); - underTest.apply(db.getSession(), change); - } - - @Test - public void remove_admin_user_if_still_other_admins() { - db.users().insertPermissionOnUser(org1, user1, ADMINISTER); - GroupDto admins = db.users().insertGroup(org1, "admins"); - db.users().insertMember(admins, user2); - db.users().insertPermissionOnGroup(admins, ADMINISTER); - - UserPermissionChange change = new UserPermissionChange(REMOVE, org1.getUuid(), ADMINISTER.getKey(), null, UserId.from(user1), permissionService); - underTest.apply(db.getSession(), change); - - assertThat(db.users().selectPermissionsOfUser(user1, org1)).isEmpty(); - } - - private void apply(UserPermissionChange change) { - underTest.apply(db.getSession(), change); - db.commit(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java index 812b3d9254b..884c7d343de 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java @@ -25,6 +25,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; +import org.sonar.server.setting.SettingsChangeNotifier; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/SettingsChangeNotifierTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/SettingsChangeNotifierTest.java deleted file mode 100644 index 973f8e73d64..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/SettingsChangeNotifierTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.platform; - -import org.junit.Test; -import org.sonar.api.config.GlobalPropertyChangeHandler; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class SettingsChangeNotifierTest { - @Test - public void onGlobalPropertyChange() { - GlobalPropertyChangeHandler handler = mock(GlobalPropertyChangeHandler.class); - SettingsChangeNotifier notifier = new SettingsChangeNotifier(new GlobalPropertyChangeHandler[] {handler}); - - notifier.onGlobalPropertyChange("foo", "bar"); - - verify(handler).onChange(argThat(change -> change.getKey().equals("foo") && change.getNewValue().equals("bar"))); - } - - @Test - public void no_handlers() { - SettingsChangeNotifier notifier = new SettingsChangeNotifier(); - - assertThat(notifier.changeHandlers).isEmpty(); - - // does not fail - notifier.onGlobalPropertyChange("foo", "bar"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java deleted file mode 100644 index f984cd9bd1e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import com.google.common.base.Optional; -import java.io.File; -import java.net.URI; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.mockito.ArgumentMatcher; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.utils.HttpDownloader; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static com.google.common.collect.Lists.newArrayList; -import static org.apache.commons.io.FileUtils.copyFileToDirectory; -import static org.apache.commons.io.FileUtils.touch; -import static org.apache.commons.io.FilenameUtils.separatorsToUnix; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.updatecenter.common.Version.create; - -public class PluginDownloaderTest { - - @Rule - public TemporaryFolder testFolder = new TemporaryFolder(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - private File downloadDir; - private UpdateCenterMatrixFactory updateCenterMatrixFactory; - private UpdateCenter updateCenter; - private HttpDownloader httpDownloader; - private PluginDownloader pluginDownloader; - - @Before - public void before() throws Exception { - updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class); - updateCenter = mock(UpdateCenter.class); - when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter)); - - httpDownloader = mock(HttpDownloader.class); - doAnswer(new Answer<Void>() { - @Override - public Void answer(InvocationOnMock inv) throws Throwable { - File toFile = (File) inv.getArguments()[1]; - touch(toFile); - return null; - } - }).when(httpDownloader).download(any(URI.class), any(File.class)); - - ServerFileSystem fs = mock(ServerFileSystem.class); - downloadDir = testFolder.newFolder("downloads"); - when(fs.getDownloadedPluginsDir()).thenReturn(downloadDir); - - pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, fs); - } - - @After - public void stop() { - pluginDownloader.stop(); - } - - @Test - public void clean_temporary_files_at_startup() throws Exception { - touch(new File(downloadDir, "sonar-php.jar")); - touch(new File(downloadDir, "sonar-js.jar.tmp")); - assertThat(downloadDir.listFiles()).hasSize(2); - pluginDownloader.start(); - - File[] files = downloadDir.listFiles(); - assertThat(files).hasSize(1); - assertThat(files[0].getName()).isEqualTo("sonar-php.jar"); - } - - @Test - public void download_from_url() { - Plugin test = Plugin.factory("test"); - Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar"); - test.addRelease(test10); - - when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10)); - - pluginDownloader.start(); - pluginDownloader.download("foo", create("1.0")); - - // SONAR-4523: do not corrupt JAR files when restarting the server while a plugin is being downloaded. - // The JAR file is downloaded in a temp file - verify(httpDownloader).download(any(URI.class), argThat(new HasFileName("test-1.0.jar.tmp"))); - assertThat(new File(downloadDir, "test-1.0.jar")).exists(); - assertThat(new File(downloadDir, "test-1.0.jar.tmp")).doesNotExist(); - } - - @Test - public void download_when_update_center_is_unavailable_with_no_exception_thrown() { - when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.absent()); - - Plugin test = Plugin.factory("test"); - Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar"); - test.addRelease(test10); - - pluginDownloader.start(); - pluginDownloader.download("foo", create("1.0")); - } - - /** - * SONAR-4685 - */ - @Test - public void download_from_redirect_url() { - Plugin test = Plugin.factory("plugintest"); - Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/redirect?r=release&g=test&a=test&v=1.0&e=jar"); - test.addRelease(test10); - - when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10)); - - pluginDownloader.start(); - pluginDownloader.download("foo", create("1.0")); - - // SONAR-4523: do not corrupt JAR files when restarting the server while a plugin is being downloaded. - // The JAR file is downloaded in a temp file - verify(httpDownloader).download(any(URI.class), argThat(new HasFileName("plugintest-1.0.jar.tmp"))); - assertThat(new File(downloadDir, "plugintest-1.0.jar")).exists(); - assertThat(new File(downloadDir, "plugintest-1.0.jar.tmp")).doesNotExist(); - } - - @Test - public void throw_exception_if_download_dir_is_invalid() throws Exception { - ServerFileSystem fs = mock(ServerFileSystem.class); - // download dir is a file instead of being a directory - File downloadDir = testFolder.newFile(); - when(fs.getDownloadedPluginsDir()).thenReturn(downloadDir); - - pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, fs); - try { - pluginDownloader.start(); - fail(); - } catch (IllegalStateException e) { - // ok - } - } - - @Test - public void fail_if_no_compatible_plugin_found() { - expectedException.expect(BadRequestException.class); - - pluginDownloader.download("foo", create("1.0")); - } - - @Test - public void download_from_file() throws Exception { - Plugin test = Plugin.factory("test"); - File file = testFolder.newFile("test-1.0.jar"); - file.createNewFile(); - Release test10 = new Release(test, "1.0").setDownloadUrl("file://" + separatorsToUnix(file.getCanonicalPath())); - test.addRelease(test10); - - when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10)); - - pluginDownloader.start(); - pluginDownloader.download("foo", create("1.0")); - verify(httpDownloader, never()).download(any(URI.class), any(File.class)); - assertThat(noDownloadedFiles()).isGreaterThan(0); - } - - @Test - public void throw_exception_if_could_not_download() { - Plugin test = Plugin.factory("test"); - Release test10 = new Release(test, "1.0").setDownloadUrl("file://not_found"); - test.addRelease(test10); - - when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10)); - - pluginDownloader.start(); - try { - pluginDownloader.download("foo", create("1.0")); - fail(); - } catch (IllegalStateException e) { - // ok - } - } - - @Test - public void throw_exception_if_download_fail() { - Plugin test = Plugin.factory("test"); - Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar"); - test.addRelease(test10); - when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10)); - - doThrow(new RuntimeException()).when(httpDownloader).download(any(URI.class), any(File.class)); - - pluginDownloader.start(); - try { - pluginDownloader.download("foo", create("1.0")); - fail(); - } catch (IllegalStateException e) { - // ok - } - } - - @Test - public void read_download_folder() throws Exception { - pluginDownloader.start(); - assertThat(noDownloadedFiles()).isZero(); - - copyFileToDirectory(TestProjectUtils.jarOf("test-base-plugin"), downloadDir); - - assertThat(pluginDownloader.getDownloadedPlugins()).hasSize(1); - PluginInfo info = pluginDownloader.getDownloadedPlugins().iterator().next(); - assertThat(info.getKey()).isEqualTo("testbase"); - assertThat(info.getName()).isEqualTo("Base Plugin"); - assertThat(info.getVersion()).isEqualTo(Version.create("0.1-SNAPSHOT")); - assertThat(info.getMainClass()).isEqualTo("BasePlugin"); - } - - @Test - public void getDownloadedPluginFilenames_reads_plugin_info_of_files_in_download_folder() throws Exception { - pluginDownloader.start(); - assertThat(pluginDownloader.getDownloadedPlugins()).hasSize(0); - - File file1 = new File(downloadDir, "file1.jar"); - file1.createNewFile(); - File file2 = new File(downloadDir, "file2.jar"); - file2.createNewFile(); - - assertThat(noDownloadedFiles()).isEqualTo(2); - } - - @Test - public void cancel_downloads() throws Exception { - File file1 = new File(downloadDir, "file1.jar"); - file1.createNewFile(); - File file2 = new File(downloadDir, "file2.jar"); - file2.createNewFile(); - - pluginDownloader.start(); - assertThat(noDownloadedFiles()).isGreaterThan(0); - pluginDownloader.cancelDownloads(); - assertThat(noDownloadedFiles()).isZero(); - } - - private int noDownloadedFiles() { - return downloadDir.listFiles((file, name) -> name.endsWith(".jar")).length; - } - - // SONAR-5011 - @Test - public void download_common_transitive_dependency() { - Plugin test1 = Plugin.factory("test1"); - Release test1R = new Release(test1, "1.0").setDownloadUrl("http://server/test1-1.0.jar"); - test1.addRelease(test1R); - - Plugin test2 = Plugin.factory("test2"); - Release test2R = new Release(test2, "1.0").setDownloadUrl("http://server/test2-1.0.jar"); - test2.addRelease(test2R); - - Plugin testDep = Plugin.factory("testdep"); - Release testDepR = new Release(testDep, "1.0").setDownloadUrl("http://server/testdep-1.0.jar"); - testDep.addRelease(testDepR); - - when(updateCenter.findInstallablePlugins("test1", create("1.0"))).thenReturn(newArrayList(test1R, testDepR)); - when(updateCenter.findInstallablePlugins("test2", create("1.0"))).thenReturn(newArrayList(test2R, testDepR)); - - pluginDownloader.start(); - pluginDownloader.download("test1", create("1.0")); - pluginDownloader.download("test2", create("1.0")); - - assertThat(new File(downloadDir, "test1-1.0.jar")).exists(); - assertThat(new File(downloadDir, "test2-1.0.jar")).exists(); - assertThat(new File(downloadDir, "testdep-1.0.jar")).exists(); - } - - class HasFileName implements ArgumentMatcher<File> { - private final String name; - - HasFileName(String name) { - this.name = name; - } - - @Override - public boolean matches(File file) { - return file.getName().equals(name); - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginFileSystemTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginFileSystemTest.java deleted file mode 100644 index bc353f99778..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginFileSystemTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.RandomStringUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.core.platform.PluginInfo; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.plugins.PluginFileSystem.PROPERTY_PLUGIN_COMPRESSION_ENABLE; - -public class PluginFileSystemTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private MapSettings settings = new MapSettings(); - private Path targetJarPath; - private Path targetFolder; - private Path sourceFolder; - - @Before - public void setUp() throws IOException { - sourceFolder = temp.newFolder("source").toPath(); - targetFolder = temp.newFolder("target").toPath(); - targetJarPath = targetFolder.resolve("test.jar"); - Files.createFile(targetJarPath); - } - - @Test - public void add_plugin_to_list_of_installed_plugins() throws IOException { - File jar = touch(temp.newFolder(), "sonar-foo-plugin.jar"); - PluginInfo info = new PluginInfo("foo"); - - PluginFileSystem underTest = new PluginFileSystem(settings.asConfig()); - underTest.addInstalledPlugin(info, jar); - - assertThat(underTest.getInstalledFiles()).hasSize(1); - InstalledPlugin installedPlugin = underTest.getInstalledPlugin("foo").get(); - assertThat(installedPlugin.getCompressedJar()).isNull(); - assertThat(installedPlugin.getLoadedJar().getFile().toPath()).isEqualTo(jar.toPath()); - assertThat(installedPlugin.getPluginInfo()).isSameAs(info); - } - - @Test - public void compress_jar_if_compression_enabled() throws IOException { - File jar = touch(temp.newFolder(), "sonar-foo-plugin.jar"); - PluginInfo info = new PluginInfo("foo").setJarFile(jar); - // the JAR is copied somewhere else in order to be loaded by classloaders - File loadedJar = touch(temp.newFolder(), "sonar-foo-plugin.jar"); - - settings.setProperty(PROPERTY_PLUGIN_COMPRESSION_ENABLE, true); - PluginFileSystem underTest = new PluginFileSystem(settings.asConfig()); - underTest.addInstalledPlugin(info, loadedJar); - - assertThat(underTest.getInstalledFiles()).hasSize(1); - - InstalledPlugin installedPlugin = underTest.getInstalledPlugin("foo").get(); - assertThat(installedPlugin.getPluginInfo()).isSameAs(info); - assertThat(installedPlugin.getLoadedJar().getFile().toPath()).isEqualTo(loadedJar.toPath()); - assertThat(installedPlugin.getCompressedJar().getFile()) - .exists() - .isFile() - .hasName("sonar-foo-plugin.pack.gz") - .hasParent(loadedJar.getParentFile()); - } - - @Test - public void copy_and_use_existing_packed_jar_if_compression_enabled() throws IOException { - File jar = touch(temp.newFolder(), "sonar-foo-plugin.jar"); - File packedJar = touch(jar.getParentFile(), "sonar-foo-plugin.pack.gz"); - PluginInfo info = new PluginInfo("foo").setJarFile(jar); - // the JAR is copied somewhere else in order to be loaded by classloaders - File loadedJar = touch(temp.newFolder(), "sonar-foo-plugin.jar"); - - settings.setProperty(PROPERTY_PLUGIN_COMPRESSION_ENABLE, true); - PluginFileSystem underTest = new PluginFileSystem(settings.asConfig()); - underTest.addInstalledPlugin(info, loadedJar); - - assertThat(underTest.getInstalledFiles()).hasSize(1); - - InstalledPlugin installedPlugin = underTest.getInstalledPlugin("foo").get(); - assertThat(installedPlugin.getPluginInfo()).isSameAs(info); - assertThat(installedPlugin.getLoadedJar().getFile().toPath()).isEqualTo(loadedJar.toPath()); - assertThat(installedPlugin.getCompressedJar().getFile()) - .exists() - .isFile() - .hasName(packedJar.getName()) - .hasParent(loadedJar.getParentFile()) - .hasSameContentAs(packedJar); - } - - private static File touch(File dir, String filename) throws IOException { - File file = new File(dir, filename); - FileUtils.write(file, RandomStringUtils.random(10)); - return file; - } - - // - // @Test - // public void should_use_deployed_packed_file() throws IOException { - // Path packedPath = sourceFolder.resolve("test.pack.gz"); - // Files.write(packedPath, new byte[] {1, 2, 3}); - // - // settings.setProperty(PROPERTY_PLUGIN_COMPRESSION_ENABLE, true); - // underTest = new PluginFileSystem(settings.asConfig()); - // underTest.compressJar("key", sourceFolder, targetJarPath); - // - // assertThat(Files.list(targetFolder)).containsOnly(targetJarPath, targetFolder.resolve("test.pack.gz")); - // assertThat(underTest.getPlugins()).hasSize(1); - // assertThat(underTest.getPlugins().get("key").getFilename()).isEqualTo("test.pack.gz"); - // - // // check that the file was copied, not generated - // assertThat(targetFolder.resolve("test.pack.gz")).hasSameContentAs(packedPath); - // } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginUninstallerTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginUninstallerTest.java deleted file mode 100644 index 20eae5f2781..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginUninstallerTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import java.io.File; -import java.io.IOException; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.server.platform.ServerFileSystem; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class PluginUninstallerTest { - @Rule - public TemporaryFolder testFolder = new TemporaryFolder(); - - @Rule - public ExpectedException exception = ExpectedException.none(); - - private File uninstallDir; - private PluginUninstaller underTest; - private ServerPluginRepository serverPluginRepository; - private ServerFileSystem fs; - - @Before - public void setUp() throws IOException { - serverPluginRepository = mock(ServerPluginRepository.class); - uninstallDir = testFolder.newFolder("uninstall"); - fs = mock(ServerFileSystem.class); - when(fs.getUninstalledPluginsDir()).thenReturn(uninstallDir); - underTest = new PluginUninstaller(serverPluginRepository, fs); - } - - @Test - public void uninstall() { - when(serverPluginRepository.hasPlugin("plugin")).thenReturn(true); - underTest.uninstall("plugin"); - verify(serverPluginRepository).uninstall("plugin", uninstallDir); - } - - @Test - public void fail_uninstall_if_plugin_not_installed() { - when(serverPluginRepository.hasPlugin("plugin")).thenReturn(false); - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Plugin [plugin] is not installed"); - underTest.uninstall("plugin"); - verifyZeroInteractions(serverPluginRepository); - } - - @Test - public void create_uninstall_dir() { - File dir = new File(testFolder.getRoot(), "dir"); - when(fs.getUninstalledPluginsDir()).thenReturn(dir); - underTest = new PluginUninstaller(serverPluginRepository, fs); - underTest.start(); - assertThat(dir).isDirectory(); - } - - @Test - public void cancel() { - underTest.cancelUninstalls(); - verify(serverPluginRepository).cancelUninstalls(uninstallDir); - verifyNoMoreInteractions(serverPluginRepository); - } - - @Test - public void list_uninstalled_plugins() throws IOException { - new File(uninstallDir, "file1").createNewFile(); - copyTestPluginTo("test-base-plugin", uninstallDir); - assertThat(underTest.getUninstalledPlugins()).extracting("key").containsOnly("testbase"); - } - - private File copyTestPluginTo(String testPluginName, File toDir) throws IOException { - File jar = TestProjectUtils.jarOf(testPluginName); - // file is copied because it's supposed to be moved by the test - FileUtils.copyFileToDirectory(jar, toDir); - return new File(toDir, jar.getName()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarExploderTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarExploderTest.java deleted file mode 100644 index 8f4d928cd4c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarExploderTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import java.io.File; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.core.platform.ExplodedPlugin; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.platform.ServerFileSystem; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ServerPluginJarExploderTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private ServerFileSystem fs = mock(ServerFileSystem.class); - private PluginFileSystem pluginFileSystem = mock(PluginFileSystem.class); - private ServerPluginJarExploder underTest = new ServerPluginJarExploder(fs, pluginFileSystem); - - @Test - public void copy_all_classloader_files_to_dedicated_directory() throws Exception { - File deployDir = temp.newFolder(); - when(fs.getDeployedPluginsDir()).thenReturn(deployDir); - File sourceJar = TestProjectUtils.jarOf("test-libs-plugin"); - PluginInfo info = PluginInfo.create(sourceJar); - - ExplodedPlugin exploded = underTest.explode(info); - - // all the files loaded by classloaders (JAR + META-INF/libs/*.jar) are copied to the dedicated directory - // web/deploy/{pluginKey} - File pluginDeployDir = new File(deployDir, "testlibs"); - - assertThat(exploded.getKey()).isEqualTo("testlibs"); - assertThat(exploded.getMain()).isFile().exists().hasParent(pluginDeployDir); - assertThat(exploded.getLibs()).extracting("name").containsOnly("commons-daemon-1.0.15.jar", "commons-email-20030310.165926.jar"); - for (File lib : exploded.getLibs()) { - assertThat(lib).exists().isFile(); - assertThat(lib.getCanonicalPath()).startsWith(pluginDeployDir.getCanonicalPath()); - } - File targetJar = new File(fs.getDeployedPluginsDir(), "testlibs/test-libs-plugin-0.1-SNAPSHOT.jar"); - verify(pluginFileSystem).addInstalledPlugin(info, targetJar); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginRepositoryTest.java deleted file mode 100644 index e426c9ebfea..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginRepositoryTest.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import org.apache.commons.io.FileUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.mockito.Mockito; -import org.sonar.api.SonarRuntime; -import org.sonar.api.utils.MessageException; -import org.sonar.api.utils.log.LogTester; -import org.sonar.core.platform.PluginInfo; -import org.sonar.core.platform.PluginLoader; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.updatecenter.common.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServerPluginRepositoryTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Rule - public LogTester logs = new LogTester(); - - private SonarRuntime runtime = mock(SonarRuntime.class); - private ServerFileSystem fs = mock(ServerFileSystem.class, Mockito.RETURNS_DEEP_STUBS); - private PluginLoader pluginLoader = mock(PluginLoader.class); - private ServerPluginRepository underTest = new ServerPluginRepository(runtime, fs, pluginLoader); - - @Before - public void setUp() throws IOException { - when(fs.getDeployedPluginsDir()).thenReturn(temp.newFolder()); - when(fs.getDownloadedPluginsDir()).thenReturn(temp.newFolder()); - when(fs.getHomeDir()).thenReturn(temp.newFolder()); - when(fs.getInstalledPluginsDir()).thenReturn(temp.newFolder()); - when(fs.getTempDir()).thenReturn(temp.newFolder()); - when(runtime.getApiVersion()).thenReturn(org.sonar.api.utils.Version.parse("5.2")); - } - - @After - public void tearDown() { - underTest.stop(); - } - - @Test - public void standard_startup_loads_installed_plugins() throws Exception { - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - } - - @Test - public void no_plugins_at_all_on_startup() { - underTest.start(); - - assertThat(underTest.getPluginInfos()).isEmpty(); - assertThat(underTest.getPluginInfosByKeys()).isEmpty(); - assertThat(underTest.hasPlugin("testbase")).isFalse(); - } - - @Test - public void fail_if_multiple_jars_for_same_installed_plugin_on_startup() throws Exception { - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - copyTestPluginTo("test-base-plugin-v2", fs.getInstalledPluginsDir()); - - try { - underTest.start(); - fail(); - } catch (MessageException e) { - assertThat(e) - .hasMessageStartingWith("Found two versions of the plugin Base Plugin [testbase] in the directory extensions/plugins. Please remove one of ") - // order is not guaranteed, so assertion is split - .hasMessageContaining("test-base-plugin-0.1-SNAPSHOT.jar") - .hasMessageContaining("test-base-plugin-0.2-SNAPSHOT.jar"); - } - } - - @Test - public void install_downloaded_plugins_on_startup() throws Exception { - File downloadedJar = copyTestPluginTo("test-base-plugin", fs.getDownloadedPluginsDir()); - - underTest.start(); - - // plugin is moved to extensions/plugins then loaded - assertThat(downloadedJar).doesNotExist(); - assertThat(new File(fs.getInstalledPluginsDir(), downloadedJar.getName())).isFile().exists(); - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - } - - @Test - public void downloaded_file_overrides_existing_installed_file_on_startup() throws Exception { - File installedV1 = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - File downloadedV2 = copyTestPluginTo("test-base-plugin-v2", fs.getDownloadedPluginsDir()); - - underTest.start(); - - // plugin is moved to extensions/plugins and replaces v1 - assertThat(downloadedV2).doesNotExist(); - assertThat(installedV1).doesNotExist(); - assertThat(new File(fs.getInstalledPluginsDir(), downloadedV2.getName())).exists(); - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - assertThat(underTest.getPluginInfo("testbase").getVersion()).isEqualTo(Version.create("0.2-SNAPSHOT")); - } - - @Test - public void blacklisted_plugin_is_automatically_uninstalled_on_startup() throws Exception { - underTest.setBlacklistedPluginKeys(ImmutableSet.of("testbase", "issuesreport")); - File jar = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // plugin is not installed and file is deleted - assertThat(underTest.getPluginInfos()).isEmpty(); - assertThat(jar).doesNotExist(); - } - - @Test - public void test_plugin_requirements_at_startup() throws Exception { - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - copyTestPluginTo("test-require-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // both plugins are installed - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase", "testrequire"); - } - - @Test - public void plugin_is_ignored_if_required_plugin_is_missing_at_startup() throws Exception { - copyTestPluginTo("test-require-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // plugin is not installed as test-base-plugin is missing - assertThat(underTest.getPluginInfosByKeys()).isEmpty(); - } - - @Test - public void plugin_is_ignored_if_required_plugin_is_too_old_at_startup() throws Exception { - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - copyTestPluginTo("test-requirenew-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // the plugin "requirenew" is not installed as it requires base 0.2+ to be installed. - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - } - - @Test - public void fail_if_plugin_does_not_support_sq_version() throws Exception { - when(runtime.getApiVersion()).thenReturn(org.sonar.api.utils.Version.parse("1.0")); - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - - try { - underTest.start(); - fail(); - } catch (MessageException e) { - assertThat(e).hasMessage("Plugin Base Plugin [testbase] requires at least SonarQube 4.5.4"); - } - } - - @Test - public void uninstall() throws Exception { - File installedJar = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - File uninstallDir = temp.newFolder("uninstallDir"); - - underTest.start(); - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - underTest.uninstall("testbase", uninstallDir); - - assertThat(installedJar).doesNotExist(); - // still up. Will be dropped after next startup - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase"); - assertThat(uninstallDir.list()).containsOnly(installedJar.getName()); - } - - @Test - public void uninstall_dependents() throws Exception { - File base = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - File extension = copyTestPluginTo("test-require-plugin", fs.getInstalledPluginsDir()); - File uninstallDir = temp.newFolder("uninstallDir"); - - underTest.start(); - assertThat(underTest.getPluginInfos()).hasSize(2); - underTest.uninstall("testbase", uninstallDir); - assertThat(base).doesNotExist(); - assertThat(extension).doesNotExist(); - assertThat(uninstallDir.list()).containsOnly(base.getName(), extension.getName()); - } - - @Test - public void dont_uninstall_non_existing_dependents() throws IOException { - File base = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - File extension = copyTestPluginTo("test-require-plugin", fs.getInstalledPluginsDir()); - File uninstallDir = temp.newFolder("uninstallDir"); - - underTest.start(); - assertThat(underTest.getPluginInfos()).hasSize(2); - underTest.uninstall("testrequire", uninstallDir); - assertThat(underTest.getPluginInfos()).hasSize(2); - - underTest.uninstall("testbase", uninstallDir); - assertThat(base).doesNotExist(); - assertThat(extension).doesNotExist(); - assertThat(uninstallDir.list()).containsOnly(base.getName(), extension.getName()); - } - - @Test - public void dont_uninstall_non_existing_files() throws IOException { - File base = copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - File extension = copyTestPluginTo("test-require-plugin", fs.getInstalledPluginsDir()); - File uninstallDir = temp.newFolder("uninstallDir"); - - underTest.start(); - assertThat(underTest.getPluginInfos()).hasSize(2); - underTest.uninstall("testbase", uninstallDir); - assertThat(underTest.getPluginInfos()).hasSize(2); - - underTest.uninstall("testbase", uninstallDir); - assertThat(base).doesNotExist(); - assertThat(extension).doesNotExist(); - assertThat(uninstallDir.list()).containsOnly(base.getName(), extension.getName()); - } - - @Test - public void install_plugin_and_its_extension_plugins_at_startup() throws Exception { - copyTestPluginTo("test-base-plugin", fs.getInstalledPluginsDir()); - copyTestPluginTo("test-extend-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // both plugins are installed - assertThat(underTest.getPluginInfosByKeys()).containsOnlyKeys("testbase", "testextend"); - } - - @Test - public void extension_plugin_is_ignored_if_base_plugin_is_missing_at_startup() throws Exception { - copyTestPluginTo("test-extend-plugin", fs.getInstalledPluginsDir()); - - underTest.start(); - - // plugin is not installed as its base plugin is not installed - assertThat(underTest.getPluginInfos()).isEmpty(); - } - - @Test - public void fail_to_get_missing_plugins() { - underTest.start(); - try { - underTest.getPluginInfo("unknown"); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Plugin [unknown] does not exist"); - } - - try { - underTest.getPluginInstance("unknown"); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Plugin [unknown] does not exist"); - } - } - - @Test - public void plugin_is_incompatible_if_no_entry_point_class() { - PluginInfo plugin = new PluginInfo("foo").setName("Foo"); - assertThat(ServerPluginRepository.isCompatible(plugin, runtime, Collections.emptyMap())).isFalse(); - assertThat(logs.logs()).contains("Plugin Foo [foo] is ignored because entry point class is not defined"); - } - - @Test - public void fail_when_views_is_installed() throws Exception { - copyTestPluginTo("fake-views-plugin", fs.getInstalledPluginsDir()); - - expectedException.expect(MessageException.class); - expectedException.expectMessage("Plugin 'views' is no longer compatible with this version of SonarQube"); - underTest.start(); - } - - @Test - public void fail_when_sqale_plugin_is_installed() throws Exception { - copyTestPluginTo("fake-sqale-plugin", fs.getInstalledPluginsDir()); - - expectedException.expect(MessageException.class); - expectedException.expectMessage("Plugin 'sqale' is no longer compatible with this version of SonarQube"); - underTest.start(); - } - - @Test - public void fail_when_report_is_installed() throws Exception { - copyTestPluginTo("fake-report-plugin", fs.getInstalledPluginsDir()); - - expectedException.expect(MessageException.class); - expectedException.expectMessage("Plugin 'report' is no longer compatible with this version of SonarQube"); - underTest.start(); - } - - /** - * Some plugins can only extend the classloader of base plugin, without declaring new extensions. - */ - @Test - public void plugin_is_compatible_if_no_entry_point_class_but_extend_other_plugin() { - PluginInfo basePlugin = new PluginInfo("base").setMainClass("org.bar.Bar"); - PluginInfo plugin = new PluginInfo("foo").setBasePlugin("base"); - Map<String, PluginInfo> plugins = ImmutableMap.of("base", basePlugin, "foo", plugin); - - assertThat(ServerPluginRepository.isCompatible(plugin, runtime, plugins)).isTrue(); - } - - @Test - public void getPluginInstance_throws_ISE_if_repo_is_not_started() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("not started yet"); - - underTest.getPluginInstance("foo"); - } - - @Test - public void getPluginInfo_throws_ISE_if_repo_is_not_started() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("not started yet"); - - underTest.getPluginInfo("foo"); - } - - @Test - public void hasPlugin_throws_ISE_if_repo_is_not_started() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("not started yet"); - - underTest.hasPlugin("foo"); - } - - @Test - public void getPluginInfos_throws_ISE_if_repo_is_not_started() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("not started yet"); - - underTest.getPluginInfos(); - } - - private File copyTestPluginTo(String testPluginName, File toDir) throws IOException { - File jar = TestProjectUtils.jarOf(testPluginName); - // file is copied because it's supposed to be moved by the test - FileUtils.copyFileToDirectory(jar, toDir); - return new File(toDir, jar.getName()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/TestPluginA.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/TestPluginA.java deleted file mode 100644 index 7952eb5799c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/TestPluginA.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import org.sonar.api.Plugin; - -public class TestPluginA implements Plugin { - @Override - public void define(Context context) { - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/TestProjectUtils.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/TestProjectUtils.java deleted file mode 100644 index 9710a8689e4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/TestProjectUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.util.Collection; - -public class TestProjectUtils { - - /** - * Get the artifact of plugins stored in src/test/projects - */ - public static File jarOf(String dirName) { - File target = FileUtils.toFile(TestProjectUtils.class.getResource(String.format("/%s/target/", dirName))); - Collection<File> jars = FileUtils.listFiles(target, new String[] {"jar"}, false); - if (jars == null || jars.size() != 1) { - throw new IllegalArgumentException("Test project is badly defined: " + dirName); - } - return jars.iterator().next(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java deleted file mode 100644 index b1e50cba77c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.utils.SonarException; -import org.sonar.api.utils.UriReader; -import org.sonar.process.ProcessProperties; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.guava.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class UpdateCenterClientTest { - - private static final String BASE_URL = "https://update.sonarsource.org"; - private UriReader reader = mock(UriReader.class); - private MapSettings settings = new MapSettings(); - private UpdateCenterClient underTest; - - @Before - public void startServer() throws Exception { - reader = mock(UriReader.class); - settings.setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL); - settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), true); - underTest = new UpdateCenterClient(reader, settings.asConfig()); - } - - @Test - public void downloadUpdateCenter() throws URISyntaxException { - when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("publicVersions=2.2,2.3"); - UpdateCenter plugins = underTest.getUpdateCenter().get(); - verify(reader, times(1)).readString(new URI(BASE_URL), StandardCharsets.UTF_8); - assertThat(plugins.getSonar().getVersions()).containsOnly(Version.create("2.2"), Version.create("2.3")); - assertThat(underTest.getLastRefreshDate()).isNotNull(); - } - - @Test - public void not_available_before_initialization() { - assertThat(underTest.getLastRefreshDate()).isNull(); - } - - @Test - public void ignore_connection_errors() { - when(reader.readString(any(URI.class), eq(StandardCharsets.UTF_8))).thenThrow(new SonarException()); - assertThat(underTest.getUpdateCenter()).isAbsent(); - } - - @Test - public void cache_data() throws Exception { - when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("sonar.versions=2.2,2.3"); - - underTest.getUpdateCenter(); - underTest.getUpdateCenter(); - - verify(reader, times(1)).readString(new URI(BASE_URL), StandardCharsets.UTF_8); - } - - @Test - public void forceRefresh() throws Exception { - when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("sonar.versions=2.2,2.3"); - - underTest.getUpdateCenter(); - underTest.getUpdateCenter(true); - - verify(reader, times(2)).readString(new URI(BASE_URL), StandardCharsets.UTF_8); - } - - @Test - public void update_center_is_null_when_property_is_false() { - settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), false); - - assertThat(underTest.getUpdateCenter()).isAbsent(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterMatrixFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterMatrixFactoryTest.java deleted file mode 100644 index a71522a77d5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterMatrixFactoryTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import com.google.common.base.Optional; -import org.junit.Test; -import org.sonar.api.SonarRuntime; -import org.sonar.updatecenter.common.UpdateCenter; - -import static org.assertj.guava.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class UpdateCenterMatrixFactoryTest { - - private UpdateCenterMatrixFactory underTest; - - @Test - public void return_absent_update_center() { - UpdateCenterClient updateCenterClient = mock(UpdateCenterClient.class); - when(updateCenterClient.getUpdateCenter(anyBoolean())).thenReturn(Optional.absent()); - - underTest = new UpdateCenterMatrixFactory(updateCenterClient, mock(SonarRuntime.class), mock(InstalledPluginReferentialFactory.class)); - - Optional<UpdateCenter> updateCenter = underTest.getUpdateCenter(false); - - assertThat(updateCenter).isAbsent(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterServlet.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterServlet.java deleted file mode 100644 index d6d9904452d..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterServlet.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins; - -import javax.servlet.GenericServlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.util.Properties; - -public class UpdateCenterServlet extends GenericServlet { - - int count = 0; - - @Override - public void service(ServletRequest request, ServletResponse response) throws IOException { - count++; - Properties props = new Properties(); - props.setProperty("count", String.valueOf(count)); - props.setProperty("agent", ((HttpServletRequest)request).getHeader("User-Agent")); - props.store(response.getOutputStream(), null); - } -} - diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java deleted file mode 100644 index 907768f56fa..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.plugins.edition; - -import java.util.Random; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.core.platform.PluginInfo; -import org.sonar.updatecenter.common.Plugin; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; - -public class EditionBundledPluginsTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private final Random random = new Random(); - - @Test - public void isEditionBundled_on_Plugin_fails_with_NPE_if_arg_is_null() { - expectedException.expect(NullPointerException.class); - - EditionBundledPlugins.isEditionBundled((Plugin) null); - } - - @Test - public void isEditionBundled_on_Plugin_returns_false_for_SonarSource_and_non_commercial_license() { - Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomAlphanumeric(3)); - - assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse(); - } - - @Test - public void isEditionBundled_on_Plugin_returns_false_for_license_SonarSource_and_non_SonarSource_organization() { - Plugin plugin = newPlugin(randomAlphanumeric(3), randomizeCase("SonarSource")); - - assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse(); - } - - @Test - public void isEditionBundled_on_Plugin_returns_false_for_license_Commercial_and_non_SonarSource_organization() { - Plugin plugin = newPlugin(randomAlphanumeric(3), randomizeCase("Commercial")); - - assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse(); - } - - @Test - public void isEditionBundled_on_Plugin_returns_true_for_organization_SonarSource_and_license_SonarSource_case_insensitive() { - Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomizeCase("SonarSource")); - - assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isTrue(); - } - - @Test - public void isEditionBundled_on_Plugin_returns_true_for_organization_SonarSource_and_license_Commercial_case_insensitive() { - Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomizeCase("Commercial")); - - assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isTrue(); - } - - @Test - public void isEditionBundled_on_PluginInfo_fails_with_NPE_if_arg_is_null() { - expectedException.expect(NullPointerException.class); - - EditionBundledPlugins.isEditionBundled((PluginInfo) null); - } - - @Test - public void isEditionBundled_on_PluginInfo_returns_false_for_SonarSource_and_non_commercial_license() { - PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomAlphanumeric(3)); - - assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse(); - } - - @Test - public void isEditionBundled_on_PluginInfo_returns_false_for_license_SonarSource_and_non_SonarSource_organization() { - PluginInfo pluginInfo = newPluginInfo(randomAlphanumeric(3), randomizeCase("SonarSource")); - - assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse(); - } - - @Test - public void isEditionBundled_on_PluginInfo_returns_false_for_license_Commercial_and_non_SonarSource_organization() { - PluginInfo pluginInfo = newPluginInfo(randomAlphanumeric(3), randomizeCase("Commercial")); - - assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse(); - } - - @Test - public void isEditionBundled_on_PluginInfo_returns_true_for_organization_SonarSource_and_license_SonarSource_case_insensitive() { - PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomizeCase("SonarSource")); - - assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isTrue(); - } - - @Test - public void isEditionBundled_on_PluginINfo_returns_true_for_organization_SonarSource_and_license_Commercial_case_insensitive() { - PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomizeCase("Commercial")); - - assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isTrue(); - } - - private String randomizeCase(String s) { - return s.chars() - .map(c -> random.nextBoolean() ? Character.toUpperCase(c) : Character.toLowerCase(c)) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - } - - private PluginInfo newPluginInfo(String organization, String license) { - PluginInfo pluginInfo = new PluginInfo(randomAlphanumeric(2)); - if (random.nextBoolean()) { - pluginInfo.setName(randomAlphanumeric(3)); - } - if (random.nextBoolean()) { - pluginInfo.setOrganizationUrl(randomAlphanumeric(4)); - } - if (random.nextBoolean()) { - pluginInfo.setIssueTrackerUrl(randomAlphanumeric(5)); - } - if (random.nextBoolean()) { - pluginInfo.setIssueTrackerUrl(randomAlphanumeric(6)); - } - if (random.nextBoolean()) { - pluginInfo.setBasePlugin(randomAlphanumeric(7)); - } - if (random.nextBoolean()) { - pluginInfo.setHomepageUrl(randomAlphanumeric(8)); - } - return pluginInfo - .setOrganizationName(organization) - .setLicense(license); - } - - private Plugin newPlugin(String organization, String license) { - Plugin plugin = Plugin.factory(randomAlphanumeric(2)); - if (random.nextBoolean()) { - plugin.setName(randomAlphanumeric(3)); - } - if (random.nextBoolean()) { - plugin.setOrganizationUrl(randomAlphanumeric(4)); - } - if (random.nextBoolean()) { - plugin.setTermsConditionsUrl(randomAlphanumeric(5)); - } - if (random.nextBoolean()) { - plugin.setIssueTrackerUrl(randomAlphanumeric(6)); - } - if (random.nextBoolean()) { - plugin.setCategory(randomAlphanumeric(7)); - } - if (random.nextBoolean()) { - plugin.setHomepageUrl(randomAlphanumeric(8)); - } - return plugin - .setLicense(license) - .setOrganization(organization); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java deleted file mode 100644 index 8085b643ede..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.project; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Collections; -import java.util.Random; -import java.util.Set; -import java.util.stream.IntStream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.InOrder; -import org.mockito.Mockito; -import org.sonar.core.util.stream.MoreCollectors; - -import static java.util.Collections.singleton; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; -import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; - -@RunWith(DataProviderRunner.class) -public class ProjectLifeCycleListenersImplTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private ProjectLifeCycleListener listener1 = mock(ProjectLifeCycleListener.class); - private ProjectLifeCycleListener listener2 = mock(ProjectLifeCycleListener.class); - private ProjectLifeCycleListener listener3 = mock(ProjectLifeCycleListener.class); - private ProjectLifeCycleListenersImpl underTestNoListeners = new ProjectLifeCycleListenersImpl(); - private ProjectLifeCycleListenersImpl underTestWithListeners = new ProjectLifeCycleListenersImpl( - new ProjectLifeCycleListener[] {listener1, listener2, listener3}); - - @Test - public void onProjectsDeleted_throws_NPE_if_set_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("projects can't be null"); - - underTestWithListeners.onProjectsDeleted(null); - } - - @Test - public void onProjectsDeleted_throws_NPE_if_set_is_null_even_if_no_listeners() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("projects can't be null"); - - underTestNoListeners.onProjectsDeleted(null); - } - - @Test - public void onProjectsDeleted_has_no_effect_if_set_is_empty() { - underTestNoListeners.onProjectsDeleted(Collections.emptySet()); - - underTestWithListeners.onProjectsDeleted(Collections.emptySet()); - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectsDeleted_does_not_fail_if_there_is_no_listener(Set<Project> projects) { - underTestNoListeners.onProjectsDeleted(projects); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectsDeleted_calls_all_listeners_in_order_of_addition_to_constructor(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - - underTestWithListeners.onProjectsDeleted(projects); - - inOrder.verify(listener1).onProjectsDeleted(same(projects)); - inOrder.verify(listener2).onProjectsDeleted(same(projects)); - inOrder.verify(listener3).onProjectsDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectsDeleted_calls_all_listeners_even_if_one_throws_an_Exception(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new RuntimeException("Faking listener2 throwing an exception")) - .when(listener2) - .onProjectsDeleted(any()); - - underTestWithListeners.onProjectsDeleted(projects); - - inOrder.verify(listener1).onProjectsDeleted(same(projects)); - inOrder.verify(listener2).onProjectsDeleted(same(projects)); - inOrder.verify(listener3).onProjectsDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectsDeleted_calls_all_listeners_even_if_one_throws_an_Error(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new Error("Faking listener2 throwing an Error")) - .when(listener2) - .onProjectsDeleted(any()); - - underTestWithListeners.onProjectsDeleted(projects); - - inOrder.verify(listener1).onProjectsDeleted(same(projects)); - inOrder.verify(listener2).onProjectsDeleted(same(projects)); - inOrder.verify(listener3).onProjectsDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - public void onProjectBranchesDeleted_throws_NPE_if_set_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("projects can't be null"); - - underTestWithListeners.onProjectBranchesDeleted(null); - } - - @Test - public void onProjectBranchesDeleted_throws_NPE_if_set_is_null_even_if_no_listeners() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("projects can't be null"); - - underTestNoListeners.onProjectBranchesDeleted(null); - } - - @Test - public void onProjectBranchesDeleted_has_no_effect_if_set_is_empty() { - underTestNoListeners.onProjectBranchesDeleted(Collections.emptySet()); - - underTestWithListeners.onProjectBranchesDeleted(Collections.emptySet()); - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectBranchesDeleted_does_not_fail_if_there_is_no_listener(Set<Project> projects) { - underTestNoListeners.onProjectBranchesDeleted(projects); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectBranchesDeleted_calls_all_listeners_in_order_of_addition_to_constructor(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - - underTestWithListeners.onProjectBranchesDeleted(projects); - - inOrder.verify(listener1).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener2).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener3).onProjectBranchesDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectBranchesDeleted_calls_all_listeners_even_if_one_throws_an_Exception(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new RuntimeException("Faking listener2 throwing an exception")) - .when(listener2) - .onProjectBranchesDeleted(any()); - - underTestWithListeners.onProjectBranchesDeleted(projects); - - inOrder.verify(listener1).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener2).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener3).onProjectBranchesDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyProjects") - public void onProjectBranchesDeleted_calls_all_listeners_even_if_one_throws_an_Error(Set<Project> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new Error("Faking listener2 throwing an Error")) - .when(listener2) - .onProjectBranchesDeleted(any()); - - underTestWithListeners.onProjectBranchesDeleted(projects); - - inOrder.verify(listener1).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener2).onProjectBranchesDeleted(same(projects)); - inOrder.verify(listener3).onProjectBranchesDeleted(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @DataProvider - public static Object[][] oneOrManyProjects() { - return new Object[][] { - {singleton(newUniqueProject())}, - {IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> newUniqueProject()).collect(MoreCollectors.toSet())} - }; - } - // SDSDS - - @Test - public void onProjectsRekeyed_throws_NPE_if_set_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("rekeyedProjects can't be null"); - - underTestWithListeners.onProjectsRekeyed(null); - } - - @Test - public void onProjectsRekeyed_throws_NPE_if_set_is_null_even_if_no_listeners() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("rekeyedProjects can't be null"); - - underTestNoListeners.onProjectsRekeyed(null); - } - - @Test - public void onProjectsRekeyed_has_no_effect_if_set_is_empty() { - underTestNoListeners.onProjectsRekeyed(Collections.emptySet()); - - underTestWithListeners.onProjectsRekeyed(Collections.emptySet()); - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - @UseDataProvider("oneOrManyRekeyedProjects") - public void onProjectsRekeyed_does_not_fail_if_there_is_no_listener(Set<RekeyedProject> projects) { - underTestNoListeners.onProjectsRekeyed(projects); - } - - @Test - @UseDataProvider("oneOrManyRekeyedProjects") - public void onProjectsRekeyed_calls_all_listeners_in_order_of_addition_to_constructor(Set<RekeyedProject> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - - underTestWithListeners.onProjectsRekeyed(projects); - - inOrder.verify(listener1).onProjectsRekeyed(same(projects)); - inOrder.verify(listener2).onProjectsRekeyed(same(projects)); - inOrder.verify(listener3).onProjectsRekeyed(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyRekeyedProjects") - public void onProjectsRekeyed_calls_all_listeners_even_if_one_throws_an_Exception(Set<RekeyedProject> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new RuntimeException("Faking listener2 throwing an exception")) - .when(listener2) - .onProjectsRekeyed(any()); - - underTestWithListeners.onProjectsRekeyed(projects); - - inOrder.verify(listener1).onProjectsRekeyed(same(projects)); - inOrder.verify(listener2).onProjectsRekeyed(same(projects)); - inOrder.verify(listener3).onProjectsRekeyed(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @UseDataProvider("oneOrManyRekeyedProjects") - public void onProjectsRekeyed_calls_all_listeners_even_if_one_throws_an_Error(Set<RekeyedProject> projects) { - InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - doThrow(new Error("Faking listener2 throwing an Error")) - .when(listener2) - .onProjectsRekeyed(any()); - - underTestWithListeners.onProjectsRekeyed(projects); - - inOrder.verify(listener1).onProjectsRekeyed(same(projects)); - inOrder.verify(listener2).onProjectsRekeyed(same(projects)); - inOrder.verify(listener3).onProjectsRekeyed(same(projects)); - inOrder.verifyNoMoreInteractions(); - } - - @DataProvider - public static Object[][] oneOrManyRekeyedProjects() { - return new Object[][] { - {singleton(newUniqueRekeyedProject())}, - {IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> newUniqueRekeyedProject()).collect(MoreCollectors.toSet())} - }; - } - - private static Project newUniqueProject() { - return Project.from(newPrivateProjectDto(newOrganizationDto())); - } - - private static int counter = 3_989; - - private static RekeyedProject newUniqueRekeyedProject() { - int base = counter++; - Project project = Project.from(newPrivateProjectDto(newOrganizationDto())); - return new RekeyedProject(project, base + "_old_key"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/RekeyedProjectTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/RekeyedProjectTest.java deleted file mode 100644 index a847d91d0d8..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/project/RekeyedProjectTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.project; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static java.util.Collections.emptyList; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; -import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; - -public class RekeyedProjectTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void constructor_throws_NPE_if_project_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("project can't be null"); - - new RekeyedProject(null, randomAlphanumeric(3)); - } - - @Test - public void constructor_throws_NPE_if_previousKey_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("previousKey can't be null"); - - new RekeyedProject(newRandomProject(), null); - } - - @Test - public void verify_getters() { - Project project = newRandomProject(); - String previousKey = randomAlphanumeric(6); - RekeyedProject underTest = new RekeyedProject(project, previousKey); - - assertThat(underTest.getProject()).isSameAs(project); - assertThat(underTest.getPreviousKey()).isEqualTo(previousKey); - } - - @Test - public void equals_is_based_on_project_and_previousKey() { - Project project = newRandomProject(); - String previousKey = randomAlphanumeric(6); - RekeyedProject underTest = new RekeyedProject(project, previousKey); - - assertThat(underTest).isEqualTo(underTest); - assertThat(underTest).isEqualTo(new RekeyedProject(project, previousKey)); - assertThat(underTest).isNotEqualTo(new RekeyedProject(project, randomAlphanumeric(11))); - assertThat(underTest).isNotEqualTo(new RekeyedProject(newRandomProject(), previousKey)); - assertThat(underTest).isNotEqualTo(new Object()); - assertThat(underTest).isNotEqualTo(null); - } - - @Test - public void hashCode_is_based_on_project_and_previousKey() { - Project project = newRandomProject(); - String previousKey = randomAlphanumeric(6); - RekeyedProject underTest = new RekeyedProject(project, previousKey); - - assertThat(underTest.hashCode()).isEqualTo(underTest.hashCode()); - assertThat(underTest.hashCode()).isEqualTo(new RekeyedProject(project, previousKey).hashCode()); - assertThat(underTest.hashCode()).isNotEqualTo(new RekeyedProject(project, randomAlphanumeric(11)).hashCode()); - assertThat(underTest.hashCode()).isNotEqualTo(new RekeyedProject(newRandomProject(), previousKey).hashCode()); - assertThat(underTest.hashCode()).isNotEqualTo(new Object().hashCode()); - assertThat(underTest.hashCode()).isNotEqualTo(null); - } - - @Test - public void verify_toString() { - Project project = new Project("A", "B", "C", "D", emptyList()); - String previousKey = "E"; - RekeyedProject underTest = new RekeyedProject(project, previousKey); - - assertThat(underTest.toString()).isEqualTo("RekeyedProject{project=Project{uuid='A', key='B', name='C', description='D'}, previousKey='E'}"); - } - - private static Project newRandomProject() { - return Project.from(newPrivateProjectDto(newOrganizationDto())); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ProjectsInWarningDaemonTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ProjectsInWarningDaemonTest.java deleted file mode 100644 index ba56ae7b267..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ProjectsInWarningDaemonTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Metric; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.measure.index.ProjectMeasuresIndex; -import org.sonar.server.measure.index.ProjectMeasuresIndexer; -import org.sonar.server.permission.index.PermissionIndexerTester; -import org.sonar.server.permission.index.WebAuthorizationTypeSupport; -import org.sonar.server.util.GlobalLockManager; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.measures.Metric.Level.WARN; -import static org.sonar.db.measure.MeasureTesting.newLiveMeasure; -import static org.sonar.server.qualitygate.ProjectsInWarningDaemon.PROJECTS_IN_WARNING_INTERNAL_PROPERTY; - -public class ProjectsInWarningDaemonTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(); - @Rule - public EsTester es = EsTester.create(); - @Rule - public LogTester logger = new LogTester().setLevel(LoggerLevel.DEBUG); - - private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, new ProjectMeasuresIndexer(db.getDbClient(), es.client())); - private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client()); - private ProjectMeasuresIndex projectMeasuresIndex = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(null), System2.INSTANCE); - - private MapSettings settings = new MapSettings(); - private GlobalLockManager lockManager = mock(GlobalLockManager.class); - private ProjectsInWarning projectsInWarning = new ProjectsInWarning(); - - private ProjectsInWarningDaemon underTest = new ProjectsInWarningDaemon(db.getDbClient(), projectMeasuresIndex, settings.asConfig(), lockManager, projectsInWarning); - - @Before - public void setUp() throws Exception { - settings.setProperty("sonar.projectsInWarning.frequencyInMilliseconds", "100"); - } - - @After - public void tearDown() { - underTest.stop(); - } - - @Test - public void store_projects_in_warning() throws InterruptedException { - allowLockToBeAcquired(); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - insertProjectInWarning(qualityGateStatus); - insertProjectInWarning(qualityGateStatus); - // Setting does not exist - assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty(); - - underTest.notifyStart(); - - assertProjectsInWarningValue(2L); - assertThat(logger.logs(LoggerLevel.INFO)).contains("Counting number of projects in warning is enabled."); - } - - @Test - public void update_projects_in_warning_when_new_project_in_warning() throws InterruptedException { - allowLockToBeAcquired(); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - ; - insertProjectInWarning(qualityGateStatus); - insertProjectInWarning(qualityGateStatus); - // Setting does not exist - assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty(); - - underTest.notifyStart(); - // Add a project in warning after the start in order to let the thread do his job - insertProjectInWarning(qualityGateStatus); - - assertProjectsInWarningValue(3L); - assertThat(logger.logs(LoggerLevel.INFO)).contains("Counting number of projects in warning is enabled."); - } - - @Test - public void stop_thread_when_number_of_projects_in_warning_reach_zero() throws InterruptedException { - allowLockToBeAcquired(); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - ; - ComponentDto project = insertProjectInWarning(qualityGateStatus); - - underTest.notifyStart(); - assertProjectsInWarningValue(1L); - // Set quality gate status of the project to OK => No more projects in warning - db.getDbClient().liveMeasureDao().insertOrUpdate(db.getSession(), - newLiveMeasure(project, qualityGateStatus).setData(Metric.Level.OK.name()).setValue(null)); - db.commit(); - projectMeasuresIndexer.indexOnAnalysis(project.uuid()); - - assertProjectsInWarningValue(0L); - assertThat(logger.logs(LoggerLevel.INFO)) - .contains( - "Counting number of projects in warning is enabled.", - "Counting number of projects in warning will be disabled as there are no more projects in warning."); - } - - @Test - public void update_internal_properties_when_already_exits_and_projects_in_warnings_more_than_zero() throws InterruptedException { - allowLockToBeAcquired(); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - insertProjectInWarning(qualityGateStatus); - insertProjectInWarning(qualityGateStatus); - // Setting contains 10, it should be updated with new value - db.getDbClient().internalPropertiesDao().save(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY, "10"); - db.commit(); - - underTest.notifyStart(); - - assertProjectsInWarningValue(2L); - assertThat(logger.logs(LoggerLevel.INFO)).contains("Counting number of projects in warning is enabled."); - } - - @Test - public void store_zero_projects_in_warning_when_no_projects() throws InterruptedException { - allowLockToBeAcquired(); - assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty(); - - underTest.notifyStart(); - - assertProjectsInWarningValue(0L); - assertThat(logger.logs(LoggerLevel.INFO)).contains("Counting number of projects in warning is enabled."); - } - - @Test - public void do_not_compute_projects_in_warning_when_internal_property_is_zero() throws InterruptedException { - allowLockToBeAcquired(); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - ; - insertProjectInWarning(qualityGateStatus); - // Setting contains 0, even if there are projects in warning it will stay 0 (as it's not possible to have new projects in warning) - db.getDbClient().internalPropertiesDao().save(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY, "0"); - db.commit(); - - underTest.notifyStart(); - - assertProjectsInWarningValue(0L); - assertThat(logger.logs(LoggerLevel.INFO)).contains("Counting number of projects in warning is not started as there are no projects in this situation."); - } - - @Test - public void do_not_store_projects_in_warning_in_db_when_cannot_acquire_lock() throws InterruptedException { - when(lockManager.tryLock(any(), anyInt())).thenReturn(false); - MetricDto qualityGateStatus = insertQualityGateStatusMetric(); - ; - insertProjectInWarning(qualityGateStatus); - - underTest.notifyStart(); - - waitForValueToBeComputed(1L); - assertThat(projectsInWarning.count()).isEqualTo(1L); - assertThat(countNumberOfProjectsInWarning()).isEqualTo(0L); - } - - private void waitForValueToBeComputed(long expectedValue) throws InterruptedException { - for (int i = 0; i < 1000; i++) { - if (projectsInWarning.isInitialized() && projectsInWarning.count() == expectedValue) { - break; - } - Thread.sleep(100); - } - } - - private void assertProjectsInWarningValue(long expectedValue) throws InterruptedException { - waitForValueToBeComputed(expectedValue); - assertThat(projectsInWarning.count()).isEqualTo(expectedValue); - assertThat(countNumberOfProjectsInWarning()).isEqualTo(expectedValue); - } - - private long countNumberOfProjectsInWarning() { - return db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY) - .map(Long::valueOf) - .orElse(0L); - } - - private ComponentDto insertProjectInWarning(MetricDto qualityGateStatus) { - ComponentDto project = db.components().insertPrivateProject(); - db.measures().insertLiveMeasure(project, qualityGateStatus, lm -> lm.setData(WARN.name()).setValue(null)); - authorizationIndexerTester.allowOnlyAnyone(project); - projectMeasuresIndexer.indexOnAnalysis(project.uuid()); - return project; - } - - private MetricDto insertQualityGateStatusMetric() { - return db.measures().insertMetric(m -> m.setKey(CoreMetrics.ALERT_STATUS_KEY).setValueType(Metric.ValueType.LEVEL.name())); - } - - private void allowLockToBeAcquired() { - when(lockManager.tryLock(any(), anyInt())).thenReturn(true); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java deleted file mode 100644 index a3da151ae34..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConditionsUpdaterTest.java +++ /dev/null @@ -1,405 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.measures.Metric; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.qualitygate.QualityGateConditionDto; -import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.NotFoundException; - -import static java.lang.String.format; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; -import static org.sonar.api.measures.CoreMetrics.SECURITY_REVIEW_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; -import static org.sonar.api.measures.Metric.ValueType.BOOL; -import static org.sonar.api.measures.Metric.ValueType.DATA; -import static org.sonar.api.measures.Metric.ValueType.DISTRIB; -import static org.sonar.api.measures.Metric.ValueType.FLOAT; -import static org.sonar.api.measures.Metric.ValueType.INT; -import static org.sonar.api.measures.Metric.ValueType.MILLISEC; -import static org.sonar.api.measures.Metric.ValueType.PERCENT; -import static org.sonar.api.measures.Metric.ValueType.RATING; -import static org.sonar.api.measures.Metric.ValueType.STRING; -import static org.sonar.api.measures.Metric.ValueType.WORK_DUR; - -@RunWith(DataProviderRunner.class) -public class QualityGateConditionsUpdaterTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private QualityGateConditionsUpdater underTest = new QualityGateConditionsUpdater(db.getDbClient()); - - @Test - public void create_error_condition() { - MetricDto metric = insertMetric(INT, "new_coverage"); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); - - verifyCondition(result, qualityGate, metric, "LT", "80"); - } - - @Test - @UseDataProvider("valid_operators_and_direction") - public void create_condition_with_valid_operators_and_direction(String operator, int direction) { - MetricDto metric = db.measures().insertMetric(m -> m.setKey("key").setValueType(INT.name()).setHidden(false).setDirection(direction)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), operator, "80"); - - verifyCondition(result, qualityGate, metric, operator, "80"); - } - - @Test - public void create_condition_throws_NPE_if_errorThreshold_is_null() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("errorThreshold can not be null"); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null); - } - - @Test - public void fail_to_create_condition_when_condition_on_same_metric_already_exist() { - MetricDto metric = insertMetric(PERCENT); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - db.qualityGates().addCondition(qualityGate, metric); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Condition on metric '%s' already exists.", metric.getShortName())); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); - } - - @Test - public void fail_to_create_condition_on_missing_metric() { - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("There is no metric with key=new_coverage"); - - underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", "80"); - } - - @Test - @UseDataProvider("invalid_metrics") - public void fail_to_create_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) { - MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden).setDirection(0)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition", metric.getKey())); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); - } - - @Test - @UseDataProvider("invalid_operators_and_direction") - public void fail_to_create_condition_on_not_allowed_operator_for_metric_direction(String operator, int direction) { - MetricDto metric = db.measures().insertMetric(m -> m.setKey("key").setValueType(INT.name()).setHidden(false).setDirection(direction)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Operator %s is not allowed for this metric.", operator)); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), operator, "90"); - } - - @Test - public void create_condition_on_rating_metric() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "3"); - - verifyCondition(result, qualityGate, metric, "GT", "3"); - } - - @Test - public void fail_to_create_error_condition_on_invalid_rating_metric() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("'80' is not a valid rating"); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "80"); - } - - @Test - public void fail_to_create_condition_on_rating_greater_than_E() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("There's no worse rating than E (5)"); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5"); - } - - @Test - @UseDataProvider("valid_values") - public void create_error_condition(Metric.ValueType valueType, String value) { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", value); - - verifyCondition(result, qualityGate, metric, "LT", value); - } - - @Test - @UseDataProvider("invalid_values") - public void fail_to_create_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName())); - - underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", value); - } - - @Test - public void update_condition() { - MetricDto metric = insertMetric(PERCENT); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", "80"); - - verifyCondition(result, qualityGate, metric, "LT", "80"); - } - - @Test - public void update_condition_throws_NPE_if_errorThreshold_is_null() { - MetricDto metric = insertMetric(PERCENT); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("errorThreshold can not be null"); - - underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", null); - } - - @Test - public void update_condition_on_rating_metric() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4"); - - verifyCondition(result, qualityGate, metric, "GT", "4"); - } - - @Test - @UseDataProvider("update_invalid_operators_and_direction") - public void fail_to_update_condition_on_not_allowed_operator_for_metric_direction(String validOperator, String updatedOperator, int direction) { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(PERCENT.name()).setHidden(false).setDirection(direction)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator(validOperator).setErrorThreshold("80")); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Operator %s is not allowed for this metric", updatedOperator)); - - underTest.updateCondition(db.getSession(), condition, metric.getKey(), updatedOperator, "70"); - } - - @Test - public void fail_to_update_condition_on_rating_metric_on_leak_period() { - MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("3")); - - QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4"); - - verifyCondition(result, qualityGate, metric, "GT", "4"); - } - - @Test - public void fail_to_update_condition_on_rating_metric_on_not_core_rating_metric() { - MetricDto metric = insertMetric(RATING, "not_core_rating_metric"); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("3")); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("The metric '%s' cannot be used", metric.getShortName())); - - underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4"); - } - - @Test - @UseDataProvider("invalid_metrics") - public void fail_to_update_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) { - MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition", metric.getKey())); - - underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "60"); - } - - @Test - @UseDataProvider("valid_values") - public void update_error_condition(Metric.ValueType valueType, String value) { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", value); - - verifyCondition(result, qualityGate, metric, "LT", value); - } - - @Test - @UseDataProvider("invalid_values") - public void fail_to_update_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); - QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, - c -> c.setOperator("LT").setErrorThreshold("80")); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName())); - - underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", value); - } - - @DataProvider - public static Object[][] invalid_metrics() { - return new Object[][] { - {ALERT_STATUS_KEY, INT, false}, - {SECURITY_REVIEW_RATING_KEY, RATING, false}, - {"boolean", BOOL, false}, - {"string", STRING, false}, - {"data_metric", DATA, false}, - {"distrib", DISTRIB, false}, - {"hidden", INT, true} - }; - } - - @DataProvider - public static Object[][] valid_values() { - return new Object[][] { - {INT, "10"}, - {MILLISEC, "1000"}, - {WORK_DUR, "1000"}, - {FLOAT, "5.12"}, - {PERCENT, "10.30"}, - }; - } - - @DataProvider - public static Object[][] invalid_values() { - return new Object[][] { - {INT, "ABCD"}, - {MILLISEC, "ABCD"}, - {WORK_DUR, "ABCD"}, - {FLOAT, "ABCD"}, - {PERCENT, "ABCD"}, - }; - } - - @DataProvider - public static Object[][] invalid_operators_and_direction() { - return new Object[][] { - {"EQ", 0}, - {"NE", 0}, - {"LT", -1}, - {"GT", 1}, - }; - } - - @DataProvider - public static Object[][] update_invalid_operators_and_direction() { - return new Object[][] { - {"LT", "EQ", 0}, - {"LT", "NE", 0}, - {"GT", "LT", -1}, - {"LT", "GT", 1}, - }; - } - - @DataProvider - public static Object[][] valid_operators_and_direction() { - return new Object[][] { - {"LT", 0}, - {"GT", 0}, - {"GT", -1}, - {"LT", 1}, - }; - } - - private MetricDto insertMetric(Metric.ValueType type) { - return insertMetric(type, "key"); - } - - private MetricDto insertMetric(Metric.ValueType type, String key) { - return db.measures().insertMetric(m -> m - .setKey(key) - .setValueType(type.name()) - .setHidden(false) - .setDirection(0)); - } - - private void verifyCondition(QualityGateConditionDto dto, QualityGateDto qualityGate, MetricDto metric, String operator, String error) { - QualityGateConditionDto reloaded = db.getDbClient().gateConditionDao().selectById(dto.getId(), db.getSession()); - assertThat(reloaded.getQualityGateId()).isEqualTo(qualityGate.getId()); - assertThat(reloaded.getMetricId()).isEqualTo(metric.getId().longValue()); - assertThat(reloaded.getOperator()).isEqualTo(operator); - assertThat(reloaded.getErrorThreshold()).isEqualTo(error); - - assertThat(dto.getQualityGateId()).isEqualTo(qualityGate.getId()); - assertThat(dto.getMetricId()).isEqualTo(metric.getId().longValue()); - assertThat(dto.getOperator()).isEqualTo(operator); - assertThat(dto.getErrorThreshold()).isEqualTo(error); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConverterTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConverterTest.java deleted file mode 100644 index c956b400763..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateConverterTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import org.junit.Test; - -public class QualityGateConverterTest { - - @Test - public void test_ToJson() { - // FIXME - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java deleted file mode 100644 index db4417f0247..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import org.junit.Test; -import org.sonar.core.platform.ComponentContainer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; - -public class QualityGateModuleTest { - @Test - public void verify_count_of_added_components() { - ComponentContainer container = new ComponentContainer(); - new QualityGateModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 6); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java deleted file mode 100644 index 574903dd0e5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualitygate.QualityGateDto; - -public class QualityGateUpdaterTest { - - static final String QGATE_NAME = "Default"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - private QualityGateUpdater underTest = new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance()); - - @Test - public void create_quality_gate() { - OrganizationDto organization = db.organizations().insert(); - - QualityGateDto result = underTest.create(dbSession, organization, QGATE_NAME); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo(QGATE_NAME); - assertThat(result.getCreatedAt()).isNotNull(); - assertThat(result.isBuiltIn()).isFalse(); - QualityGateDto reloaded = dbClient.qualityGateDao().selectByName(dbSession, QGATE_NAME); - assertThat(reloaded).isNotNull(); - } - - @Test - public void fail_to_create_when_name_already_exists() { - OrganizationDto org = db.organizations().insert(); - underTest.create(dbSession, org, QGATE_NAME); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Name has already been taken"); - - underTest.create(dbSession, org, QGATE_NAME); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/RegisterQualityGatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/RegisterQualityGatesTest.java deleted file mode 100644 index 176e7f3e623..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/RegisterQualityGatesTest.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Random; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.core.util.Uuids; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.metric.MetricDao; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.qualitygate.QualityGateConditionDao; -import org.sonar.db.qualitygate.QualityGateConditionDto; -import org.sonar.db.qualitygate.QualityGateDao; -import org.sonar.db.qualitygate.QualityGateDto; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT_KEY; -import static org.sonar.api.measures.Metric.ValueType.INT; -import static org.sonar.api.measures.Metric.ValueType.PERCENT; -import static org.sonar.db.metric.MetricTesting.newMetricDto; -import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_GREATER_THAN; -import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_LESS_THAN; - -public class RegisterQualityGatesTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public LogTester logTester = new LogTester(); - - private static final String BUILT_IN_NAME = "Sonar way"; - - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - - private QualityGateDao qualityGateDao = dbClient.qualityGateDao(); - private QualityGateConditionDao gateConditionDao = dbClient.gateConditionDao(); - private MetricDao metricDao = dbClient.metricDao(); - private QualityGateConditionsUpdater qualityGateConditionsUpdater = new QualityGateConditionsUpdater(dbClient); - private QualityGateFinder qualityGateFinder = new QualityGateFinder(dbClient); - - private RegisterQualityGates underTest = new RegisterQualityGates(dbClient, qualityGateConditionsUpdater, - UuidFactoryFast.getInstance(), System2.INSTANCE); - - @Test - public void register_default_gate() { - insertMetrics(); - - underTest.start(); - - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isTrue(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - @Test - public void upgrade_empty_quality_gate() { - insertMetrics(); - - underTest.start(); - - assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - @Test - public void upgrade_should_remove_deleted_condition() { - insertMetrics(); - QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate(); - createBuiltInConditions(builtInQualityGate); - // Add another condition - qualityGateConditionsUpdater.createCondition(dbSession, builtInQualityGate, - NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, "5"); - dbSession.commit(); - - underTest.start(); - - assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - @Test - public void upgrade_should_add_missing_condition() { - insertMetrics(); - QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate(); - List<QualityGateConditionDto> builtInConditions = createBuiltInConditions(builtInQualityGate); - // Remove a condition - QualityGateConditionDto conditionToBeDeleted = builtInConditions.get(new Random().nextInt(builtInConditions.size())); - gateConditionDao.delete(conditionToBeDeleted, dbSession); - dbSession.commit(); - - underTest.start(); - - assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - @Test - public void should_set_SonarWay_as_builtin_when_not_set() { - insertMetrics(); - QualityGateDto qualityGate = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto() - .setName("Sonar way") - .setUuid(Uuids.createFast()) - .setBuiltIn(false) - .setCreatedAt(new Date())); - dbSession.commit(); - createBuiltInConditions(qualityGate); - dbSession.commit(); - - underTest.start(); - - assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Quality gate [Sonar way] has been set as built-in")).isTrue(); - } - - @Test - public void should_not_update_builtin_quality_gate_if_already_uptodate() { - insertMetrics(); - QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate(); - createBuiltInConditions(builtInQualityGate); - dbSession.commit(); - - underTest.start(); - - assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); - verifyCorrectBuiltInQualityGate(); - // Log must not be present - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Quality gate [Sonar way] has been set as built-in")).isFalse(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isFalse(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isFalse(); - } - - @Test - public void ensure_only_one_built_in_quality_gate() { - insertMetrics(); - String qualityGateName = "IncorrectQualityGate"; - QualityGateDto builtin = new QualityGateDto().setName(qualityGateName).setBuiltIn(true).setUuid(Uuids.createFast()); - qualityGateDao.insert(dbSession, builtin); - dbSession.commit(); - - underTest.start(); - - QualityGateDto oldQualityGate = qualityGateDao.selectByName(dbSession, qualityGateName); - assertThat(oldQualityGate).isNotNull(); - assertThat(oldQualityGate.isBuiltIn()).isFalse(); - assertThat(db.select("select name as \"name\" from quality_gates where is_built_in is true")) - .extracting(column -> column.get("name")) - .containsExactly(BUILT_IN_NAME); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate [Sonar way] has been created")).isTrue(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - @Test - public void ensure_only_that_builtin_is_set_as_default_when_no_default_quality_gate() { - insertMetrics(); - QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate(); - - underTest.start(); - - assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession)).isNotNull(); - assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession).getId()).isEqualTo(builtInQualityGate.getId()); - } - - @Test - public void builtin_quality_gate_with_incorrect_metricId_should_not_throw_an_exception() { - insertMetrics(); - QualityGateConditionDto conditionDto = new QualityGateConditionDto() - .setMetricId(-1) // This Id does not exist - .setOperator(OPERATOR_GREATER_THAN) - .setErrorThreshold("1"); - gateConditionDao.insert(conditionDto, dbSession); - dbSession.commit(); - - underTest.start(); - - // No exception thrown - verifyCorrectBuiltInQualityGate(); - assertThat( - logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); - } - - private void insertMetrics() { - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_RELIABILITY_RATING_KEY).setValueType(INT.name()).setHidden(false).setDirection(0)); - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_SECURITY_RATING_KEY).setValueType(INT.name()).setHidden(false).setDirection(0)); - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_SECURITY_REMEDIATION_EFFORT_KEY).setValueType(INT.name()).setHidden(false).setDirection(0)); - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_MAINTAINABILITY_RATING_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0)); - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_COVERAGE_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0)); - dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name()).setHidden(false).setDirection(0)); - dbSession.commit(); - } - - private void verifyCorrectBuiltInQualityGate() { - MetricDto newReliability = metricDao.selectByKey(dbSession, NEW_RELIABILITY_RATING_KEY); - MetricDto newSecurity = metricDao.selectByKey(dbSession, NEW_SECURITY_RATING_KEY); - MetricDto newMaintainability = metricDao.selectByKey(dbSession, NEW_MAINTAINABILITY_RATING_KEY); - MetricDto newCoverage = metricDao.selectByKey(dbSession, NEW_COVERAGE_KEY); - MetricDto newDuplication = metricDao.selectByKey(dbSession, NEW_DUPLICATED_LINES_DENSITY_KEY); - - QualityGateDto qualityGateDto = qualityGateDao.selectByName(dbSession, BUILT_IN_NAME); - assertThat(qualityGateDto).isNotNull(); - assertThat(qualityGateDto.getCreatedAt()).isNotNull(); - assertThat(qualityGateDto.isBuiltIn()).isTrue(); - assertThat(gateConditionDao.selectForQualityGate(dbSession, qualityGateDto.getId())) - .extracting(QualityGateConditionDto::getMetricId, QualityGateConditionDto::getOperator, - QualityGateConditionDto::getErrorThreshold) - .containsOnly( - tuple(newReliability.getId().longValue(), OPERATOR_GREATER_THAN, "1"), - tuple(newSecurity.getId().longValue(), OPERATOR_GREATER_THAN, "1"), - tuple(newMaintainability.getId().longValue(), OPERATOR_GREATER_THAN, "1"), - tuple(newCoverage.getId().longValue(), OPERATOR_LESS_THAN, "80"), - tuple(newDuplication.getId().longValue(), OPERATOR_GREATER_THAN, "3")); - } - - private List<QualityGateConditionDto> createBuiltInConditions(QualityGateDto qg) { - List<QualityGateConditionDto> conditions = new ArrayList<>(); - - conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, - NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); - conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, - NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); - conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, - NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); - conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, - NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, "80")); - conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, - NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, "3")); - - return conditions; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java deleted file mode 100644 index 964637487fb..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate.changeevent; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.apache.commons.lang.RandomStringUtils; -import org.assertj.core.groups.Tuple; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mockito; -import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.issue.DefaultIssue; -import org.sonar.db.component.ComponentDto; -import org.sonar.server.qualitygate.changeevent.QGChangeEventListener.ChangedIssue; -import org.sonar.server.qualitygate.changeevent.QGChangeEventListenersImpl.ChangedIssueImpl; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptySet; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class QGChangeEventListenersImplTest { - @Rule - public LogTester logTester = new LogTester(); - - private QGChangeEventListener listener1 = mock(QGChangeEventListener.class); - private QGChangeEventListener listener2 = mock(QGChangeEventListener.class); - private QGChangeEventListener listener3 = mock(QGChangeEventListener.class); - private List<QGChangeEventListener> listeners = Arrays.asList(listener1, listener2, listener3); - - private String component1Uuid = RandomStringUtils.randomAlphabetic(6); - private ComponentDto component1 = newComponentDto(component1Uuid); - private DefaultIssue component1Issue = newDefaultIssue(component1Uuid); - private List<DefaultIssue> oneIssueOnComponent1 = singletonList(component1Issue); - private QGChangeEvent component1QGChangeEvent = newQGChangeEvent(component1); - - private InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3); - - private QGChangeEventListenersImpl underTest = new QGChangeEventListenersImpl(new QGChangeEventListener[] {listener1, listener2, listener3}); - - @Test - public void broadcastOnIssueChange_has_no_effect_when_issues_are_empty() { - underTest.broadcastOnIssueChange(emptyList(), singletonList(component1QGChangeEvent)); - - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - public void broadcastOnIssueChange_has_no_effect_when_no_changeEvent() { - underTest.broadcastOnIssueChange(oneIssueOnComponent1, emptySet()); - - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - public void broadcastOnIssueChange_passes_same_arguments_to_all_listeners_in_order_of_addition_to_constructor() { - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor(); - inOrder.verify(listener1).onIssueChanges(same(component1QGChangeEvent), changedIssuesCaptor.capture()); - Set<ChangedIssue> changedIssues = changedIssuesCaptor.getValue(); - inOrder.verify(listener2).onIssueChanges(same(component1QGChangeEvent), same(changedIssues)); - inOrder.verify(listener3).onIssueChanges(same(component1QGChangeEvent), same(changedIssues)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - public void broadcastOnIssueChange_calls_all_listeners_even_if_one_throws_an_exception() { - QGChangeEventListener failingListener = new QGChangeEventListener[] {listener1, listener2, listener3}[new Random().nextInt(3)]; - doThrow(new RuntimeException("Faking an exception thrown by onChanges")) - .when(failingListener) - .onIssueChanges(any(), any()); - - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor(); - inOrder.verify(listener1).onIssueChanges(same(component1QGChangeEvent), changedIssuesCaptor.capture()); - Set<ChangedIssue> changedIssues = changedIssuesCaptor.getValue(); - inOrder.verify(listener2).onIssueChanges(same(component1QGChangeEvent), same(changedIssues)); - inOrder.verify(listener3).onIssueChanges(same(component1QGChangeEvent), same(changedIssues)); - inOrder.verifyNoMoreInteractions(); - assertThat(logTester.logs()).hasSize(4); - assertThat(logTester.logs(LoggerLevel.WARN)).hasSize(1); - } - - @Test - public void broadcastOnIssueChange_stops_calling_listeners_when_one_throws_an_ERROR() { - doThrow(new Error("Faking an error thrown by a listener")) - .when(listener2) - .onIssueChanges(any(), any()); - - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor(); - inOrder.verify(listener1).onIssueChanges(same(component1QGChangeEvent), changedIssuesCaptor.capture()); - Set<ChangedIssue> changedIssues = changedIssuesCaptor.getValue(); - inOrder.verify(listener2).onIssueChanges(same(component1QGChangeEvent), same(changedIssues)); - inOrder.verifyNoMoreInteractions(); - assertThat(logTester.logs()).hasSize(3); - assertThat(logTester.logs(LoggerLevel.WARN)).hasSize(1); - } - - @Test - public void broadcastOnIssueChange_logs_each_listener_call_at_TRACE_level() { - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - assertThat(logTester.logs()).hasSize(3); - List<String> traceLogs = logTester.logs(LoggerLevel.TRACE); - assertThat(traceLogs).hasSize(3) - .containsOnly( - "calling onChange() on listener " + listener1.getClass().getName() + " for events " + component1QGChangeEvent.toString() + "...", - "calling onChange() on listener " + listener2.getClass().getName() + " for events " + component1QGChangeEvent.toString() + "...", - "calling onChange() on listener " + listener3.getClass().getName() + " for events " + component1QGChangeEvent.toString() + "..."); - } - - @Test - public void broadcastOnIssueChange_passes_immutable_set_of_ChangedIssues() { - QGChangeEventListenersImpl underTest = new QGChangeEventListenersImpl(new QGChangeEventListener[] {listener1}); - - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor(); - inOrder.verify(listener1).onIssueChanges(same(component1QGChangeEvent), changedIssuesCaptor.capture()); - assertThat(changedIssuesCaptor.getValue()).isInstanceOf(ImmutableSet.class); - } - - @Test - public void broadcastOnIssueChange_has_no_effect_when_no_listener() { - QGChangeEventListenersImpl underTest = new QGChangeEventListenersImpl(); - - underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent)); - - verifyZeroInteractions(listener1, listener2, listener3); - } - - @Test - public void broadcastOnIssueChange_calls_listener_for_each_component_uuid_with_at_least_one_QGChangeEvent() { - // component2 has multiple issues - ComponentDto component2 = newComponentDto(component1Uuid + "2"); - DefaultIssue[] component2Issues = {newDefaultIssue(component2.uuid()), newDefaultIssue(component2.uuid())}; - QGChangeEvent component2QGChangeEvent = newQGChangeEvent(component2); - - // component 3 has multiple QGChangeEvent and only one issue - ComponentDto component3 = newComponentDto(component1Uuid + "3"); - DefaultIssue component3Issue = newDefaultIssue(component3.uuid()); - QGChangeEvent[] component3QGChangeEvents = {newQGChangeEvent(component3), newQGChangeEvent(component3)}; - - // component 4 has multiple QGChangeEvent and multiples issues - ComponentDto component4 = newComponentDto(component1Uuid + "4"); - DefaultIssue[] component4Issues = {newDefaultIssue(component4.uuid()), newDefaultIssue(component4.uuid())}; - QGChangeEvent[] component4QGChangeEvents = {newQGChangeEvent(component4), newQGChangeEvent(component4)}; - - // component 5 has no QGChangeEvent but one issue - ComponentDto component5 = newComponentDto(component1Uuid + "5"); - DefaultIssue component5Issue = newDefaultIssue(component5.uuid()); - - List<DefaultIssue> issues = Stream.of( - Stream.of(component1Issue), - Arrays.stream(component2Issues), - Stream.of(component3Issue), - Arrays.stream(component4Issues), - Stream.of(component5Issue)) - .flatMap(s -> s) - .collect(Collectors.toList()); - - List<DefaultIssue> changedIssues = randomizedList(issues); - List<QGChangeEvent> qgChangeEvents = Stream.of( - Stream.of(component1QGChangeEvent), - Stream.of(component2QGChangeEvent), - Arrays.stream(component3QGChangeEvents), - Arrays.stream(component4QGChangeEvents)) - .flatMap(s -> s) - .collect(Collectors.toList()); - - underTest.broadcastOnIssueChange(changedIssues, randomizedList(qgChangeEvents)); - - listeners.forEach(listener -> { - verifyListenerCalled(listener, component1QGChangeEvent, component1Issue); - verifyListenerCalled(listener, component2QGChangeEvent, component2Issues); - Arrays.stream(component3QGChangeEvents) - .forEach(component3QGChangeEvent -> verifyListenerCalled(listener, component3QGChangeEvent, component3Issue)); - Arrays.stream(component4QGChangeEvents) - .forEach(component4QGChangeEvent -> verifyListenerCalled(listener, component4QGChangeEvent, component4Issues)); - }); - verifyNoMoreInteractions(listener1, listener2, listener3); - } - - @Test - public void isNotClosed_returns_true_if_issue_in_one_of_opened_states() { - DefaultIssue defaultIssue = new DefaultIssue(); - defaultIssue.setStatus(Issue.STATUS_REOPENED); - defaultIssue.setKey("abc"); - defaultIssue.setType(RuleType.BUG); - defaultIssue.setSeverity("BLOCKER"); - - ChangedIssue changedIssue = new ChangedIssueImpl(defaultIssue); - - assertThat(changedIssue.isNotClosed()).isTrue(); - } - - @Test - public void isNotClosed_returns_false_if_issue_in_one_of_closed_states() { - DefaultIssue defaultIssue = new DefaultIssue(); - defaultIssue.setStatus(Issue.STATUS_CONFIRMED); - defaultIssue.setKey("abc"); - defaultIssue.setType(RuleType.BUG); - defaultIssue.setSeverity("BLOCKER"); - - ChangedIssue changedIssue = new ChangedIssueImpl(defaultIssue); - - assertThat(changedIssue.isNotClosed()).isFalse(); - } - - @Test - public void test_status_mapping() { - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_OPEN))).isEqualTo(QGChangeEventListener.Status.OPEN); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_REOPENED))).isEqualTo(QGChangeEventListener.Status.REOPENED); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_CONFIRMED))).isEqualTo(QGChangeEventListener.Status.CONFIRMED); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FALSE_POSITIVE))) - .isEqualTo(QGChangeEventListener.Status.RESOLVED_FP); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX))) - .isEqualTo(QGChangeEventListener.Status.RESOLVED_WF); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FIXED))) - .isEqualTo(QGChangeEventListener.Status.RESOLVED_FIXED); - try { - ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_CLOSED)); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Unexpected status: CLOSED"); - } - try { - ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_RESOLVED)); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("A resolved issue should have a resolution"); - } - try { - ChangedIssueImpl.statusOf(new DefaultIssue().setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_REMOVED)); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Unexpected resolution for a resolved issue: REMOVED"); - } - } - - @Test - public void test_status_mapping_on_security_hotspots() { - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW))) - .isEqualTo(QGChangeEventListener.Status.TO_REVIEW); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW))) - .isEqualTo(QGChangeEventListener.Status.IN_REVIEW); - assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED))) - .isEqualTo(QGChangeEventListener.Status.REVIEWED); - } - - private void verifyListenerCalled(QGChangeEventListener listener, QGChangeEvent changeEvent, DefaultIssue... issues) { - ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor(); - verify(listener).onIssueChanges(same(changeEvent), changedIssuesCaptor.capture()); - Set<ChangedIssue> changedIssues = changedIssuesCaptor.getValue(); - Tuple[] expected = Arrays.stream(issues) - .map(issue -> tuple(issue.key(), ChangedIssueImpl.statusOf(issue), issue.type())) - .toArray(Tuple[]::new); - assertThat(changedIssues) - .hasSize(issues.length) - .extracting(ChangedIssue::getKey, ChangedIssue::getStatus, ChangedIssue::getType) - .containsOnly(expected); - } - - private static final String[] POSSIBLE_STATUSES = asList(Issue.STATUS_CONFIRMED, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED).stream().toArray(String[]::new); - private static int issueIdCounter = 0; - - private static DefaultIssue newDefaultIssue(String projectUuid) { - DefaultIssue defaultIssue = new DefaultIssue(); - defaultIssue.setKey("issue_" + issueIdCounter++); - defaultIssue.setProjectUuid(projectUuid); - defaultIssue.setType(RuleType.values()[new Random().nextInt(RuleType.values().length)]); - defaultIssue.setStatus(POSSIBLE_STATUSES[new Random().nextInt(POSSIBLE_STATUSES.length)]); - String[] possibleResolutions = possibleResolutions(defaultIssue.getStatus()); - if (possibleResolutions.length > 0) { - defaultIssue.setResolution(possibleResolutions[new Random().nextInt(possibleResolutions.length)]); - } - return defaultIssue; - } - - private static String[] possibleResolutions(String status) { - switch (status) { - case Issue.STATUS_RESOLVED: - return new String[] {Issue.RESOLUTION_FALSE_POSITIVE, Issue.RESOLUTION_WONT_FIX}; - default: - return new String[0]; - } - } - - private static ComponentDto newComponentDto(String uuid) { - ComponentDto componentDto = new ComponentDto(); - componentDto.setUuid(uuid); - return componentDto; - } - - private static QGChangeEvent newQGChangeEvent(ComponentDto componentDto) { - QGChangeEvent res = mock(QGChangeEvent.class); - when(res.getProject()).thenReturn(componentDto); - return res; - } - - private static <T> ArgumentCaptor<Set<T>> newSetCaptor() { - Class<Set<T>> clazz = (Class<Set<T>>) (Class) Set.class; - return ArgumentCaptor.forClass(clazz); - } - - private static <T> List<T> randomizedList(List<T> issues) { - ArrayList<T> res = new ArrayList<>(issues); - Collections.shuffle(res); - return ImmutableList.copyOf(res); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventTest.java deleted file mode 100644 index eb4ce5d6c60..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualitygate.changeevent; - -import java.util.Optional; -import java.util.Random; -import java.util.function.Supplier; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; -import org.sonar.api.config.Configuration; -import org.sonar.api.measures.Metric; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.SnapshotDto; -import org.sonar.server.qualitygate.EvaluatedQualityGate; - -import static org.assertj.core.api.Assertions.assertThat; - -public class QGChangeEventTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private ComponentDto project = new ComponentDto() - .setDbKey("foo") - .setUuid("bar"); - private BranchDto branch = new BranchDto() - .setBranchType(BranchType.SHORT) - .setUuid("bar") - .setProjectUuid("doh") - .setMergeBranchUuid("zop"); - private SnapshotDto analysis = new SnapshotDto() - .setUuid("pto") - .setCreatedAt(8_999_999_765L); - private Configuration configuration = Mockito.mock(Configuration.class); - private Metric.Level previousStatus = Metric.Level.values()[new Random().nextInt(Metric.Level.values().length)]; - private Supplier<Optional<EvaluatedQualityGate>> supplier = Optional::empty; - - @Test - public void constructor_fails_with_NPE_if_project_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("project can't be null"); - - new QGChangeEvent(null, branch, analysis, configuration, previousStatus, supplier); - } - - @Test - public void constructor_fails_with_NPE_if_branch_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("branch can't be null"); - - new QGChangeEvent(project, null, analysis, configuration, previousStatus, supplier); - } - - @Test - public void constructor_fails_with_NPE_if_analysis_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("analysis can't be null"); - - new QGChangeEvent(project, branch, null, configuration, previousStatus, supplier); - } - - @Test - public void constructor_fails_with_NPE_if_configuration_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("projectConfiguration can't be null"); - - new QGChangeEvent(project, branch, analysis, null, previousStatus, supplier); - } - - @Test - public void constructor_does_not_fail_with_NPE_if_previousStatus_is_null() { - new QGChangeEvent(project, branch, analysis, configuration, null, supplier); - } - - @Test - public void constructor_fails_with_NPE_if_supplier_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("qualityGateSupplier can't be null"); - - new QGChangeEvent(project, branch, analysis, configuration, previousStatus, null); - } - - @Test - public void verify_getters() { - QGChangeEvent underTest = new QGChangeEvent(project, branch, analysis, configuration, previousStatus, supplier); - - assertThat(underTest.getProject()).isSameAs(project); - assertThat(underTest.getBranch()).isSameAs(branch); - assertThat(underTest.getAnalysis()).isSameAs(analysis); - assertThat(underTest.getProjectConfiguration()).isSameAs(configuration); - assertThat(underTest.getPreviousStatus()).contains(previousStatus); - assertThat(underTest.getQualityGateSupplier()).isSameAs(supplier); - } - - @Test - public void getPreviousStatus_returns_empty_when_previousStatus_is_null() { - QGChangeEvent underTest = new QGChangeEvent(project, branch, analysis, configuration, previousStatus, supplier); - - assertThat(underTest.getPreviousStatus()).contains(previousStatus); - } - - @Test - public void overrides_toString() { - QGChangeEvent underTest = new QGChangeEvent(project, branch, analysis, configuration, previousStatus, supplier); - - assertThat(underTest.toString()) - .isEqualTo("QGChangeEvent{project=bar:foo, branch=SHORT:bar:doh:zop, analysis=pto:8999999765" + - ", projectConfiguration=" + configuration.toString() + - ", previousStatus=" + previousStatus + - ", qualityGateSupplier=" + supplier + "}"); - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java deleted file mode 100644 index 6bf85ee8932..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import com.google.common.io.Resources; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.QualityProfileTesting; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleParamDto; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.junit.rules.ExpectedException.none; - -public class QProfileBackuperImplTest { - - private static final String EMPTY_BACKUP = "<?xml version='1.0' encoding='UTF-8'?>" + - "<profile><name>foo</name>" + - "<language>js</language>" + - "<rules/>" + - "</profile>"; - - private System2 system2 = new AlwaysIncreasingSystem2(); - - @Rule - public ExpectedException expectedException = none(); - @Rule - public DbTester db = DbTester.create(system2); - - private DummyReset reset = new DummyReset(); - private QProfileFactory profileFactory = new DummyProfileFactory(); - private QProfileBackuper underTest = new QProfileBackuperImpl(db.getDbClient(), reset, profileFactory); - - @Test - public void backup_generates_xml_file() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - ActiveRuleDto activeRule = activate(profile, rule); - - StringWriter writer = new StringWriter(); - underTest.backup(db.getSession(), profile, writer); - - assertThat(writer.toString()).isEqualTo("<?xml version='1.0' encoding='UTF-8'?>" + - "<profile><name>" + profile.getName() + "</name>" + - "<language>" + profile.getLanguage() + "</language>" + - "<rules>" + - "<rule>" + - "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + - "<key>" + rule.getRuleKey() + "</key>" + - "<priority>" + activeRule.getSeverityString() + "</priority>" + - "<parameters/>" + - "</rule>" + - "</rules>" + - "</profile>"); - } - - @Test - public void backup_rules_having_parameters() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto profile = createProfile(rule); - ActiveRuleDto activeRule = activate(profile, rule, param); - - StringWriter writer = new StringWriter(); - underTest.backup(db.getSession(), profile, writer); - - assertThat(writer.toString()).contains( - "<rule>" + - "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + - "<key>" + rule.getRuleKey() + "</key>" + - "<priority>" + activeRule.getSeverityString() + "</priority>" + - "<parameters><parameter>" + - "<key>" + param.getName() + "</key>" + - "<value>20</value>" + - "</parameter></parameters>" + - "</rule>"); - } - - @Test - public void backup_empty_profile() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - - StringWriter writer = new StringWriter(); - underTest.backup(db.getSession(), profile, writer); - - assertThat(writer.toString()).isEqualTo("<?xml version='1.0' encoding='UTF-8'?>" + - "<profile><name>" + profile.getName() + "</name>" + - "<language>" + profile.getLanguage() + "</language>" + - "<rules/>" + - "</profile>"); - } - - @Test - public void restore_backup_on_the_profile_specified_in_backup() { - OrganizationDto organization = db.organizations().insert(); - Reader backup = new StringReader(EMPTY_BACKUP); - - QProfileRestoreSummary summary = underTest.restore(db.getSession(), backup, organization, null); - - assertThat(summary.getProfile().getName()).isEqualTo("foo"); - assertThat(summary.getProfile().getLanguage()).isEqualTo("js"); - - assertThat(reset.calledProfile.getKee()).isEqualTo(summary.getProfile().getKee()); - assertThat(reset.calledActivations).isEmpty(); - } - - @Test - public void restore_backup_on_profile_having_different_name() { - OrganizationDto organization = db.organizations().insert(); - Reader backup = new StringReader(EMPTY_BACKUP); - - QProfileRestoreSummary summary = underTest.restore(db.getSession(), backup, organization, "bar"); - - assertThat(summary.getProfile().getName()).isEqualTo("bar"); - assertThat(summary.getProfile().getLanguage()).isEqualTo("js"); - - assertThat(reset.calledProfile.getKee()).isEqualTo(summary.getProfile().getKee()); - assertThat(reset.calledActivations).isEmpty(); - } - - @Test - public void restore_resets_the_activated_rules() { - Integer ruleId = db.rules().insert(RuleKey.of("sonarjs", "s001")).getId(); - OrganizationDto organization = db.organizations().insert(); - Reader backup = new StringReader("<?xml version='1.0' encoding='UTF-8'?>" + - "<profile><name>foo</name>" + - "<language>js</language>" + - "<rules>" + - "<rule>" + - "<repositoryKey>sonarjs</repositoryKey>" + - "<key>s001</key>" + - "<priority>BLOCKER</priority>" + - "<parameters>" + - "<parameter><key>bar</key><value>baz</value></parameter>" + - "</parameters>" + - "</rule>" + - "</rules>" + - "</profile>"); - - underTest.restore(db.getSession(), backup, organization, null); - - assertThat(reset.calledActivations).hasSize(1); - RuleActivation activation = reset.calledActivations.get(0); - assertThat(activation.getSeverity()).isEqualTo("BLOCKER"); - assertThat(activation.getRuleId()).isEqualTo(ruleId); - assertThat(activation.getParameter("bar")).isEqualTo("baz"); - } - - @Test - public void fail_to_restore_if_bad_xml_format() { - OrganizationDto organization = db.organizations().insert(); - try { - underTest.restore(db.getSession(), new StringReader("<rules><rule></rules>"), organization, null); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Backup XML is not valid. Root element must be <profile>."); - assertThat(reset.calledProfile).isNull(); - } - } - - @Test - public void fail_to_restore_if_not_xml_backup() { - OrganizationDto organization = db.organizations().insert(); - try { - underTest.restore(db.getSession(), new StringReader("foo"), organization, null); - fail(); - } catch (IllegalArgumentException e) { - assertThat(reset.calledProfile).isNull(); - } - } - - @Test - public void fail_to_restore_if_xml_is_not_well_formed() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Fail to restore Quality profile backup, XML document is not well formed"); - OrganizationDto organization = db.organizations().insert(); - String notWellFormedXml = "<?xml version='1.0' encoding='UTF-8'?><profile><name>\"profil\"</name><language>\"language\"</language><rules/></profile"; - - underTest.restore(db.getSession(), new StringReader(notWellFormedXml), organization, null); - } - - @Test - public void fail_to_restore_if_duplicate_rule() throws Exception { - OrganizationDto organization = db.organizations().insert(); - try { - String xml = Resources.toString(getClass().getResource("QProfileBackuperMediumTest/duplicates-xml-backup.xml"), UTF_8); - underTest.restore(db.getSession(), new StringReader(xml), organization, null); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("The quality profile cannot be restored as it contains duplicates for the following rules: xoo:x1, xoo:x2"); - assertThat(reset.calledProfile).isNull(); - } - } - - @Test - public void fail_to_restore_external_rule() { - db.rules().insert(RuleKey.of("sonarjs", "s001"), r -> r.setIsExternal(true)).getId(); - OrganizationDto organization = db.organizations().insert(); - Reader backup = new StringReader("<?xml version='1.0' encoding='UTF-8'?>" + - "<profile><name>foo</name>" + - "<language>js</language>" + - "<rules>" + - "<rule>" + - "<repositoryKey>sonarjs</repositoryKey>" + - "<key>s001</key>" + - "<priority>BLOCKER</priority>" + - "<parameters>" + - "<parameter><key>bar</key><value>baz</value></parameter>" + - "</parameters>" + - "</rule>" + - "</rules>" + - "</profile>"); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The quality profile cannot be restored as it contains rules from external rule engines: sonarjs:s001"); - underTest.restore(db.getSession(), backup, organization, null); - } - - private RuleDefinitionDto createRule() { - return db.rules().insert(); - } - - private QProfileDto createProfile(RuleDefinitionDto rule) { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage())); - } - - private ActiveRuleDto activate(QProfileDto profile, RuleDefinitionDto rule) { - return db.qualityProfiles().activateRule(profile, rule); - } - - private ActiveRuleDto activate(QProfileDto profile, RuleDefinitionDto rule, RuleParamDto param) { - ActiveRuleDto activeRule = db.qualityProfiles().activateRule(profile, rule); - ActiveRuleParamDto dto = ActiveRuleParamDto.createFor(param) - .setValue("20") - .setActiveRuleId(activeRule.getId()); - db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRule, dto); - return activeRule; - } - - private static class DummyReset implements QProfileReset { - private QProfileDto calledProfile; - private List<RuleActivation> calledActivations; - - @Override - public BulkChangeResult reset(DbSession dbSession, QProfileDto profile, Collection<RuleActivation> activations) { - this.calledProfile = profile; - this.calledActivations = new ArrayList<>(activations); - return new BulkChangeResult(); - } - } - private static class DummyProfileFactory implements QProfileFactory { - @Override - public QProfileDto getOrCreateCustom(DbSession dbSession, OrganizationDto organization, QProfileName key) { - return QualityProfileTesting.newQualityProfileDto() - .setOrganizationUuid(organization.getUuid()) - .setLanguage(key.getLanguage()) - .setName(key.getName()); - } - - @Override - public QProfileDto checkAndCreateCustom(DbSession dbSession, OrganizationDto organization, QProfileName name) { - throw new UnsupportedOperationException(); - } - - @Override - public void delete(DbSession dbSession, Collection<QProfileDto> profiles) { - throw new UnsupportedOperationException(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java deleted file mode 100644 index 81ce2e33ef6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.MapDifference.ValueDifference; -import org.assertj.core.data.MapEntry; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rule.Severity; -import org.sonar.api.server.rule.RuleParamType; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.rule.RuleTesting; -import org.sonar.server.es.EsTester; -import org.sonar.server.qualityprofile.QProfileComparison.ActiveRuleDiff; -import org.sonar.server.qualityprofile.QProfileComparison.QProfileComparisonResult; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.TypeValidations; - -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; - -public class QProfileComparisonTest { - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone().anonymous(); - @Rule - public DbTester dbTester = DbTester.create(); - @Rule - public EsTester es = EsTester.create(); - - private DbClient db; - private DbSession dbSession; - private QProfileRules qProfileRules; - private QProfileComparison comparison; - - private RuleDefinitionDto xooRule1; - private RuleDefinitionDto xooRule2; - private QProfileDto left; - private QProfileDto right; - - @Before - public void before() { - db = dbTester.getDbClient(); - dbSession = db.openSession(false); - RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE); - ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db, es.client()); - RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, db, new TypeValidations(singletonList(new IntegerTypeValidation())), userSession); - qProfileRules = new QProfileRulesImpl(db, ruleActivator, ruleIndex, activeRuleIndexer); - comparison = new QProfileComparison(db); - - xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR").getDefinition(); - xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR").getDefinition(); - db.ruleDao().insert(dbSession, xooRule1); - db.ruleDao().insert(dbSession, xooRule2); - db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1) - .setName("max").setType(RuleParamType.INTEGER.type())); - db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1) - .setName("min").setType(RuleParamType.INTEGER.type())); - - left = QProfileTesting.newXooP1("org-123"); - right = QProfileTesting.newXooP2("org-123"); - db.qualityProfileDao().insert(dbSession, left, right); - - dbSession.commit(); - } - - @After - public void after() { - dbSession.close(); - } - - @Test - public void compare_empty_profiles() { - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isEmpty(); - assertThat(result.collectRuleKeys()).isEmpty(); - } - - @Test - public void compare_same() { - RuleActivation commonActivation = RuleActivation.create(xooRule1.getId(), Severity.CRITICAL, - ImmutableMap.of("min", "7", "max", "42")); - qProfileRules.activateAndCommit(dbSession, left, singleton(commonActivation)); - qProfileRules.activateAndCommit(dbSession, right, singleton(commonActivation)); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isEmpty(); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - } - - @Test - public void compare_only_left() { - RuleActivation activation = RuleActivation.create(xooRule1.getId()); - qProfileRules.activateAndCommit(dbSession, left, singleton(activation)); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isEmpty(); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - } - - @Test - public void compare_only_right() { - qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule1.getId()))); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.modified()).isEmpty(); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - } - - @Test - public void compare_disjoint() { - qProfileRules.activateAndCommit(dbSession, left, singleton(RuleActivation.create(xooRule1.getId()))); - qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule2.getId()))); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule2.getKey()); - assertThat(result.modified()).isEmpty(); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey(), xooRule2.getKey()); - } - - @Test - public void compare_modified_severity() { - qProfileRules.activateAndCommit(dbSession, left, singleton(RuleActivation.create(xooRule1.getId(), Severity.CRITICAL, null))); - qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule1.getId(), Severity.BLOCKER, null))); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - - ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey()); - assertThat(activeRuleDiff.leftSeverity()).isEqualTo(Severity.CRITICAL); - assertThat(activeRuleDiff.rightSeverity()).isEqualTo(Severity.BLOCKER); - assertThat(activeRuleDiff.paramDifference().areEqual()).isTrue(); - } - - @Test - public void compare_modified_param() { - qProfileRules.activateAndCommit(dbSession, left, singleton(RuleActivation.create(xooRule1.getId(), null, ImmutableMap.of("max", "20")))); - qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule1.getId(), null, ImmutableMap.of("max", "30")))); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - - ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey()); - assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString()); - assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse(); - assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isNotEmpty(); - ValueDifference<String> paramDiff = activeRuleDiff.paramDifference().entriesDiffering().get("max"); - assertThat(paramDiff.leftValue()).isEqualTo("20"); - assertThat(paramDiff.rightValue()).isEqualTo("30"); - } - - @Test - public void compare_different_params() { - qProfileRules.activateAndCommit(dbSession, left, singleton(RuleActivation.create(xooRule1.getId(), null, ImmutableMap.of("max", "20")))); - qProfileRules.activateAndCommit(dbSession, right, singleton(RuleActivation.create(xooRule1.getId(), null, ImmutableMap.of("min", "5")))); - - QProfileComparisonResult result = comparison.compare(dbSession, left, right); - assertThat(result.left().getKee()).isEqualTo(left.getKee()); - assertThat(result.right().getKee()).isEqualTo(right.getKee()); - assertThat(result.same()).isEmpty(); - assertThat(result.inLeft()).isEmpty(); - assertThat(result.inRight()).isEmpty(); - assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey()); - assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey()); - - ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey()); - assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString()); - assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse(); - assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isEmpty(); - assertThat(activeRuleDiff.paramDifference().entriesOnlyOnLeft()).containsExactly(MapEntry.entry("max", "20")); - assertThat(activeRuleDiff.paramDifference().entriesOnlyOnRight()).containsExactly(MapEntry.entry("min", "5")); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileCopierTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileCopierTest.java deleted file mode 100644 index a084f72f5b6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileCopierTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.Collection; -import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.impl.utils.JUnitTempFolder; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.QualityProfileTesting; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public class QProfileCopierTest { - - private static final String BACKUP = "<backup/>"; - private System2 system2 = new AlwaysIncreasingSystem2(); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public JUnitTempFolder temp = new JUnitTempFolder(); - - private DummyProfileFactory profileFactory = new DummyProfileFactory(); - private DummyBackuper backuper = new DummyBackuper(); - private QProfileCopier underTest = new QProfileCopier(db.getDbClient(), profileFactory, backuper, temp); - - @Test - public void create_target_profile_and_copy_rules() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto source = db.qualityProfiles().insert(organization); - - QProfileDto target = underTest.copyToName(db.getSession(), source, "foo"); - - assertThat(target.getLanguage()).isEqualTo(source.getLanguage()); - assertThat(target.getName()).isEqualTo("foo"); - assertThat(target.getParentKee()).isNull(); - assertThat(backuper.backuped).isSameAs(source); - assertThat(backuper.restored.getName()).isEqualTo("foo"); - assertThat(backuper.restoredBackup).isEqualTo(BACKUP); - } - - @Test - public void create_target_profile_with_same_parent_than_source_profile() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto parent = db.qualityProfiles().insert(organization); - QProfileDto source = db.qualityProfiles().insert(organization, p -> p.setParentKee(parent.getKee())); - - QProfileDto target = underTest.copyToName(db.getSession(), source, "foo"); - - assertThat(target.getLanguage()).isEqualTo(source.getLanguage()); - assertThat(target.getName()).isEqualTo("foo"); - assertThat(target.getParentKee()).isEqualTo(parent.getKee()); - } - - @Test - public void fail_to_copy_on_self() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto source = db.qualityProfiles().insert(organization); - - try { - underTest.copyToName(db.getSession(), source, source.getName()); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Source and target profiles are equal: " + source.getName()); - assertThat(backuper.backuped).isNull(); - assertThat(backuper.restored).isNull(); - } - } - - @Test - public void copy_to_existing_profile() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto profile1 = db.qualityProfiles().insert(organization); - QProfileDto profile2 = db.qualityProfiles().insert(organization, p -> p.setLanguage(profile1.getLanguage())); - - QProfileDto target = underTest.copyToName(db.getSession(), profile1, profile2.getName()); - - assertThat(profileFactory.createdProfile).isNull(); - assertThat(target.getLanguage()).isEqualTo(profile2.getLanguage()); - assertThat(target.getName()).isEqualTo(profile2.getName()); - assertThat(backuper.backuped).isSameAs(profile1); - assertThat(backuper.restored.getName()).isEqualTo(profile2.getName()); - assertThat(backuper.restoredBackup).isEqualTo(BACKUP); - } - - private static class DummyProfileFactory implements QProfileFactory { - private QProfileDto createdProfile; - - @Override - public QProfileDto getOrCreateCustom(DbSession dbSession, OrganizationDto organization, QProfileName key) { - throw new UnsupportedOperationException(); - } - - @Override - public QProfileDto checkAndCreateCustom(DbSession dbSession, OrganizationDto organization, QProfileName key) { - createdProfile = QualityProfileTesting.newQualityProfileDto() - .setOrganizationUuid(organization.getUuid()) - .setLanguage(key.getLanguage()) - .setName(key.getName()); - return createdProfile; - } - - @Override - public void delete(DbSession dbSession, Collection<QProfileDto> profiles) { - throw new UnsupportedOperationException(); - } - } - - private static class DummyBackuper implements QProfileBackuper { - private QProfileDto backuped; - private String restoredBackup; - private QProfileDto restored; - - @Override - public void backup(DbSession dbSession, QProfileDto profile, Writer backupWriter) { - this.backuped = profile; - try { - backupWriter.write(BACKUP); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - @Override - public QProfileRestoreSummary restore(DbSession dbSession, Reader backup, OrganizationDto organization, @Nullable String overriddenProfileName) { - throw new UnsupportedOperationException(); - } - - @Override - public QProfileRestoreSummary restore(DbSession dbSession, Reader backup, QProfileDto profile) { - try { - this.restoredBackup = IOUtils.toString(backup); - this.restored = profile; - return null; - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java deleted file mode 100644 index dd57f191db2..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Collection; -import org.junit.Before; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.organization.DefaultOrganizationProvider; -import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.rule.DefaultRuleFinder; -import org.sonar.server.tester.UserSessionRule; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.apache.commons.io.IOUtils.toInputStream; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class QProfileExportersTest { - - @org.junit.Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private System2 system2 = new AlwaysIncreasingSystem2(); - - @org.junit.Rule - public ExpectedException expectedException = ExpectedException.none(); - @org.junit.Rule - public DbTester db = DbTester.create(system2); - - public DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private RuleFinder ruleFinder = new DefaultRuleFinder(db.getDbClient(), defaultOrganizationProvider); - private ProfileExporter[] exporters = new ProfileExporter[] { - new StandardExporter(), new XooExporter()}; - private ProfileImporter[] importers = new ProfileImporter[] { - new XooProfileImporter(), new XooProfileImporterWithMessages(), new XooProfileImporterWithError()}; - private RuleDefinitionDto rule; - private QProfileRules qProfileRules = mock(QProfileRules.class); - private QProfileExporters underTest = new QProfileExporters(db.getDbClient(), ruleFinder, qProfileRules, exporters, importers); - - @Before - public void setUp() { - rule = db.rules().insert(r -> r.setLanguage("xoo").setRepositoryKey("SonarXoo").setRuleKey("R1")); - } - - @Test - public void exportersForLanguage() { - assertThat(underTest.exportersForLanguage("xoo")).hasSize(2); - assertThat(underTest.exportersForLanguage("java")).hasSize(1); - assertThat(underTest.exportersForLanguage("java").get(0)).isInstanceOf(StandardExporter.class); - } - - @Test - public void mimeType() { - assertThat(underTest.mimeType("xootool")).isEqualTo("plain/custom"); - - // default mime type - assertThat(underTest.mimeType("standard")).isEqualTo("text/plain"); - } - - @Test - public void import_xml() { - QProfileDto profile = createProfile(); - - - underTest.importXml(profile, "XooProfileImporter", toInputStream("<xml/>", UTF_8), db.getSession()); - - ArgumentCaptor<QProfileDto> profileCapture = ArgumentCaptor.forClass(QProfileDto.class); - Class<Collection<RuleActivation>> collectionClass = (Class<Collection<RuleActivation>>) (Class) Collection.class; - ArgumentCaptor<Collection<RuleActivation>> activationCapture = ArgumentCaptor.forClass(collectionClass); - verify(qProfileRules).activateAndCommit(any(DbSession.class), profileCapture.capture(), activationCapture.capture()); - - assertThat(profileCapture.getValue().getKee()).isEqualTo(profile.getKee()); - Collection<RuleActivation> activations = activationCapture.getValue(); - assertThat(activations).hasSize(1); - RuleActivation activation = activations.iterator().next(); - assertThat(activation.getRuleId()).isEqualTo(rule.getId()); - assertThat(activation.getSeverity()).isEqualTo("CRITICAL"); - } - - @Test - public void import_xml_return_messages() { - QProfileDto profile = createProfile(); - - QProfileResult result = underTest.importXml(profile, "XooProfileImporterWithMessages", toInputStream("<xml/>", UTF_8), db.getSession()); - - assertThat(result.infos()).containsOnly("an info"); - assertThat(result.warnings()).containsOnly("a warning"); - } - - @Test - public void fail_to_import_xml_when_error_in_importer() { - try { - underTest.importXml(QProfileTesting.newXooP1("org-123"), "XooProfileImporterWithError", toInputStream("<xml/>", UTF_8), db.getSession()); - fail(); - } catch (BadRequestException e) { - assertThat(e).hasMessage("error!"); - } - } - - @Test - public void fail_to_import_xml_on_unknown_importer() { - try { - underTest.importXml(QProfileTesting.newXooP1("org-123"), "Unknown", toInputStream("<xml/>", UTF_8), db.getSession()); - fail(); - } catch (BadRequestException e) { - assertThat(e).hasMessage("No such importer : Unknown"); - } - } - - @Test - public void export_empty_profile() { - QProfileDto profile = createProfile(); - - StringWriter writer = new StringWriter(); - underTest.export(db.getSession(), profile, "standard", writer); - assertThat(writer.toString()).isEqualTo("standard -> " + profile.getName() + " -> 0"); - - writer = new StringWriter(); - underTest.export(db.getSession(), profile, "xootool", writer); - assertThat(writer.toString()).isEqualTo("xoo -> " + profile.getName() + " -> 0"); - } - - @Test - public void export_profile() { - QProfileDto profile = createProfile(); - db.qualityProfiles().activateRule(profile, rule); - - StringWriter writer = new StringWriter(); - underTest.export(db.getSession(), profile, "standard", writer); - assertThat(writer.toString()).isEqualTo("standard -> " + profile.getName() + " -> 1"); - - writer = new StringWriter(); - underTest.export(db.getSession(), profile, "xootool", writer); - assertThat(writer.toString()).isEqualTo("xoo -> " + profile.getName() + " -> 1"); - } - - @Test - public void export_throws_NotFoundException_if_exporter_does_not_exist() { - QProfileDto profile = createProfile(); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Unknown quality profile exporter: does_not_exist"); - - underTest.export(db.getSession(), profile, "does_not_exist", new StringWriter()); - - } - - private QProfileDto createProfile() { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage())); - } - - public static class XooExporter extends ProfileExporter { - public XooExporter() { - super("xootool", "Xoo Tool"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {"xoo"}; - } - - @Override - public String getMimeType() { - return "plain/custom"; - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write("xoo -> " + profile.getName() + " -> " + profile.getActiveRules().size()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - - public static class StandardExporter extends ProfileExporter { - public StandardExporter() { - super("standard", "Standard"); - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write("standard -> " + profile.getName() + " -> " + profile.getActiveRules().size()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - - public class XooProfileImporter extends ProfileImporter { - public XooProfileImporter() { - super("XooProfileImporter", "Xoo Profile Importer"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {"xoo"}; - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - RulesProfile rulesProfile = RulesProfile.create(); - rulesProfile.activateRule(Rule.create(rule.getRepositoryKey(), rule.getRuleKey()), RulePriority.CRITICAL); - return rulesProfile; - } - } - - public static class XooProfileImporterWithMessages extends ProfileImporter { - public XooProfileImporterWithMessages() { - super("XooProfileImporterWithMessages", "Xoo Profile Importer With Message"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {}; - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - messages.addWarningText("a warning"); - messages.addInfoText("an info"); - return RulesProfile.create(); - } - } - - public static class XooProfileImporterWithError extends ProfileImporter { - public XooProfileImporterWithError() { - super("XooProfileImporterWithError", "Xoo Profile Importer With Error"); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - messages.addErrorText("error!"); - return RulesProfile.create(); - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryImplTest.java deleted file mode 100644 index 176bddc24c6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryImplTest.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.util.Collections; -import java.util.Set; -import org.assertj.core.api.AbstractObjectAssert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.rule.Severity; -import org.sonar.api.utils.System2; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.core.util.Uuids; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.OrgQProfileDto; -import org.sonar.db.qualityprofile.QProfileChangeDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.RulesProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyCollection; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -public class QProfileFactoryImplTest { - - private System2 system2 = new AlwaysIncreasingSystem2(); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(system2); - - private DbSession dbSession = db.getSession(); - private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class); - private QProfileFactory underTest = new QProfileFactoryImpl(db.getDbClient(), new SequenceUuidFactory(), system2, activeRuleIndexer); - private RuleDefinitionDto rule; - private RuleParamDto ruleParam; - - @Before - public void setUp() { - rule = db.rules().insert(); - ruleParam = db.rules().insertRuleParam(rule); - } - - @Test - public void checkAndCreateCustom() { - OrganizationDto organization = db.organizations().insert(); - - QProfileDto profile = underTest.checkAndCreateCustom(dbSession, organization, new QProfileName("xoo", "P1")); - - assertThat(profile.getOrganizationUuid()).isEqualTo(organization.getUuid()); - assertThat(profile.getKee()).isNotEmpty(); - assertThat(profile.getName()).isEqualTo("P1"); - assertThat(profile.getLanguage()).isEqualTo("xoo"); - assertThat(profile.getId()).isNotNull(); - assertThat(profile.isBuiltIn()).isFalse(); - - QProfileDto reloaded = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(dbSession, organization, profile.getName(), profile.getLanguage()); - assertEqual(profile, reloaded); - assertThat(db.getDbClient().qualityProfileDao().selectOrderedByOrganizationUuid(dbSession, organization)).extracting(QProfileDto::getKee).containsExactly(profile.getKee()); - } - - @Test - public void checkAndCreateCustom_throws_BadRequestException_if_name_null() { - QProfileName name = new QProfileName("xoo", null); - OrganizationDto organization = db.organizations().insert(); - - expectBadRequestException("quality_profiles.profile_name_cant_be_blank"); - - underTest.checkAndCreateCustom(dbSession, organization, name); - } - - @Test - public void checkAndCreateCustom_throws_BadRequestException_if_name_empty() { - QProfileName name = new QProfileName("xoo", ""); - OrganizationDto organization = db.organizations().insert(); - - expectBadRequestException("quality_profiles.profile_name_cant_be_blank"); - - underTest.checkAndCreateCustom(dbSession, organization, name); - } - - @Test - public void checkAndCreateCustom_throws_BadRequestException_if_already_exists() { - QProfileName name = new QProfileName("xoo", "P1"); - OrganizationDto organization = db.organizations().insert(); - - underTest.checkAndCreateCustom(dbSession, organization, name); - dbSession.commit(); - - expectBadRequestException("Quality profile already exists: xoo/P1"); - - underTest.checkAndCreateCustom(dbSession, organization, name); - } - - @Test - public void delete_custom_profiles() { - OrganizationDto org = db.organizations().insert(); - QProfileDto profile1 = createCustomProfile(org); - QProfileDto profile2 = createCustomProfile(org); - QProfileDto profile3 = createCustomProfile(org); - - underTest.delete(dbSession, asList(profile1, profile2)); - - verifyCallActiveRuleIndexerDelete(profile1.getKee(), profile2.getKee()); - assertThatCustomProfileDoesNotExist(profile1); - assertThatCustomProfileDoesNotExist(profile2); - assertThatCustomProfileExists(profile3); - } - - @Test - public void delete_removes_custom_profile_marked_as_default() { - OrganizationDto org = db.organizations().insert(); - QProfileDto profile = createCustomProfile(org); - db.qualityProfiles().setAsDefault(profile); - - underTest.delete(dbSession, asList(profile)); - - assertThatCustomProfileDoesNotExist(profile); - } - - @Test - public void delete_removes_custom_profile_from_project_associations() { - OrganizationDto org = db.organizations().insert(); - QProfileDto profile = createCustomProfile(org); - ComponentDto project = db.components().insertPrivateProject(org); - db.qualityProfiles().associateWithProject(project, profile); - - underTest.delete(dbSession, asList(profile)); - - assertThatCustomProfileDoesNotExist(profile); - } - - @Test - public void delete_builtin_profile() { - RulesProfileDto builtInProfile = createBuiltInProfile(); - OrganizationDto org = db.organizations().insert(); - QProfileDto profile = associateBuiltInProfileToOrganization(builtInProfile, org); - - underTest.delete(dbSession, asList(profile)); - - verifyNoCallsActiveRuleIndexerDelete(); - - // remove only from org_qprofiles - assertThat(db.getDbClient().qualityProfileDao().selectOrderedByOrganizationUuid(dbSession, org)).isEmpty(); - - assertThatRulesProfileExists(builtInProfile); - } - - @Test - public void delete_builtin_profile_associated_to_project() { - RulesProfileDto builtInProfile = createBuiltInProfile(); - OrganizationDto org = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(org); - QProfileDto profile = associateBuiltInProfileToOrganization(builtInProfile, org); - db.qualityProfiles().associateWithProject(project, profile); - assertThat(db.getDbClient().qualityProfileDao().selectAssociatedToProjectAndLanguage(dbSession, project, profile.getLanguage())).isNotNull(); - - underTest.delete(dbSession, asList(profile)); - - verifyNoCallsActiveRuleIndexerDelete(); - - // remove only from org_qprofiles and project_qprofiles - assertThat(db.getDbClient().qualityProfileDao().selectOrderedByOrganizationUuid(dbSession, org)).isEmpty(); - assertThat(db.getDbClient().qualityProfileDao().selectAssociatedToProjectAndLanguage(dbSession, project, profile.getLanguage())).isNull(); - assertThatRulesProfileExists(builtInProfile); - } - - @Test - public void delete_builtin_profile_marked_as_default_on_organization() { - RulesProfileDto builtInProfile = createBuiltInProfile(); - OrganizationDto org = db.organizations().insert(); - QProfileDto profile = associateBuiltInProfileToOrganization(builtInProfile, org); - db.qualityProfiles().setAsDefault(profile); - - underTest.delete(dbSession, asList(profile)); - - verifyNoCallsActiveRuleIndexerDelete(); - - // remove only from org_qprofiles and default_qprofiles - assertThat(db.getDbClient().qualityProfileDao().selectOrderedByOrganizationUuid(dbSession, org)).isEmpty(); - assertThat(db.getDbClient().qualityProfileDao().selectDefaultProfile(dbSession, org, profile.getLanguage())).isNull(); - assertThatRulesProfileExists(builtInProfile); - } - - @Test - public void delete_accepts_empty_list_of_keys() { - OrganizationDto org = db.organizations().insert(); - QProfileDto profile = createCustomProfile(org); - - underTest.delete(dbSession, Collections.emptyList()); - - verifyZeroInteractions(activeRuleIndexer); - assertQualityProfileFromDb(profile).isNotNull(); - } - - @Test - public void delete_removes_qprofile_edit_permissions() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto profile = db.qualityProfiles().insert(organization); - UserDto user = db.users().insertUser(); - db.qualityProfiles().addUserPermission(profile, user); - GroupDto group = db.users().insertGroup(organization); - db.qualityProfiles().addGroupPermission(profile, group); - - underTest.delete(dbSession, asList(profile)); - - assertThat(db.countRowsOfTable(dbSession, "qprofile_edit_users")).isZero(); - assertThat(db.countRowsOfTable(dbSession, "qprofile_edit_groups")).isZero(); - } - - private QProfileDto createCustomProfile(OrganizationDto org) { - QProfileDto profile = db.qualityProfiles().insert(org, p -> p.setLanguage("xoo").setIsBuiltIn(false)); - ActiveRuleDto activeRuleDto = db.qualityProfiles().activateRule(profile, rule); - - ActiveRuleParamDto activeRuleParam = new ActiveRuleParamDto() - .setRulesParameterId(ruleParam.getId()) - .setKey("foo") - .setValue("bar"); - db.getDbClient().activeRuleDao().insertParam(dbSession, activeRuleDto, activeRuleParam); - - db.getDbClient().qProfileChangeDao().insert(dbSession, new QProfileChangeDto() - .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) - .setRulesProfileUuid(profile.getRulesProfileUuid())); - db.commit(); - return profile; - } - - private RulesProfileDto createBuiltInProfile() { - RulesProfileDto rulesProfileDto = new RulesProfileDto() - .setIsBuiltIn(true) - .setKee(Uuids.createFast()) - .setLanguage("xoo") - .setName("Sonar way"); - db.getDbClient().qualityProfileDao().insert(dbSession, rulesProfileDto); - ActiveRuleDto activeRuleDto = new ActiveRuleDto() - .setProfileId(rulesProfileDto.getId()) - .setRuleId(rule.getId()) - .setSeverity(Severity.BLOCKER); - db.getDbClient().activeRuleDao().insert(dbSession, activeRuleDto); - - ActiveRuleParamDto activeRuleParam = new ActiveRuleParamDto() - .setRulesParameterId(ruleParam.getId()) - .setKey("foo") - .setValue("bar"); - db.getDbClient().activeRuleDao().insertParam(dbSession, activeRuleDto, activeRuleParam); - - db.getDbClient().qProfileChangeDao().insert(dbSession, new QProfileChangeDto() - .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) - .setRulesProfileUuid(rulesProfileDto.getKee())); - - db.commit(); - return rulesProfileDto; - } - - private QProfileDto associateBuiltInProfileToOrganization(RulesProfileDto rulesProfile, OrganizationDto organization) { - OrgQProfileDto orgQProfileDto = new OrgQProfileDto() - .setUuid(Uuids.createFast()) - .setRulesProfileUuid(rulesProfile.getKee()) - .setOrganizationUuid(organization.getUuid()); - db.getDbClient().qualityProfileDao().insert(dbSession, orgQProfileDto); - db.commit(); - return QProfileDto.from(orgQProfileDto, rulesProfile); - } - - private AbstractObjectAssert<?, QProfileDto> assertQualityProfileFromDb(QProfileDto profile) { - return assertThat(db.getDbClient().qualityProfileDao().selectByUuid(dbSession, profile.getKee())); - } - - private void verifyNoCallsActiveRuleIndexerDelete() { - verify(activeRuleIndexer, never()).commitDeletionOfProfiles(any(DbSession.class), anyCollection()); - } - - private void verifyCallActiveRuleIndexerDelete(String... expectedRuleProfileUuids) { - Class<Set<QProfileDto>> setClass = (Class<Set<QProfileDto>>) (Class) Set.class; - ArgumentCaptor<Set<QProfileDto>> setCaptor = ArgumentCaptor.forClass(setClass); - verify(activeRuleIndexer).commitDeletionOfProfiles(any(DbSession.class), setCaptor.capture()); - - assertThat(setCaptor.getValue()) - .extracting(QProfileDto::getKee) - .containsExactlyInAnyOrder(expectedRuleProfileUuids); - } - - private void assertThatRulesProfileExists(RulesProfileDto rulesProfile) { - assertThat(db.getDbClient().qualityProfileDao().selectBuiltInRuleProfiles(dbSession)) - .extracting(RulesProfileDto::getKee) - .containsExactly(rulesProfile.getKee()); - assertThat(db.countRowsOfTable(dbSession, "active_rules")).isGreaterThan(0); - assertThat(db.countRowsOfTable(dbSession, "active_rule_parameters")).isGreaterThan(0); - assertThat(db.countRowsOfTable(dbSession, "qprofile_changes")).isGreaterThan(0); - } - - private void assertThatCustomProfileDoesNotExist(QProfileDto profile) { - assertThat(db.countSql(dbSession, "select count(*) from org_qprofiles where uuid = '" + profile.getKee() + "'")).isEqualTo(0); - assertThat(db.countSql(dbSession, "select count(*) from project_qprofiles where profile_key = '" + profile.getKee() + "'")).isEqualTo(0); - assertThat(db.countSql(dbSession, "select count(*) from default_qprofiles where qprofile_uuid = '" + profile.getKee() + "'")).isEqualTo(0); - assertThat(db.countSql(dbSession, "select count(*) from rules_profiles where kee = '" + profile.getRulesProfileUuid() + "'")).isEqualTo(0); - assertThat(db.countSql(dbSession, "select count(*) from active_rules where profile_id = " + profile.getId())).isEqualTo(0); - assertThat(db.countSql(dbSession, "select count(*) from qprofile_changes where rules_profile_uuid = '" + profile.getRulesProfileUuid() + "'")).isEqualTo(0); - // TODO active_rule_parameters - } - - private void assertThatCustomProfileExists(QProfileDto profile) { - assertThat(db.countSql(dbSession, "select count(*) from org_qprofiles where uuid = '" + profile.getKee() + "'")).isGreaterThan(0); - //assertThat(db.countSql(dbSession, "select count(*) from project_qprofiles where profile_key = '" + profile.getKee() + "'")).isGreaterThan(0); - //assertThat(db.countSql(dbSession, "select count(*) from default_qprofiles where qprofile_uuid = '" + profile.getKee() + "'")).isGreaterThan(0); - assertThat(db.countSql(dbSession, "select count(*) from rules_profiles where kee = '" + profile.getRulesProfileUuid() + "'")).isEqualTo(1); - assertThat(db.countSql(dbSession, "select count(*) from active_rules where profile_id = " + profile.getId())).isGreaterThan(0); - assertThat(db.countSql(dbSession, "select count(*) from qprofile_changes where rules_profile_uuid = '" + profile.getRulesProfileUuid() + "'")).isGreaterThan(0); - // TODO active_rule_parameters - } - - private static void assertEqual(QProfileDto p1, QProfileDto p2) { - assertThat(p2.getOrganizationUuid()).isEqualTo(p1.getOrganizationUuid()); - assertThat(p2.getName()).isEqualTo(p1.getName()); - assertThat(p2.getKee()).startsWith(p1.getKee()); - assertThat(p2.getLanguage()).isEqualTo(p1.getLanguage()); - assertThat(p2.getId()).isEqualTo(p1.getId()); - assertThat(p2.getParentKee()).isEqualTo(p1.getParentKee()); - } - - private void expectBadRequestException(String message) { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(message); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileResetImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileResetImplTest.java deleted file mode 100644 index b53733b9cd1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileResetImplTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.ActiveRuleKey; -import org.sonar.db.qualityprofile.OrgActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.QualityProfileTesting; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.StringTypeValidation; -import org.sonar.server.util.TypeValidations; - -import static java.util.Arrays.asList; -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.Mockito.mock; -import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.ACTIVATED; - -public class QProfileResetImplTest { - - private static final String LANGUAGE = "xoo"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public DbTester db = DbTester.create(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - private System2 system2 = new AlwaysIncreasingSystem2(); - private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class); - private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation())); - private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession); - private QProfileTree qProfileTree = new QProfileTreeImpl(db.getDbClient(), ruleActivator, system2, activeRuleIndexer); - private QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, null, activeRuleIndexer); - private QProfileResetImpl underTest = new QProfileResetImpl(db.getDbClient(), ruleActivator, activeRuleIndexer); - - @Test - public void reset() { - QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE)); - RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - qProfileRules.activateAndCommit(db.getSession(), profile, singleton(RuleActivation.create(existingRule.getId()))); - RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - - BulkChangeResult result = underTest.reset(db.getSession(), profile, singletonList(RuleActivation.create(newRule.getId()))); - - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)) - .extracting(OrgActiveRuleDto::getRuleKey) - .containsExactlyInAnyOrder(newRule.getKey()); - // Only activated rules are returned in the result - assertThat(result.getChanges()) - .extracting(ActiveRuleChange::getKey, ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(ActiveRuleKey.of(profile, newRule.getKey()), ACTIVATED)); - } - - @Test - public void inherited_rules_are_not_disabled() { - QProfileDto parentProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE)); - QProfileDto childProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE)); - qProfileTree.setParentAndCommit(db.getSession(), childProfile, parentProfile); - RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - qProfileRules.activateAndCommit(db.getSession(), parentProfile, singleton(RuleActivation.create(existingRule.getId()))); - qProfileRules.activateAndCommit(db.getSession(), childProfile, singleton(RuleActivation.create(existingRule.getId()))); - RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - - underTest.reset(db.getSession(), childProfile, singletonList(RuleActivation.create(newRule.getId()))); - - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), childProfile)) - .extracting(OrgActiveRuleDto::getRuleKey) - .containsExactlyInAnyOrder(newRule.getKey(), existingRule.getKey()); - } - - @Test - public void fail_when_profile_is_built_in() { - QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE).setIsBuiltIn(true)); - RuleDefinitionDto defaultRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage(String.format("Operation forbidden for built-in Quality Profile '%s'", profile.getKee())); - - underTest.reset(db.getSession(), profile, singletonList(RuleActivation.create(defaultRule.getId()))); - } - - @Test - public void fail_when_profile_is_not_persisted() { - QProfileDto profile = QualityProfileTesting.newQualityProfileDto().setLanguage(LANGUAGE); - RuleDefinitionDto defaultRule = db.rules().insert(r -> r.setLanguage(LANGUAGE)); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("Quality profile must be persisted"); - - underTest.reset(db.getSession(), profile, singletonList(RuleActivation.create(defaultRule.getId()))); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRuleImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRuleImplTest.java deleted file mode 100644 index c2c813f10d8..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRuleImplTest.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.stream.IntStream; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.PropertyType; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.OrgActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.StringTypeValidation; -import org.sonar.server.util.TypeValidations; - -import static com.google.common.collect.ImmutableMap.of; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.api.rule.Severity.CRITICAL; -import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.db.rule.RuleTesting.newCustomRule; -import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED; - -public class QProfileRuleImplTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private System2 system2 = new AlwaysIncreasingSystem2(); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public EsTester es = EsTester.create(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - private RuleIndex ruleIndex = new RuleIndex(es.client(), system2); - private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client()); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); - private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation())); - - private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession); - private QProfileRules underTest = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer); - - @Test - public void system_activates_rule_without_parameters() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap()); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void user_activates_rule_without_parameters() { - userSession.logIn(); - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap()); - assertThatProfileIsUpdatedByUser(profile); - } - - @Test - public void activate_rule_with_default_severity_and_parameters() { - RuleDefinitionDto rule = createRule(); - RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10")); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void activate_rule_with_parameters() { - RuleDefinitionDto rule = createRule(); - RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId(), null, of(ruleParam.getName(), "15")); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "15")); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void activate_rule_with_default_severity() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap()); - assertThatProfileIsUpdatedBySystem(profile); - } - - /** - * SONAR-5841 - */ - @Test - public void activate_rule_with_empty_parameter_having_no_default_value() { - RuleDefinitionDto rule = createRule(); - RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId(), null, of("min", "")); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10")); - assertThatProfileIsUpdatedBySystem(profile); - } - - /** - * // * SONAR-5840 - * // - */ - @Test - public void activate_rule_with_negative_integer_value_on_parameter_having_no_default_value() { - RuleDefinitionDto rule = createRule(); - RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null)); - RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), "-10")); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, - of(paramWithoutDefault.getName(), "-10", paramWithDefault.getName(), paramWithDefault.getDefaultValue())); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void activation_ignores_unsupported_parameters() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId(), null, of("xxx", "yyy")); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue())); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void update_an_already_activated_rule() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation - RuleActivation activation = RuleActivation.create(rule.getId(), MAJOR, null); - activate(profile, activation); - - // update - RuleActivation updateActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "20")); - List<ActiveRuleChange> changes = activate(profile, updateActivation); - - assertThatRuleIsUpdated(profile, rule, CRITICAL, null, of(param.getName(), "20")); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void update_activation_with_parameter_without_default_value() { - RuleDefinitionDto rule = createRule(); - RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null)); - RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation -> param "max" has a default value - RuleActivation activation = RuleActivation.create(rule.getId()); - activate(profile, activation); - - // update param "min", which has no default value - RuleActivation updateActivation = RuleActivation.create(rule.getId(), MAJOR, of(paramWithoutDefault.getName(), "3")); - List<ActiveRuleChange> changes = activate(profile, updateActivation); - - assertThatRuleIsUpdated(profile, rule, MAJOR, null, of(paramWithDefault.getName(), "10", paramWithoutDefault.getName(), "3")); - assertThatProfileIsUpdatedBySystem(profile); - } - - @Test - public void reset_parameter_to_default_value() { - RuleDefinitionDto rule = createRule(); - RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation -> param "max" has a default value - RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithDefault.getName(), "20")); - activate(profile, activation); - - // reset to default_value - RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(paramWithDefault.getName(), "")); - List<ActiveRuleChange> changes = activate(profile, updateActivation); - - assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), "10")); - assertThat(changes).hasSize(1); - } - - @Test - public void update_activation_removes_parameter_without_default_value() { - RuleDefinitionDto rule = createRule(); - RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null)); - RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation -> param "max" has a default value - RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), "20")); - activate(profile, activation); - - // remove parameter - RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), "")); - List<ActiveRuleChange> changes = activate(profile, updateActivation); - - assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), paramWithDefault.getDefaultValue())); - assertThat(changes).hasSize(1); - } - - @Test - public void update_activation_with_new_parameter() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation -> param "max" has a default value - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(profile, activation); - db.getDbClient().activeRuleDao().deleteParametersByRuleProfileUuids(db.getSession(), asList(profile.getRulesProfileUuid())); - assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap()); - - // contrary to activerule, the param is supposed to be inserted but not updated - RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(param.getName(), "")); - changes = activate(profile, updateActivation); - - assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue())); - assertThat(changes).hasSize(1); - } - - @Test - public void ignore_activation_without_changes() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - - // initial activation - RuleActivation activation = RuleActivation.create(rule.getId()); - activate(profile, activation); - - // update with exactly the same severity and params - activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(profile, activation); - - assertThat(changes).isEmpty(); - } - - @Test - public void do_not_change_severity_and_params_if_unset_and_already_activated() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10")); - QProfileDto profile = createProfile(rule); - - // initial activation -> param "max" has a default value - RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, of(param.getName(), "20")); - activate(profile, activation); - - // update without any severity or params => keep - RuleActivation update = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(profile, update); - - assertThat(changes).isEmpty(); - } - - @Test - public void fail_to_activate_rule_if_profile_is_on_different_languages() { - RuleDefinitionDto rule = createJavaRule(); - QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage("js")); - RuleActivation activation = RuleActivation.create(rule.getId()); - - expectFailure("java rule " + rule.getKey() + " cannot be activated on js profile " + profile.getKee(), () -> activate(profile, activation)); - } - - @Test - public void fail_to_activate_rule_if_rule_has_REMOVED_status() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setStatus(RuleStatus.REMOVED)); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId()); - - expectFailure("Rule was removed: " + rule.getKey(), () -> activate(profile, activation)); - } - - @Test - public void fail_to_activate_if_template() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setIsTemplate(true)); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId()); - - expectFailure("Rule template can't be activated on a Quality profile: " + rule.getKey(), () -> activate(profile, activation)); - } - - @Test - public void fail_to_activate_if_invalid_parameter() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10").setType(PropertyType.INTEGER.name())); - QProfileDto profile = createProfile(rule); - - RuleActivation activation = RuleActivation.create(rule.getId(), null, of(param.getName(), "foo")); - expectFailure("Value 'foo' must be an integer.", () -> activate(profile, activation)); - } - - @Test - public void ignore_parameters_when_activating_custom_rule() { - RuleDefinitionDto templateRule = db.rules().insert(r -> r.setIsTemplate(true)); - RuleParamDto templateParam = db.rules().insertRuleParam(templateRule, p -> p.setName("format")); - RuleDefinitionDto customRule = db.rules().insert(newCustomRule(templateRule)); - RuleParamDto customParam = db.rules().insertRuleParam(customRule, p -> p.setName("format").setDefaultValue("txt")); - QProfileDto profile = createProfile(customRule); - - // initial activation - RuleActivation activation = RuleActivation.create(customRule.getId(), MAJOR, emptyMap()); - activate(profile, activation); - assertThatRuleIsActivated(profile, customRule, null, MAJOR, null, of("format", "txt")); - - // update -> parameter is not changed - RuleActivation updateActivation = RuleActivation.create(customRule.getId(), BLOCKER, of("format", "xml")); - activate(profile, updateActivation); - assertThatRuleIsActivated(profile, customRule, null, BLOCKER, null, of("format", "txt")); - } - - @Test - public void user_deactivates_a_rule() { - userSession.logIn(); - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId()); - activate(profile, activation); - - List<ActiveRuleChange> changes = deactivate(profile, rule); - verifyNoActiveRules(); - assertThatProfileIsUpdatedByUser(profile); - assertThat(changes).hasSize(1); - assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED); - } - - @Test - public void system_deactivates_a_rule() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId()); - activate(profile, activation); - - List<ActiveRuleChange> changes = deactivate(profile, rule); - verifyNoActiveRules(); - assertThatProfileIsUpdatedBySystem(profile); - assertThatChangeIsDeactivation(changes, rule); - } - - private void assertThatChangeIsDeactivation(List<ActiveRuleChange> changes, RuleDefinitionDto rule) { - assertThat(changes).hasSize(1); - ActiveRuleChange change = changes.get(0); - assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED); - assertThat(change.getKey().getRuleKey()).isEqualTo(rule.getKey()); - } - - @Test - public void ignore_deactivation_if_rule_is_not_activated() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - - List<ActiveRuleChange> changes = deactivate(profile, rule); - verifyNoActiveRules(); - assertThat(changes).hasSize(0); - } - - @Test - public void deactivate_rule_that_has_REMOVED_status() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - RuleActivation activation = RuleActivation.create(rule.getId()); - activate(profile, activation); - - rule.setStatus(RuleStatus.REMOVED); - db.getDbClient().ruleDao().update(db.getSession(), rule); - - List<ActiveRuleChange> changes = deactivate(profile, rule); - verifyNoActiveRules(); - assertThatChangeIsDeactivation(changes, rule); - } - - @Test - public void activation_on_child_profile_is_propagated_to_descendants() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - List<ActiveRuleChange> changes = activate(childProfile, RuleActivation.create(rule.getId())); - assertThatProfileHasNoActiveRules(parentProfile); - assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(grandChildProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap()); - } - - @Test - public void update_on_child_profile_is_propagated_to_descendants() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - System.out.println("ACTIVATE ON " + childProfile.getName()); - RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(childProfile, initialActivation); - - System.out.println("---------------"); - System.out.println("ACTIVATE ON " + childProfile.getName()); - RuleActivation updateActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar")); - List<ActiveRuleChange> changes = activate(childProfile, updateActivation); - - assertThatProfileHasNoActiveRules(parentProfile); - assertThatRuleIsUpdated(childProfile, rule, CRITICAL, null, of(param.getName(), "bar")); - assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, INHERITED, of(param.getName(), "bar")); - assertThat(changes).hasSize(2); - } - - @Test - public void override_activation_of_inherited_profile() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(childProfile, initialActivation); - - RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar")); - List<ActiveRuleChange> changes = activate(grandChildProfile, overrideActivation); - - assertThatProfileHasNoActiveRules(parentProfile); - assertThatRuleIsUpdated(childProfile, rule, MAJOR, null, of(param.getName(), "foo")); - assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar")); - assertThat(changes).hasSize(1); - } - - @Test - public void updated_activation_on_parent_is_not_propagated_to_overridden_profiles() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(childProfile, initialActivation); - - RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar")); - activate(grandChildProfile, overrideActivation); - - // update child --> do not touch grandChild - RuleActivation updateActivation = RuleActivation.create(rule.getId(), BLOCKER, of(param.getName(), "baz")); - List<ActiveRuleChange> changes = activate(childProfile, updateActivation); - - assertThatProfileHasNoActiveRules(parentProfile); - assertThatRuleIsUpdated(childProfile, rule, BLOCKER, null, of(param.getName(), "baz")); - assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar")); - assertThat(changes).hasSize(1); - } - - @Test - public void reset_on_parent_is_not_propagated_to_overridden_profiles() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(parentProfile, initialActivation); - - RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar")); - activate(grandChildProfile, overrideActivation); - - // reset parent --> touch child but not grandChild - RuleActivation updateActivation = RuleActivation.createReset(rule.getId()); - List<ActiveRuleChange> changes = activate(parentProfile, updateActivation); - - assertThatRuleIsUpdated(parentProfile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue())); - assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), INHERITED, of(param.getName(), param.getDefaultValue())); - assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar")); - assertThat(changes).hasSize(2); - } - - @Test - public void active_on_parent_a_rule_already_activated_on_child() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation childActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(childProfile, childActivation); - - RuleActivation parentActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar")); - List<ActiveRuleChange> changes = activate(parentProfile, parentActivation); - - assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, of(param.getName(), "bar")); - assertThatRuleIsUpdated(childProfile, rule, MAJOR, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "foo")); - assertThat(changes).hasSize(2); - } - - @Test - public void do_not_mark_as_overridden_if_same_values_than_parent() { - RuleDefinitionDto rule = createRule(); - RuleParamDto param = db.rules().insertRuleParam(rule); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation parentActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - activate(parentProfile, parentActivation); - - RuleActivation overrideActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo")); - List<ActiveRuleChange> changes = activate(childProfile, overrideActivation); - - assertThatRuleIsUpdated(childProfile, rule, MAJOR, INHERITED, of(param.getName(), "foo")); - assertThat(changes).hasSize(0); - } - - @Test - public void propagate_deactivation_on_children() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(parentProfile, activation); - assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap()); - - changes = deactivate(parentProfile, rule); - assertThatProfileHasNoActiveRules(parentProfile); - assertThatProfileHasNoActiveRules(childProfile); - assertThat(changes).hasSize(2); - } - - @Test - public void propagate_deactivation_on_children_even_when_overridden() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(parentProfile, activation); - assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap()); - - activation = RuleActivation.create(rule.getId(), CRITICAL, null); - activate(childProfile, activation); - - changes = deactivate(parentProfile, rule); - assertThatProfileHasNoActiveRules(parentProfile); - assertThatProfileHasNoActiveRules(childProfile); - assertThat(changes).hasSize(2); - } - - @Test - public void cannot_deactivate_rule_inherited() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation activation = RuleActivation.create(rule.getId()); - List<ActiveRuleChange> changes = activate(parentProfile, activation); - assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap()); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Cannot deactivate inherited rule"); - deactivate(childProfile, rule); - } - - @Test - public void reset_child_profile_do_not_change_parent() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null); - List<ActiveRuleChange> changes = activate(parentProfile, activation); - assertThatRuleIsActivated(parentProfile, rule, changes, CRITICAL, null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, INHERITED, emptyMap()); - assertThat(changes).hasSize(2); - - RuleActivation childActivation = RuleActivation.create(rule.getId(), BLOCKER, null); - changes = activate(childProfile, childActivation); - assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap()); - assertThat(changes).hasSize(1); - - RuleActivation resetActivation = RuleActivation.createReset(rule.getId()); - changes = activate(childProfile, resetActivation); - assertThatRuleIsUpdated(childProfile, rule, CRITICAL, INHERITED, emptyMap()); - assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, emptyMap()); - assertThat(changes).hasSize(1); - } - - @Test - public void reset_parent_is_not_propagated_when_child_overrides() { - RuleDefinitionDto rule = createRule(); - QProfileDto baseProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(baseProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null); - List<ActiveRuleChange> changes = activate(baseProfile, activation); - assertThatRuleIsActivated(baseProfile, rule, changes, CRITICAL, null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, INHERITED, emptyMap()); - assertThatRuleIsActivated(grandChildProfile, rule, changes, CRITICAL, INHERITED, emptyMap()); - assertThat(changes).hasSize(3); - - RuleActivation childActivation = RuleActivation.create(rule.getId(), BLOCKER, null); - changes = activate(childProfile, childActivation); - assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap()); - assertThatRuleIsUpdated(grandChildProfile, rule, BLOCKER, INHERITED, emptyMap()); - assertThat(changes).hasSize(2); - - // Reset on parent do not change child nor grandchild - RuleActivation resetActivation = RuleActivation.createReset(rule.getId()); - changes = activate(baseProfile, resetActivation); - assertThatRuleIsUpdated(baseProfile, rule, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap()); - assertThatRuleIsUpdated(grandChildProfile, rule, BLOCKER, INHERITED, emptyMap()); - assertThat(changes).hasSize(1); - - // Reset on child change grandchild - resetActivation = RuleActivation.createReset(rule.getId()); - changes = activate(childProfile, resetActivation); - assertThatRuleIsUpdated(baseProfile, rule, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), INHERITED, emptyMap()); - assertThatRuleIsUpdated(grandChildProfile, rule, rule.getSeverityString(), INHERITED, emptyMap()); - assertThat(changes).hasSize(2); - } - - @Test - public void ignore_reset_if_not_activated() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - createChildProfile(parentProfile); - - RuleActivation resetActivation = RuleActivation.createReset(rule.getId()); - List<ActiveRuleChange> changes = activate(parentProfile, resetActivation); - verifyNoActiveRules(); - assertThat(changes).hasSize(0); - } - - @Test - public void bulk_activation() { - int bulkSize = SearchOptions.MAX_LIMIT + 10 + new Random().nextInt(100); - String language = randomAlphanumeric(10); - String repositoryKey = randomAlphanumeric(10); - QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(language)); - - List<RuleDto> rules = new ArrayList<>(); - IntStream.rangeClosed(1, bulkSize).forEach( - i -> rules.add(db.rules().insertRule(r -> r.setLanguage(language).setRepositoryKey(repositoryKey)))); - - verifyNoActiveRules(); - ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes()); - - RuleQuery ruleQuery = new RuleQuery() - .setRepositories(singletonList(repositoryKey)); - - BulkChangeResult bulkChangeResult = underTest.bulkActivateAndCommit(db.getSession(), profile, ruleQuery, MINOR); - - assertThat(bulkChangeResult.countFailed()).isEqualTo(0); - assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize); - assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize); - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(bulkSize); - rules.stream().forEach( - r -> assertThatRuleIsActivated(profile, r.getDefinition(), null, MINOR, null, emptyMap())); - } - - @Test - public void bulk_deactivation() { - int bulkSize = SearchOptions.MAX_LIMIT + 10 + new Random().nextInt(100); - String language = randomAlphanumeric(10); - String repositoryKey = randomAlphanumeric(10); - QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(language)); - - List<RuleDto> rules = new ArrayList<>(); - IntStream.rangeClosed(1, bulkSize).forEach( - i -> rules.add(db.rules().insertRule(r -> r.setLanguage(language).setRepositoryKey(repositoryKey)))); - - verifyNoActiveRules(); - ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes()); - - RuleQuery ruleQuery = new RuleQuery() - .setRepositories(singletonList(repositoryKey)); - - BulkChangeResult bulkChangeResult = underTest.bulkActivateAndCommit(db.getSession(), profile, ruleQuery, MINOR); - - assertThat(bulkChangeResult.countFailed()).isEqualTo(0); - assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize); - assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize); - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(bulkSize); - - // Now deactivate all rules - bulkChangeResult = underTest.bulkDeactivateAndCommit(db.getSession(), profile, ruleQuery); - - assertThat(bulkChangeResult.countFailed()).isEqualTo(0); - assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize); - assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize); - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(0); - rules.stream().forEach( - r -> assertThatRuleIsNotPresent(profile, r.getDefinition())); - } - - @Test - public void bulk_deactivation_ignores_errors() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - List<ActiveRuleChange> changes = activate(parentProfile, RuleActivation.create(rule.getId())); - assertThatRuleIsActivated(parentProfile, rule, null, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, null, rule.getSeverityString(), INHERITED, emptyMap()); - - ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes()); - - RuleQuery ruleQuery = new RuleQuery() - .setQProfile(childProfile); - BulkChangeResult bulkChangeResult = underTest.bulkDeactivateAndCommit(db.getSession(), childProfile, ruleQuery); - - assertThat(bulkChangeResult.countFailed()).isEqualTo(1); - assertThat(bulkChangeResult.countSucceeded()).isEqualTo(0); - assertThat(bulkChangeResult.getChanges()).hasSize(0); - assertThatRuleIsActivated(parentProfile, rule, null, rule.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule, null, rule.getSeverityString(), INHERITED, emptyMap()); - } - - @Test - public void bulk_change_severity() { - RuleDefinitionDto rule1 = createJavaRule(); - RuleDefinitionDto rule2 = createJavaRule(); - QProfileDto parentProfile = createProfile(rule1); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandchildProfile = createChildProfile(childProfile); - - activate(parentProfile, RuleActivation.create(rule1.getId())); - activate(parentProfile, RuleActivation.create(rule2.getId())); - - ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes()); - - RuleQuery query = new RuleQuery() - .setRuleKey(rule1.getRuleKey()) - .setQProfile(parentProfile); - BulkChangeResult result = underTest.bulkActivateAndCommit(db.getSession(), parentProfile, query, "BLOCKER"); - - assertThat(result.getChanges()).hasSize(3); - assertThat(result.countSucceeded()).isEqualTo(1); - assertThat(result.countFailed()).isEqualTo(0); - - // Rule1 must be activated with BLOCKER on all profiles - assertThatRuleIsActivated(parentProfile, rule1, null, BLOCKER, null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule1, null, BLOCKER, INHERITED, emptyMap()); - assertThatRuleIsActivated(grandchildProfile, rule1, null, BLOCKER, INHERITED, emptyMap()); - - // Rule2 did not changed - assertThatRuleIsActivated(parentProfile, rule2, null, rule2.getSeverityString(), null, emptyMap()); - assertThatRuleIsActivated(childProfile, rule2, null, rule2.getSeverityString(), INHERITED, emptyMap()); - assertThatRuleIsActivated(grandchildProfile, rule2, null, rule2.getSeverityString(), INHERITED, emptyMap()); - } - - @Test - public void delete_rule_from_all_profiles() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandChildProfile = createChildProfile(childProfile); - - RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null); - activate(parentProfile, activation); - - RuleActivation overrideActivation = RuleActivation.create(rule.getId(), BLOCKER, null); - activate(grandChildProfile, overrideActivation); - - // Reset on parent do not change child nor grandchild - List<ActiveRuleChange> changes = underTest.deleteRule(db.getSession(), rule); - - assertThatRuleIsNotPresent(parentProfile, rule); - assertThatRuleIsNotPresent(childProfile, rule); - assertThatRuleIsNotPresent(grandChildProfile, rule); - assertThat(changes) - .extracting(ActiveRuleChange::getType) - .containsOnly(ActiveRuleChange.Type.DEACTIVATED) - .hasSize(3); - } - - @Test - public void activation_fails_when_profile_is_built_in() { - RuleDefinitionDto rule = createRule(); - QProfileDto builtInProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true)); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The built-in profile " + builtInProfile.getName() + " is read-only and can't be updated"); - - underTest.activateAndCommit(db.getSession(), builtInProfile, singleton(RuleActivation.create(rule.getId()))); - } - - private void assertThatProfileHasNoActiveRules(QProfileDto profile) { - List<OrgActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile); - assertThat(activeRules).isEmpty(); - } - - private List<ActiveRuleChange> deactivate(QProfileDto profile, RuleDefinitionDto rule) { - return underTest.deactivateAndCommit(db.getSession(), profile, singleton(rule.getId())); - } - - private List<ActiveRuleChange> activate(QProfileDto profile, RuleActivation activation) { - return underTest.activateAndCommit(db.getSession(), profile, singleton(activation)); - } - - private QProfileDto createProfile(RuleDefinitionDto rule) { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage())); - } - - private QProfileDto createChildProfile(QProfileDto parent) { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p - .setLanguage(parent.getLanguage()) - .setParentKee(parent.getKee()) - .setName("Child of " + parent.getName())); - } - - private void assertThatProfileIsUpdatedByUser(QProfileDto profile) { - QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee()); - assertThat(loaded.getUserUpdatedAt()).isNotNull(); - assertThat(loaded.getRulesUpdatedAt()).isNotEmpty(); - } - - private void assertThatProfileIsUpdatedBySystem(QProfileDto profile) { - QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee()); - assertThat(loaded.getUserUpdatedAt()).isNull(); - assertThat(loaded.getRulesUpdatedAt()).isNotEmpty(); - } - - private void assertThatRuleIsActivated(QProfileDto profile, RuleDefinitionDto rule, @Nullable List<ActiveRuleChange> changes, - String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) { - OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst() - .orElseThrow(IllegalStateException::new); - - assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity); - assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null); - assertThat(activeRule.getCreatedAt()).isNotNull(); - assertThat(activeRule.getUpdatedAt()).isNotNull(); - - List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId()); - assertThat(params).hasSize(expectedParams.size()); - - if (changes != null) { - ActiveRuleChange change = changes.stream() - .filter(c -> c.getActiveRule().getId().equals(activeRule.getId())) - .findFirst().orElseThrow(IllegalStateException::new); - assertThat(change.getInheritance()).isEqualTo(expectedInheritance); - assertThat(change.getSeverity()).isEqualTo(expectedSeverity); - assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED); - } - } - - private void assertThatRuleIsNotPresent(QProfileDto profile, RuleDefinitionDto rule) { - Optional<OrgActiveRuleDto> activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst(); - - assertThat(activeRule).isEmpty(); - } - - private void assertThatRuleIsUpdated(QProfileDto profile, RuleDefinitionDto rule, - String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) { - OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst() - .orElseThrow(IllegalStateException::new); - - assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity); - assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null); - assertThat(activeRule.getCreatedAt()).isNotNull(); - assertThat(activeRule.getUpdatedAt()).isNotNull(); - - List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId()); - assertThat(params).hasSize(expectedParams.size()); - } - - private void expectFailure(String expectedMessage, Runnable runnable) { - try { - runnable.run(); - fail(); - } catch (BadRequestException e) { - assertThat(e.getMessage()).isEqualTo(expectedMessage); - } - verifyNoActiveRules(); - } - - private void verifyNoActiveRules() { - assertThat(db.countRowsOfTable(db.getSession(), "active_rules")).isEqualTo(0); - } - - private RuleDefinitionDto createRule() { - return db.rules().insert(r -> r.setSeverity(Severity.MAJOR)); - } - - private RuleDefinitionDto createJavaRule() { - return db.rules().insert(r -> r.setSeverity(Severity.MAJOR).setLanguage("java")); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRulesImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRulesImplTest.java deleted file mode 100644 index 88c3a82e875..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRulesImplTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import com.google.common.collect.ImmutableMap; -import java.util.Collections; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rule.Severity; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileChangeDto; -import org.sonar.db.qualityprofile.QProfileChangeQuery; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.TypeValidations; - -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -public class QProfileRulesImplTest { - - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public DbTester db = DbTester.create(); - @Rule - public EsTester es = EsTester.create(); - - private RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE); - private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client()); - private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, db.getDbClient(), new TypeValidations(singletonList(new IntegerTypeValidation())), userSession); - - private QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer); - - @Test - public void activate_one_rule() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto qProfile = db.qualityProfiles().insert(organization); - RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(qProfile.getLanguage())); - RuleActivation ruleActivation = RuleActivation.create(rule.getId(), Severity.CRITICAL, Collections.emptyMap()); - - qProfileRules.activateAndCommit(db.getSession(), qProfile, singleton(ruleActivation)); - - assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), qProfile)) - .extracting(ActiveRuleDto::getRuleKey, ActiveRuleDto::getSeverityString) - .containsExactlyInAnyOrder(tuple(rule.getKey(), Severity.CRITICAL)); - } - - @Test - public void active_rule_change() { - UserDto user = db.users().insertUser(); - userSession.logIn(user); - OrganizationDto organization = db.organizations().insert(); - QProfileDto qProfile = db.qualityProfiles().insert(organization); - RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(qProfile.getLanguage())); - RuleActivation ruleActivation = RuleActivation.create(rule.getId(), Severity.CRITICAL, Collections.emptyMap()); - - qProfileRules.activateAndCommit(db.getSession(), qProfile, singleton(ruleActivation)); - - assertThat(db.getDbClient().qProfileChangeDao().selectByQuery(db.getSession(), new QProfileChangeQuery(qProfile.getKee()))) - .extracting(QProfileChangeDto::getUserUuid, QProfileChangeDto::getDataAsMap) - .containsExactlyInAnyOrder(tuple(user.getUuid(), ImmutableMap.of("ruleId", Integer.toString(rule.getId()), "severity", Severity.CRITICAL))); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java deleted file mode 100644 index 4339d33c9ba..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.QProfileDto; - -/** - * Utility class for tests involving quality profiles. - * @deprecated replaced by {@link org.sonar.db.qualityprofile.QualityProfileDbTester} - */ -@Deprecated -public class QProfileTesting { - - public static final QProfileName XOO_P1_NAME = new QProfileName("xoo", "P1"); - public static final String XOO_P1_KEY = "XOO_P1"; - public static final QProfileName XOO_P2_NAME = new QProfileName("xoo", "P2"); - public static final String XOO_P2_KEY = "XOO_P2"; - public static final QProfileName XOO_P3_NAME = new QProfileName("xoo", "P3"); - public static final String XOO_P3_KEY = "XOO_P3"; - - /** - * @deprecated provide organization as dto - */ - @Deprecated - public static QProfileDto newQProfileDto(String organizationUuid, QProfileName name, String key) { - return new QProfileDto() - .setKee(key) - .setRulesProfileUuid("rp-" + key) - .setOrganizationUuid(organizationUuid) - .setName(name.getName()) - .setLanguage(name.getLanguage()); - } - - /** - * @deprecated provide organization as dto - */ - @Deprecated - public static QProfileDto newXooP1(String organizationUuid) { - return newQProfileDto(organizationUuid, XOO_P1_NAME, XOO_P1_KEY); - } - - /** - * @deprecated provide organization as dto - */ - @Deprecated - public static QProfileDto newXooP2(String organizationUuid) { - return newQProfileDto(organizationUuid, XOO_P2_NAME, XOO_P2_KEY); - } - - /** - * @deprecated provide organization as dto - */ - @Deprecated - public static QProfileDto newXooP3(String organizationUuid) { - return newQProfileDto(organizationUuid, XOO_P3_NAME, XOO_P3_KEY); - } - - public static QProfileDto newQProfileDto(OrganizationDto organization, QProfileName name, String uuid) { - return new QProfileDto() - .setKee(uuid) - .setRulesProfileUuid("rp-" + uuid) - .setOrganizationUuid(organization.getUuid()) - .setName(name.getName()) - .setLanguage(name.getLanguage()); - } - - public static QProfileDto newXooP1(OrganizationDto organization) { - return newQProfileDto(organization, XOO_P1_NAME, XOO_P1_KEY); - } - - public static QProfileDto newXooP2(OrganizationDto organization) { - return newQProfileDto(organization, XOO_P2_NAME, XOO_P2_KEY); - } - - public static QProfileDto newXooP3(OrganizationDto organization) { - return newQProfileDto(organization, XOO_P3_NAME, XOO_P3_KEY); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTreeImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTreeImplTest.java deleted file mode 100644 index 77e3fcc903e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTreeImplTest.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.OrgActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.IntegerTypeValidation; -import org.sonar.server.util.StringTypeValidation; -import org.sonar.server.util.TypeValidations; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singleton; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED; - -public class QProfileTreeImplTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private System2 system2 = new AlwaysIncreasingSystem2(); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public EsTester es = EsTester.create(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client()); - private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation())); - private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession); - private QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, null, activeRuleIndexer); - private QProfileTree underTest = new QProfileTreeImpl(db.getDbClient(), ruleActivator, System2.INSTANCE, activeRuleIndexer); - - @Test - public void set_itself_as_parent_fails() { - RuleDefinitionDto rule = createRule(); - QProfileDto profile = createProfile(rule); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(" can not be selected as parent of "); - - underTest.setParentAndCommit(db.getSession(), profile, profile); - } - - @Test - public void set_child_as_parent_fails() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(" can not be selected as parent of "); - underTest.setParentAndCommit(db.getSession(), parentProfile, childProfile); - } - - @Test - public void set_grandchild_as_parent_fails() { - RuleDefinitionDto rule = createRule(); - QProfileDto parentProfile = createProfile(rule); - QProfileDto childProfile = createChildProfile(parentProfile); - QProfileDto grandchildProfile = createChildProfile(childProfile); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(" can not be selected as parent of "); - underTest.setParentAndCommit(db.getSession(), parentProfile, grandchildProfile); - } - - @Test - public void cannot_set_parent_if_language_is_different() { - RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("foo")); - RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("bar")); - - QProfileDto parentProfile = createProfile(rule1); - List<ActiveRuleChange> changes = activate(parentProfile, RuleActivation.create(rule1.getId())); - assertThat(changes).hasSize(1); - - QProfileDto childProfile = createProfile(rule2); - changes = activate(childProfile, RuleActivation.create(rule2.getId())); - assertThat(changes).hasSize(1); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Cannot set the profile"); - - underTest.setParentAndCommit(db.getSession(), childProfile, parentProfile); - } - - @Test - public void set_then_unset_parent() { - RuleDefinitionDto rule1 = createJavaRule(); - RuleDefinitionDto rule2 = createJavaRule(); - - QProfileDto profile1 = createProfile(rule1); - List<ActiveRuleChange> changes = activate(profile1, RuleActivation.create(rule1.getId())); - assertThat(changes).hasSize(1); - - QProfileDto profile2 = createProfile(rule2); - changes = activate(profile2, RuleActivation.create(rule2.getId())); - assertThat(changes).hasSize(1); - - changes = underTest.setParentAndCommit(db.getSession(), profile2, profile1); - assertThat(changes).hasSize(1); - assertThatRuleIsActivated(profile2, rule1, changes, rule1.getSeverityString(), INHERITED, emptyMap()); - assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap()); - - changes = underTest.removeParentAndCommit(db.getSession(), profile2); - assertThat(changes).hasSize(1); - assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap()); - assertThatRuleIsNotPresent(profile2, rule1); - } - - @Test - public void set_then_unset_parent_keep_overridden_rules() { - RuleDefinitionDto rule1 = createJavaRule(); - RuleDefinitionDto rule2 = createJavaRule(); - QProfileDto profile1 = createProfile(rule1); - List<ActiveRuleChange> changes = activate(profile1, RuleActivation.create(rule1.getId())); - assertThat(changes).hasSize(1); - - QProfileDto profile2 = createProfile(rule2); - changes = activate(profile2, RuleActivation.create(rule2.getId())); - assertThat(changes).hasSize(1); - - changes = underTest.setParentAndCommit(db.getSession(), profile2, profile1); - assertThat(changes).hasSize(1); - assertThatRuleIsActivated(profile2, rule1, changes, rule1.getSeverityString(), INHERITED, emptyMap()); - assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap()); - - RuleActivation activation = RuleActivation.create(rule1.getId(), BLOCKER, null); - changes = activate(profile2, activation); - assertThat(changes).hasSize(1); - assertThatRuleIsUpdated(profile2, rule1, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap()); - assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap()); - - changes = underTest.removeParentAndCommit(db.getSession(), profile2); - assertThat(changes).hasSize(1); - // Not testing changes here since severity is not set in changelog - assertThatRuleIsActivated(profile2, rule1, null, BLOCKER, null, emptyMap()); - assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap()); - } - - @Test - public void activation_errors_are_ignored_when_setting_a_parent() { - RuleDefinitionDto rule1 = createJavaRule(); - RuleDefinitionDto rule2 = createJavaRule(); - QProfileDto parentProfile = createProfile(rule1); - activate(parentProfile, RuleActivation.create(rule1.getId())); - activate(parentProfile, RuleActivation.create(rule2.getId())); - - rule1.setStatus(RuleStatus.REMOVED); - db.rules().update(rule1); - - QProfileDto childProfile = createProfile(rule1); - List<ActiveRuleChange> changes = underTest.setParentAndCommit(db.getSession(), childProfile, parentProfile); - - assertThatRuleIsNotPresent(childProfile, rule1); - assertThatRuleIsActivated(childProfile, rule2, changes, rule2.getSeverityString(), INHERITED, emptyMap()); - } - - private List<ActiveRuleChange> activate(QProfileDto profile, RuleActivation activation) { - return qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation)); - } - - private QProfileDto createProfile(RuleDefinitionDto rule) { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage())); - } - - private QProfileDto createChildProfile(QProfileDto parent) { - return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p - .setLanguage(parent.getLanguage()) - .setParentKee(parent.getKee()) - .setName("Child of " + parent.getName())); - } - - private void assertThatRuleIsActivated(QProfileDto profile, RuleDefinitionDto rule, @Nullable List<ActiveRuleChange> changes, - String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) { - OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst() - .orElseThrow(IllegalStateException::new); - - assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity); - assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null); - assertThat(activeRule.getCreatedAt()).isNotNull(); - assertThat(activeRule.getUpdatedAt()).isNotNull(); - - List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId()); - assertThat(params).hasSize(expectedParams.size()); - - if (changes != null) { - ActiveRuleChange change = changes.stream() - .filter(c -> c.getActiveRule().getId().equals(activeRule.getId())) - .findFirst().orElseThrow(IllegalStateException::new); - assertThat(change.getInheritance()).isEqualTo(expectedInheritance); - assertThat(change.getSeverity()).isEqualTo(expectedSeverity); - assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED); - } - } - - private void assertThatRuleIsNotPresent(QProfileDto profile, RuleDefinitionDto rule) { - Optional<OrgActiveRuleDto> activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst(); - - assertThat(activeRule).isEmpty(); - } - - private void assertThatRuleIsUpdated(QProfileDto profile, RuleDefinitionDto rule, - String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) { - OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile) - .stream() - .filter(ar -> ar.getRuleKey().equals(rule.getKey())) - .findFirst() - .orElseThrow(IllegalStateException::new); - - assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity); - assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null); - assertThat(activeRule.getCreatedAt()).isNotNull(); - assertThat(activeRule.getUpdatedAt()).isNotNull(); - - List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId()); - assertThat(params).hasSize(expectedParams.size()); - } - - private RuleDefinitionDto createRule() { - return db.rules().insert(r -> r.setSeverity(Severity.MAJOR)); - } - - private RuleDefinitionDto createJavaRule() { - return db.rules().insert(r -> r.setSeverity(Severity.MAJOR).setLanguage("java")); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java deleted file mode 100644 index d6a535e448f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import com.google.common.collect.Multimap; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.function.Consumer; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; -import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInActiveRule; -import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.NewBuiltInQualityProfile; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.log.LogTester; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.core.util.stream.MoreCollectors; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.RulesProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.util.TypeValidations; - -import static com.google.common.base.Preconditions.checkState; -import static java.util.Collections.singleton; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.apache.commons.lang.math.RandomUtils.nextLong; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RulePriority.MAJOR; -import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto; -import static org.sonar.server.language.LanguageTesting.newLanguage; -import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.ACTIVATED; -import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.DEACTIVATED; -import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.UPDATED; - -public class RegisterQualityProfilesNotificationTest { - - private static final Random RANDOM = new SecureRandom(); - - private System2 system2 = mock(System2.class); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public BuiltInQProfileRepositoryRule builtInQProfileRepositoryRule = new BuiltInQProfileRepositoryRule(); - @Rule - public LogTester logTester = new LogTester(); - - private DbClient dbClient = db.getDbClient(); - private TypeValidations typeValidations = mock(TypeValidations.class); - private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class); - private BuiltInQProfileInsert builtInQProfileInsert = new BuiltInQProfileInsertImpl(dbClient, system2, UuidFactoryFast.getInstance(), typeValidations, activeRuleIndexer); - private RuleActivator ruleActivator = new RuleActivator(system2, dbClient, typeValidations, userSessionRule); - private QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, mock(RuleIndex.class), activeRuleIndexer); - private BuiltInQProfileUpdate builtInQProfileUpdate = new BuiltInQProfileUpdateImpl(dbClient, ruleActivator, activeRuleIndexer); - private BuiltInQualityProfilesUpdateListener builtInQualityProfilesNotification = mock(BuiltInQualityProfilesUpdateListener.class); - private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, - builtInQProfileInsert, builtInQProfileUpdate, builtInQualityProfilesNotification, system2); - - @Test - public void do_not_send_notification_on_new_profile() { - String language = newLanguageKey(); - builtInQProfileRepositoryRule.add(newLanguage(language), "Sonar way"); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - verifyZeroInteractions(builtInQualityProfilesNotification); - } - - @Test - public void do_not_send_notification_when_profile_is_not_updated() { - String language = newLanguageKey(); - RuleDefinitionDto dbRule = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile = insertBuiltInProfile(language); - activateRuleInDb(dbProfile, dbRule, MAJOR); - addPluginProfile(dbProfile, dbRule); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - verifyZeroInteractions(builtInQualityProfilesNotification); - } - - @Test - public void send_notification_when_a_new_rule_is_activated() { - String language = newLanguageKey(); - RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile = insertBuiltInProfile(language); - activateRuleInDb(dbProfile, existingRule, MAJOR); - RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(language)); - addPluginProfile(dbProfile, existingRule, newRule); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder(tuple(dbProfile.getName(), dbProfile.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(newRule.getId(), ACTIVATED)); - } - - @Test - public void send_notification_when_a_rule_is_deactivated() { - String language = newLanguageKey(); - RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile = insertBuiltInProfile(language); - activateRuleInDb(dbProfile, existingRule, MAJOR); - addPluginProfile(dbProfile); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder(tuple(dbProfile.getName(), dbProfile.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(existingRule.getId(), DEACTIVATED)); - } - - @Test - public void send_a_single_notification_when_multiple_rules_are_activated() { - String language = newLanguageKey(); - - RuleDefinitionDto existingRule1 = db.rules().insert(r -> r.setLanguage(language)); - RuleDefinitionDto newRule1 = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile1 = insertBuiltInProfile(language); - activateRuleInDb(dbProfile1, existingRule1, MAJOR); - addPluginProfile(dbProfile1, existingRule1, newRule1); - - RuleDefinitionDto existingRule2 = db.rules().insert(r -> r.setLanguage(language)); - RuleDefinitionDto newRule2 = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile2 = insertBuiltInProfile(language); - activateRuleInDb(dbProfile2, existingRule2, MAJOR); - addPluginProfile(dbProfile2, existingRule2, newRule2); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder( - tuple(dbProfile1.getName(), dbProfile1.getLanguage()), - tuple(dbProfile2.getName(), dbProfile2.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder( - tuple(newRule1.getId(), ACTIVATED), - tuple(newRule2.getId(), ACTIVATED)); - } - - @Test - public void notification_does_not_include_inherited_profiles_when_rule_is_added() { - String language = newLanguageKey(); - RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(language)); - OrganizationDto organization = db.organizations().insert(); - - QProfileDto builtInQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); - QProfileDto childQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInQProfileDto.getKee())); - addPluginProfile(builtInQProfileDto, newRule); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder(tuple(builtInQProfileDto.getName(), builtInQProfileDto.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(newRule.getId(), ACTIVATED)); - } - - @Test - public void notification_does_not_include_inherited_profiled_when_rule_is_changed() { - String language = newLanguageKey(); - RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(language).setSeverity(Severity.MINOR)); - OrganizationDto organization = db.organizations().insert(); - - QProfileDto builtInProfile = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); - db.qualityProfiles().activateRule(builtInProfile, rule, ar -> ar.setSeverity(Severity.MINOR)); - QProfileDto childProfile = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInProfile.getKee())); - db.qualityProfiles().activateRule(childProfile, rule, ar -> ar.setInheritance(ActiveRuleDto.INHERITED).setSeverity(Severity.MINOR)); - addPluginProfile(builtInProfile, rule); - builtInQProfileRepositoryRule.initialize(); - db.commit(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder(tuple(builtInProfile.getName(), builtInProfile.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(rule.getId(), UPDATED)); - } - - @Test - public void notification_does_not_include_inherited_profiles_when_rule_is_deactivated() { - String language = newLanguageKey(); - RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(language).setSeverity(Severity.MINOR)); - OrganizationDto organization = db.organizations().insert(); - - QProfileDto builtInQProfileDto = insertProfile(organization, - orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); - db.qualityProfiles().activateRule(builtInQProfileDto, rule); - QProfileDto childQProfileDto = insertProfile(organization, - orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInQProfileDto.getKee())); - qProfileRules.activateAndCommit(db.getSession(), childQProfileDto, singleton(RuleActivation.create(rule.getId()))); - db.commit(); - - addPluginProfile(builtInQProfileDto); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); - Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); - assertThat(updatedProfiles.keySet()) - .extracting(QProfileName::getName, QProfileName::getLanguage) - .containsExactlyInAnyOrder(tuple(builtInQProfileDto.getName(), builtInQProfileDto.getLanguage())); - assertThat(updatedProfiles.values()) - .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) - .containsExactlyInAnyOrder(tuple(rule.getId(), DEACTIVATED)); - } - - @Test - public void notification_contains_send_start_and_end_date() { - String language = newLanguageKey(); - RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(language)); - RulesProfileDto dbProfile = insertBuiltInProfile(language); - activateRuleInDb(dbProfile, existingRule, MAJOR); - RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(language)); - addPluginProfile(dbProfile, existingRule, newRule); - builtInQProfileRepositoryRule.initialize(); - long startDate = RANDOM.nextInt(5000); - long endDate = startDate + RANDOM.nextInt(5000); - when(system2.now()).thenReturn(startDate, endDate); - - underTest.start(); - - verify(builtInQualityProfilesNotification).onChange(any(), eq(startDate), eq(endDate)); - } - - private void addPluginProfile(RulesProfileDto dbProfile, RuleDefinitionDto... dbRules) { - BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); - NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(dbProfile.getName(), dbProfile.getLanguage()); - - Arrays.stream(dbRules).forEach(dbRule -> newQp.activateRule(dbRule.getRepositoryKey(), dbRule.getRuleKey()).overrideSeverity(Severity.MAJOR)); - newQp.done(); - List<BuiltInActiveRule> rules = context.profile(dbProfile.getLanguage(), dbProfile.getName()).rules(); - BuiltInQProfile.ActiveRule[] activeRules = toActiveRules(rules, dbRules); - builtInQProfileRepositoryRule.add(newLanguage(dbProfile.getLanguage()), dbProfile.getName(), false, activeRules); - } - - private static BuiltInQProfile.ActiveRule[] toActiveRules(List<BuiltInActiveRule> rules, RuleDefinitionDto[] dbRules) { - Map<RuleKey, RuleDefinitionDto> dbRulesByRuleKey = Arrays.stream(dbRules) - .collect(MoreCollectors.uniqueIndex(RuleDefinitionDto::getKey)); - return rules.stream() - .map(r -> { - RuleKey ruleKey = RuleKey.of(r.repoKey(), r.ruleKey()); - RuleDefinitionDto ruleDefinitionDto = dbRulesByRuleKey.get(ruleKey); - checkState(ruleDefinitionDto != null, "Rule '%s' not found", ruleKey); - return new BuiltInQProfile.ActiveRule(ruleDefinitionDto.getId(), r); - }).toArray(BuiltInQProfile.ActiveRule[]::new); - } - - private void addPluginProfile(QProfileDto profile, RuleDefinitionDto... dbRules) { - BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); - NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(profile.getName(), profile.getLanguage()); - - Arrays.stream(dbRules).forEach(dbRule -> newQp.activateRule(dbRule.getRepositoryKey(), dbRule.getRuleKey()).overrideSeverity(Severity.MAJOR)); - newQp.done(); - BuiltInQProfile.ActiveRule[] activeRules = toActiveRules(context.profile(profile.getLanguage(), profile.getName()).rules(), dbRules); - builtInQProfileRepositoryRule.add(newLanguage(profile.getLanguage()), profile.getName(), false, activeRules); - } - - private RulesProfileDto insertBuiltInProfile(String language) { - RulesProfileDto ruleProfileDto = newRuleProfileDto(rp -> rp.setIsBuiltIn(true).setLanguage(language)); - db.getDbClient().qualityProfileDao().insert(db.getSession(), ruleProfileDto); - db.commit(); - return ruleProfileDto; - } - - private void activateRuleInDb(RulesProfileDto profile, RuleDefinitionDto rule, RulePriority severity) { - ActiveRuleDto dto = new ActiveRuleDto() - .setProfileId(profile.getId()) - .setSeverity(severity.name()) - .setRuleId(rule.getId()) - .setCreatedAt(nextLong()) - .setUpdatedAt(nextLong()); - db.getDbClient().activeRuleDao().insert(db.getSession(), dto); - db.commit(); - } - - private QProfileDto insertProfile(OrganizationDto organization, Consumer<QProfileDto> consumer) { - QProfileDto builtInQProfileDto = db.qualityProfiles().insert(organization, consumer); - db.commit(); - return builtInQProfileDto; - } - - private static String newLanguageKey() { - return randomAlphanumeric(20).toLowerCase(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java deleted file mode 100644 index 6b7d6a6dd73..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.resources.Language; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.RulesProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.tester.UserSessionRule; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto; -import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto; - -public class RegisterQualityProfilesTest { - private static final Language FOO_LANGUAGE = LanguageTesting.newLanguage("foo"); - private static final Language BAR_LANGUAGE = LanguageTesting.newLanguage("bar"); - - private System2 system2 = new AlwaysIncreasingSystem2(); - @Rule - public DbTester db = DbTester.create(system2); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public BuiltInQProfileRepositoryRule builtInQProfileRepositoryRule = new BuiltInQProfileRepositoryRule(); - @Rule - public LogTester logTester = new LogTester(); - - private DbClient dbClient = db.getDbClient(); - private DummyBuiltInQProfileInsert insert = new DummyBuiltInQProfileInsert(); - private DummyBuiltInQProfileUpdate update = new DummyBuiltInQProfileUpdate(); - private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, insert, update, mock(BuiltInQualityProfilesUpdateListener.class), system2); - - @Test - public void start_fails_if_BuiltInQProfileRepository_has_not_been_initialized() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("initialize must be called first"); - - underTest.start(); - } - - @Test - public void persist_built_in_profiles_that_are_not_persisted_yet() { - BuiltInQProfile builtInQProfile = builtInQProfileRepositoryRule.add(FOO_LANGUAGE, "Sonar way"); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - assertThat(insert.callLogs).containsExactly(builtInQProfile); - assertThat(update.callLogs).isEmpty(); - assertThat(logTester.logs(LoggerLevel.INFO)).contains("Register profile foo/Sonar way"); - } - - @Test - public void dont_persist_built_in_profiles_that_are_already_persisted() { - String name = "doh"; - - BuiltInQProfile persistedBuiltIn = builtInQProfileRepositoryRule.add(FOO_LANGUAGE, name, true); - BuiltInQProfile nonPersistedBuiltIn = builtInQProfileRepositoryRule.add(BAR_LANGUAGE, name, true); - builtInQProfileRepositoryRule.initialize(); - insertRulesProfile(persistedBuiltIn); - - underTest.start(); - - assertThat(insert.callLogs).containsExactly(nonPersistedBuiltIn); - assertThat(update.callLogs).containsExactly(persistedBuiltIn); - } - - @Test - public void rename_custom_outdated_profiles_if_same_name_than_built_in_profile() { - OrganizationDto org1 = db.organizations().insert(org -> org.setKey("org1")); - OrganizationDto org2 = db.organizations().insert(org -> org.setKey("org2")); - - QProfileDto outdatedProfileInOrg1 = db.qualityProfiles().insert(org1, p -> p.setIsBuiltIn(false) - .setLanguage(FOO_LANGUAGE.getKey()).setName("Sonar way")); - QProfileDto outdatedProfileInOrg2 = db.qualityProfiles().insert(org2, p -> p.setIsBuiltIn(false) - .setLanguage(FOO_LANGUAGE.getKey()).setName("Sonar way")); - builtInQProfileRepositoryRule.add(FOO_LANGUAGE, "Sonar way", false); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - assertThat(selectPersistedName(outdatedProfileInOrg1)).isEqualTo("Sonar way (outdated copy)"); - assertThat(selectPersistedName(outdatedProfileInOrg2)).isEqualTo("Sonar way (outdated copy)"); - assertThat(logTester.logs(LoggerLevel.INFO)).contains("Rename Quality profiles [foo/Sonar way] to [Sonar way (outdated copy)] in 2 organizations"); - } - - @Test - public void update_built_in_profile_if_it_already_exists() { - RulesProfileDto ruleProfile = newRuleProfileDto(rp -> rp.setIsBuiltIn(true).setName("Sonar way").setLanguage(FOO_LANGUAGE.getKey())); - db.getDbClient().qualityProfileDao().insert(db.getSession(), ruleProfile); - db.commit(); - - BuiltInQProfile builtIn = builtInQProfileRepositoryRule.add(FOO_LANGUAGE, ruleProfile.getName(), false); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - assertThat(insert.callLogs).isEmpty(); - assertThat(update.callLogs).containsExactly(builtIn); - assertThat(logTester.logs(LoggerLevel.INFO)).contains("Update profile foo/Sonar way"); - } - - @Test - public void update_default_built_in_quality_profile() { - String orgUuid = UuidFactoryFast.getInstance().create(); - - RulesProfileDto ruleProfileWithoutRule = newRuleProfileDto(rp -> rp.setIsBuiltIn(true).setName("Sonar way").setLanguage(FOO_LANGUAGE.getKey())); - RulesProfileDto ruleProfileWithOneRule = newRuleProfileDto(rp -> rp.setIsBuiltIn(true).setName("Sonar way 2").setLanguage(FOO_LANGUAGE.getKey())); - - QProfileDto qProfileWithoutRule = newQualityProfileDto() - .setIsBuiltIn(true) - .setLanguage(FOO_LANGUAGE.getKey()) - .setOrganizationUuid(orgUuid) - .setRulesProfileUuid(ruleProfileWithoutRule.getKee()); - QProfileDto qProfileWithOneRule = newQualityProfileDto() - .setIsBuiltIn(true) - .setLanguage(FOO_LANGUAGE.getKey()) - .setOrganizationUuid(orgUuid) - .setRulesProfileUuid(ruleProfileWithOneRule.getKee()); - - db.qualityProfiles().insert(qProfileWithoutRule, qProfileWithOneRule); - db.qualityProfiles().setAsDefault(qProfileWithoutRule); - - RuleDefinitionDto ruleDefinition = db.rules().insert(); - db.qualityProfiles().activateRule(qProfileWithOneRule, ruleDefinition); - db.commit(); - - builtInQProfileRepositoryRule.add(FOO_LANGUAGE, ruleProfileWithoutRule.getName(), true); - builtInQProfileRepositoryRule.add(FOO_LANGUAGE, ruleProfileWithOneRule.getName(), false); - builtInQProfileRepositoryRule.initialize(); - - underTest.start(); - - logTester.logs(LoggerLevel.INFO).contains( - format("Default built-in quality profile for language [foo] has been updated from [%s] to [%s] since previous default does not have active rules.", - qProfileWithoutRule.getName(), qProfileWithOneRule.getName())); - - assertThat(selectUuidOfDefaultProfile(FOO_LANGUAGE.getKey())) - .isPresent().get() - .isEqualTo(qProfileWithOneRule.getKee()); - } - - private Optional<String> selectUuidOfDefaultProfile(String language) { - return db.select("select qprofile_uuid as \"profileUuid\" " + - " from default_qprofiles " + - " where language='" + language + "'") - .stream() - .findFirst() - .map(m -> (String) m.get("profileUuid")); - } - - private String selectPersistedName(QProfileDto profile) { - return db.qualityProfiles().selectByUuid(profile.getKee()).get().getName(); - } - - private void insertRulesProfile(BuiltInQProfile builtIn) { - RulesProfileDto dto = newRuleProfileDto(rp -> rp - .setIsBuiltIn(true) - .setLanguage(builtIn.getLanguage()) - .setName(builtIn.getName())); - dbClient.qualityProfileDao().insert(db.getSession(), dto); - db.commit(); - } - - - - private static class DummyBuiltInQProfileInsert implements BuiltInQProfileInsert { - private final List<BuiltInQProfile> callLogs = new ArrayList<>(); - - @Override - public void create(DbSession dbSession, DbSession batchDbSession, BuiltInQProfile builtIn) { - callLogs.add(builtIn); - } - } - - private static class DummyBuiltInQProfileUpdate implements BuiltInQProfileUpdate { - private final List<BuiltInQProfile> callLogs = new ArrayList<>(); - - @Override - public List<ActiveRuleChange> update(DbSession dbSession, BuiltInQProfile builtIn, RulesProfileDto ruleProfile) { - callLogs.add(builtIn); - return Collections.emptyList(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java deleted file mode 100644 index a557963cee6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java +++ /dev/null @@ -1,1202 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.rule; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleScope; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; -import org.sonar.api.server.debt.DebtRemediationFunction; -import org.sonar.api.server.rule.RulesDefinition; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.rule.DeprecatedRuleKeyDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleDto.Scope; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.rule.RuleRepositoryDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.es.SearchIdResult; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.organization.OrganizationFlags; -import org.sonar.server.organization.TestOrganizationFlags; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.qualityprofile.QProfileRules; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.rule.index.RuleIndexDefinition; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.rule.index.RuleQuery; - -import static com.google.common.collect.Sets.newHashSet; -import static java.lang.String.valueOf; -import static java.util.Collections.singletonList; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.api.rule.RuleStatus.READY; -import static org.sonar.api.rule.RuleStatus.REMOVED; -import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.api.rule.Severity.INFO; -import static org.sonar.api.server.rule.RulesDefinition.NewRepository; -import static org.sonar.api.server.rule.RulesDefinition.NewRule; - -@RunWith(DataProviderRunner.class) -public class RegisterRulesTest { - - private static final String FAKE_PLUGIN_KEY = "unittest"; - private static final Date DATE1 = DateUtils.parseDateTime("2014-01-01T19:10:03+0100"); - private static final Date DATE2 = DateUtils.parseDateTime("2014-02-01T12:10:03+0100"); - private static final Date DATE3 = DateUtils.parseDateTime("2014-03-01T12:10:03+0100"); - - private static final RuleKey EXTERNAL_RULE_KEY1 = RuleKey.of("external_eslint", "rule1"); - private static final RuleKey EXTERNAL_HOTSPOT_RULE_KEY = RuleKey.of("external_eslint", "hotspot"); - - private static final RuleKey RULE_KEY1 = RuleKey.of("fake", "rule1"); - private static final RuleKey RULE_KEY2 = RuleKey.of("fake", "rule2"); - private static final RuleKey RULE_KEY3 = RuleKey.of("fake", "rule3"); - private static final RuleKey HOTSPOT_RULE_KEY = RuleKey.of("fake", "hotspot"); - - private System2 system = mock(System2.class); - - @org.junit.Rule - public ExpectedException expectedException = ExpectedException.none(); - @org.junit.Rule - public DbTester db = DbTester.create(system); - @org.junit.Rule - public EsTester es = EsTester.create(); - @org.junit.Rule - public LogTester logTester = new LogTester(); - - private QProfileRules qProfileRules = mock(QProfileRules.class); - private WebServerRuleFinder webServerRuleFinder = mock(WebServerRuleFinder.class); - private DbClient dbClient = db.getDbClient(); - private RuleIndexer ruleIndexer; - private ActiveRuleIndexer activeRuleIndexer; - private RuleIndex ruleIndex; - private OrganizationDto defaultOrganization; - private OrganizationFlags organizationFlags = TestOrganizationFlags.standalone(); - private UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @Before - public void before() { - when(system.now()).thenReturn(DATE1.getTime()); - ruleIndexer = new RuleIndexer(es.client(), dbClient); - ruleIndex = new RuleIndex(es.client(), system); - activeRuleIndexer = new ActiveRuleIndexer(dbClient, es.client()); - defaultOrganization = db.getDefaultOrganization(); - } - - @Test - public void insert_new_rules() { - execute(new FakeRepositoryV1()); - - // verify db - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(3); - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), db.getDefaultOrganization(), RULE_KEY1); - assertThat(rule1.getName()).isEqualTo("One"); - assertThat(rule1.getDescription()).isEqualTo("Description of One"); - assertThat(rule1.getSeverityString()).isEqualTo(BLOCKER); - assertThat(rule1.getTags()).isEmpty(); - assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3"); - assertThat(rule1.getConfigKey()).isEqualTo("config1"); - assertThat(rule1.getStatus()).isEqualTo(RuleStatus.BETA); - assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getScope()).isEqualTo(Scope.ALL); - assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name()); - assertThat(rule1.getDefRemediationGapMultiplier()).isEqualTo("5d"); - assertThat(rule1.getDefRemediationBaseEffort()).isEqualTo("10h"); - assertThat(rule1.getType()).isEqualTo(RuleType.CODE_SMELL.getDbConstant()); - assertThat(rule1.getPluginKey()).isEqualTo(FAKE_PLUGIN_KEY); - assertThat(rule1.isExternal()).isFalse(); - assertThat(rule1.isAdHoc()).isFalse(); - - RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), db.getDefaultOrganization(), HOTSPOT_RULE_KEY); - assertThat(hotspotRule.getName()).isEqualTo("Hotspot"); - assertThat(hotspotRule.getDescription()).isEqualTo("Minimal hotspot"); - assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime()); - assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant()); - assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3"); - - List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(db.getSession(), RULE_KEY1); - assertThat(params).hasSize(2); - RuleParamDto param = getParam(params, "param1"); - assertThat(param.getDescription()).isEqualTo("parameter one"); - assertThat(param.getDefaultValue()).isEqualTo("default1"); - - // verify index - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), db.getDefaultOrganization(), RULE_KEY2); - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule2.getId(), hotspotRule.getId()); - - // verify repositories - assertThat(dbClient.ruleRepositoryDao().selectAll(db.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake"); - } - - @Test - public void insert_new_external_rule() { - execute(new ExternalRuleRepository()); - - // verify db - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(2); - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), db.getDefaultOrganization(), EXTERNAL_RULE_KEY1); - assertThat(rule1.getName()).isEqualTo("One"); - assertThat(rule1.getDescription()).isEqualTo("Description of One"); - assertThat(rule1.getSeverityString()).isEqualTo(BLOCKER); - assertThat(rule1.getTags()).isEmpty(); - assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3"); - assertThat(rule1.getConfigKey()).isEqualTo("config1"); - assertThat(rule1.getStatus()).isEqualTo(RuleStatus.BETA); - assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getScope()).isEqualTo(Scope.ALL); - assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getDefRemediationFunction()).isNull(); - assertThat(rule1.getDefRemediationGapMultiplier()).isNull(); - assertThat(rule1.getDefRemediationBaseEffort()).isNull(); - assertThat(rule1.getType()).isEqualTo(RuleType.CODE_SMELL.getDbConstant()); - assertThat(rule1.getPluginKey()).isEqualTo(FAKE_PLUGIN_KEY); - assertThat(rule1.isExternal()).isTrue(); - assertThat(rule1.isAdHoc()).isFalse(); - - RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), db.getDefaultOrganization(), EXTERNAL_HOTSPOT_RULE_KEY); - assertThat(hotspotRule.getName()).isEqualTo("Hotspot"); - assertThat(hotspotRule.getDescription()).isEqualTo("Minimal hotspot"); - assertThat(hotspotRule.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(hotspotRule.getUpdatedAt()).isEqualTo(DATE1.getTime()); - assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant()); - assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3"); - } - - @Test - public void insert_then_remove_rule() { - String ruleKey = randomAlphanumeric(5); - - // register one rule - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule(ruleKey) - .setName(randomAlphanumeric(5)) - .setHtmlDescription(randomAlphanumeric(20)); - repo.done(); - }); - - // verify db - List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(db.getSession()); - assertThat(rules) - .extracting(RuleDefinitionDto::getKey) - .extracting(RuleKey::rule) - .containsExactly(ruleKey); - RuleDefinitionDto rule = rules.iterator().next(); - - // verify index - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()) - .containsExactly(rule.getId()); - - // register no rule - execute(context -> context.createRepository("fake", "java").done()); - - // verify db - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())) - .extracting(RuleDefinitionDto::getKey) - .extracting(RuleKey::rule) - .containsExactly(ruleKey); - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())) - .extracting(RuleDefinitionDto::getStatus) - .containsExactly(REMOVED); - - // verify index - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()) - .isEmpty(); - } - - @Test - public void mass_insert_then_remove_rule() { - int numberOfRules = 5000; - - // register many rules - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - IntStream.range(0, numberOfRules) - .mapToObj(i -> "rule-" + i) - .forEach(ruleKey -> repo.createRule(ruleKey) - .setName(randomAlphanumeric(20)) - .setHtmlDescription(randomAlphanumeric(20))); - repo.done(); - }); - - // verify db - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())) - .hasSize(numberOfRules) - .extracting(RuleDefinitionDto::getStatus) - .containsOnly(READY); - - // verify index - assertThat(es.countDocuments(RuleIndexDefinition.TYPE_RULE)).isEqualTo(numberOfRules); - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()) - .isNotEmpty(); - - // register no rule - execute(context -> context.createRepository("fake", "java").done()); - - // verify db - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())) - .hasSize(numberOfRules) - .extracting(RuleDefinitionDto::getStatus) - .containsOnly(REMOVED); - - // verify index (documents are still in the index, but all are removed) - assertThat(es.countDocuments(RuleIndexDefinition.TYPE_RULE)).isEqualTo(numberOfRules); - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()) - .isEmpty(); - } - - @Test - public void delete_repositories_that_have_been_uninstalled() { - RuleRepositoryDto repository = new RuleRepositoryDto("findbugs", "java", "Findbugs"); - DbSession dbSession = db.getSession(); - db.getDbClient().ruleRepositoryDao().insertOrUpdate(dbSession, singletonList(repository)); - dbSession.commit(); - - execute(new FakeRepositoryV1()); - - assertThat(db.getDbClient().ruleRepositoryDao().selectAll(dbSession)).extracting(RuleRepositoryDto::getKey).containsOnly("fake"); - } - - @Test - public void update_and_remove_rules_on_changes() { - execute(new FakeRepositoryV1()); - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(3); - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY2); - RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, HOTSPOT_RULE_KEY); - assertThat(es.getIds(RuleIndexDefinition.TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()), valueOf(hotspotRule.getId())); - - // user adds tags and sets markdown note - rule1.setTags(newHashSet("usertag1", "usertag2")); - rule1.setNoteData("user *note*"); - rule1.setNoteUserUuid("marius"); - dbClient.ruleDao().insertOrUpdate(db.getSession(), rule1.getMetadata()); - db.getSession().commit(); - - when(system.now()).thenReturn(DATE2.getTime()); - execute(new FakeRepositoryV2()); - - // rule1 has been updated - rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule1.getName()).isEqualTo("One v2"); - assertThat(rule1.getDescription()).isEqualTo("Description of One v2"); - assertThat(rule1.getSeverityString()).isEqualTo(INFO); - assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2"); - assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4"); - assertThat(rule1.getConfigKey()).isEqualTo("config1 v2"); - assertThat(rule1.getNoteData()).isEqualTo("user *note*"); - assertThat(rule1.getNoteUserUuid()).isEqualTo("marius"); - assertThat(rule1.getStatus()).isEqualTo(READY); - assertThat(rule1.getType()).isEqualTo(RuleType.BUG.getDbConstant()); - assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2.getTime()); - - List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(db.getSession(), RULE_KEY1); - assertThat(params).hasSize(2); - RuleParamDto param = getParam(params, "param1"); - assertThat(param.getDescription()).isEqualTo("parameter one v2"); - assertThat(param.getDefaultValue()).isEqualTo("default1 v2"); - - // rule2 has been removed -> status set to REMOVED but db row is not deleted - rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY2); - assertThat(rule2.getStatus()).isEqualTo(REMOVED); - assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime()); - - // rule3 has been created - RuleDto rule3 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY3); - assertThat(rule3).isNotNull(); - assertThat(rule3.getStatus()).isEqualTo(READY); - - // verify index - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId()); - - // verify repositories - assertThat(dbClient.ruleRepositoryDao().selectAll(db.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake"); - } - - @Test - public void add_new_tag() { - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One") - .setTags("tag1"); - repo.done(); - }); - - OrganizationDto defaultOrganization = db.getDefaultOrganization(); - RuleDto rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getSystemTags()).containsOnly("tag1"); - - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One") - .setTags("tag1", "tag2"); - repo.done(); - }); - - rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getSystemTags()).containsOnly("tag1", "tag2"); - } - - @Test - public void add_new_security_standards() { - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One") - .addOwaspTop10(RulesDefinition.OwaspTop10.A1) - .addCwe(123); - repo.done(); - }); - - OrganizationDto defaultOrganization = db.getDefaultOrganization(); - RuleDto rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getSecurityStandards()).containsOnly("cwe:123", "owaspTop10:a1"); - - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One") - .addOwaspTop10(RulesDefinition.OwaspTop10.A1, RulesDefinition.OwaspTop10.A3) - .addCwe(1, 123, 863); - repo.done(); - }); - - rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getSecurityStandards()).containsOnly("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3"); - } - - @Test - public void update_only_rule_name() { - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule") - .setName("Name1") - .setHtmlDescription("Description"); - repo.done(); - }); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule") - .setName("Name2") - .setHtmlDescription("Description"); - repo.done(); - }); - - // rule1 has been updated - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of("fake", "rule")); - assertThat(rule1.getName()).isEqualTo("Name2"); - assertThat(rule1.getDescription()).isEqualTo("Description"); - - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions()).getTotal()).isEqualTo(1); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()).getTotal()).isEqualTo(0); - } - - @Test - public void update_if_rule_key_renamed_and_deprecated_key_declared() { - String ruleKey1 = "rule1"; - String ruleKey2 = "rule2"; - String repository = "fake"; - - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository, "java"); - repo.createRule(ruleKey1) - .setName("Name1") - .setHtmlDescription("Description"); - repo.done(); - }); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository, ruleKey1)); - SearchIdResult<Integer> searchRule1 = ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()); - assertThat(searchRule1.getIds()).containsOnly(rule1.getId()); - assertThat(searchRule1.getTotal()).isEqualTo(1); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository, "java"); - repo.createRule(ruleKey2) - .setName("Name2") - .setHtmlDescription("Description") - .addDeprecatedRuleKey(repository, ruleKey1); - repo.done(); - }); - - // rule2 is actually rule1 - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository, ruleKey2)); - assertThat(rule2.getId()).isEqualTo(rule1.getId()); - assertThat(rule2.getName()).isEqualTo("Name2"); - assertThat(rule2.getDescription()).isEqualTo(rule1.getDescription()); - - SearchIdResult<Integer> searchRule2 = ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions()); - assertThat(searchRule2.getIds()).containsOnly(rule2.getId()); - assertThat(searchRule2.getTotal()).isEqualTo(1); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()).getTotal()).isEqualTo(0); - } - - @Test - public void update_if_repository_changed_and_deprecated_key_declared() { - String ruleKey = "rule"; - String repository1 = "fake1"; - String repository2 = "fake2"; - - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository1, "java"); - repo.createRule(ruleKey) - .setName("Name1") - .setHtmlDescription("Description"); - repo.done(); - }); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository1, ruleKey)); - SearchIdResult<Integer> searchRule1 = ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()); - assertThat(searchRule1.getIds()).containsOnly(rule1.getId()); - assertThat(searchRule1.getTotal()).isEqualTo(1); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository2, "java"); - repo.createRule(ruleKey) - .setName("Name2") - .setHtmlDescription("Description") - .addDeprecatedRuleKey(repository1, ruleKey); - repo.done(); - }); - - // rule2 is actually rule1 - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository2, ruleKey)); - assertThat(rule2.getId()).isEqualTo(rule1.getId()); - assertThat(rule2.getName()).isEqualTo("Name2"); - assertThat(rule2.getDescription()).isEqualTo(rule1.getDescription()); - - SearchIdResult<Integer> searchRule2 = ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions()); - assertThat(searchRule2.getIds()).containsOnly(rule2.getId()); - assertThat(searchRule2.getTotal()).isEqualTo(1); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()).getTotal()).isEqualTo(0); - } - - @Test - @UseDataProvider("allRenamingCases") - public void update_if_only_renamed_and_deprecated_key_declared(String ruleKey1, String repo1, String ruleKey2, String repo2) { - String name = "Name1"; - String description = "Description"; - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repo1, "java"); - repo.createRule(ruleKey1) - .setName(name) - .setHtmlDescription(description); - repo.done(); - }); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repo1, ruleKey1)); - assertThat(ruleIndex.search(new RuleQuery().setQueryText(name), new SearchOptions()).getIds()) - .containsOnly(rule1.getId()); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repo2, "java"); - repo.createRule(ruleKey2) - .setName(name) - .setHtmlDescription(description) - .addDeprecatedRuleKey(repo1, ruleKey1); - repo.done(); - }); - - // rule2 is actually rule1 - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repo2, ruleKey2)); - assertThat(rule2.getId()).isEqualTo(rule1.getId()); - assertThat(rule2.getName()).isEqualTo(rule1.getName()); - assertThat(rule2.getDescription()).isEqualTo(rule1.getDescription()); - - assertThat(ruleIndex.search(new RuleQuery().setQueryText(name), new SearchOptions()).getIds()) - .containsOnly(rule2.getId()); - } - - @DataProvider - public static Object[][] allRenamingCases() { - return new Object[][] { - {"repo1", "rule1", "repo1", "rule2"}, - {"repo1", "rule1", "repo2", "rule1"}, - {"repo1", "rule1", "repo2", "rule2"}, - }; - } - - @Test - public void update_if_repository_and_key_changed_and_deprecated_key_declared_among_others() { - String ruleKey1 = "rule1"; - String ruleKey2 = "rule2"; - String repository1 = "fake1"; - String repository2 = "fake2"; - - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository1, "java"); - repo.createRule(ruleKey1) - .setName("Name1") - .setHtmlDescription("Description"); - repo.done(); - }); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository1, ruleKey1)); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name1"), new SearchOptions()).getIds()) - .containsOnly(rule1.getId()); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - RulesDefinition.NewRepository repo = context.createRepository(repository2, "java"); - repo.createRule(ruleKey2) - .setName("Name2") - .setHtmlDescription("Description") - .addDeprecatedRuleKey("foo", "bar") - .addDeprecatedRuleKey(repository1, ruleKey1) - .addDeprecatedRuleKey("some", "noise"); - repo.done(); - }); - - // rule2 is actually rule1 - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of(repository2, ruleKey2)); - assertThat(rule2.getId()).isEqualTo(rule1.getId()); - - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Name2"), new SearchOptions()).getIds()) - .containsOnly(rule1.getId()); - } - - @Test - public void update_only_rule_description() { - when(system.now()).thenReturn(DATE1.getTime()); - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule") - .setName("Name") - .setHtmlDescription("Desc1"); - repo.done(); - }); - - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule") - .setName("Name") - .setHtmlDescription("Desc2"); - repo.done(); - }); - - // rule1 has been updated - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RuleKey.of("fake", "rule")); - assertThat(rule1.getName()).isEqualTo("Name"); - assertThat(rule1.getDescription()).isEqualTo("Desc2"); - - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Desc2"), new SearchOptions()).getTotal()).isEqualTo(1); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Desc1"), new SearchOptions()).getTotal()).isEqualTo(0); - } - - @Test - public void rule_previously_created_as_adhoc_becomes_none_adhoc() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setRepositoryKey("external_fake").setIsExternal(true).setIsAdHoc(true)); - when(system.now()).thenReturn(DATE2.getTime()); - execute((RulesDefinition) context -> { - NewRepository repo = context.createExternalRepository("fake", rule.getLanguage()); - repo.createRule(rule.getRuleKey()) - .setName(rule.getName()) - .setHtmlDescription(rule.getDescription()); - repo.done(); - }); - - RuleDto reloaded = dbClient.ruleDao().selectByKey(db.getSession(), defaultOrganization.getUuid(), rule.getKey()).get(); - assertThat(reloaded.isAdHoc()).isFalse(); - } - - @Test - public void remove_no_more_defined_external_rule() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setRepositoryKey("external_fake") - .setStatus(READY) - .setIsExternal(true) - .setIsAdHoc(false)); - - execute(); - - RuleDto reloaded = dbClient.ruleDao().selectByKey(db.getSession(), defaultOrganization.getUuid(), rule.getKey()).get(); - assertThat(reloaded.getStatus()).isEqualTo(REMOVED); - } - - @Test - public void do_not_remove_no_more_defined_ad_hoc_rule() { - RuleDefinitionDto rule = db.rules().insert(r -> r.setRepositoryKey("external_fake") - .setStatus(READY) - .setIsExternal(true) - .setIsAdHoc(true)); - - execute(); - - RuleDto reloaded = dbClient.ruleDao().selectByKey(db.getSession(), defaultOrganization.getUuid(), rule.getKey()).get(); - assertThat(reloaded.getStatus()).isEqualTo(READY); - } - - @Test - public void disable_then_enable_rule() { - // Install rule - when(system.now()).thenReturn(DATE1.getTime()); - execute(new FakeRepositoryV1()); - - // Uninstall rule - when(system.now()).thenReturn(DATE2.getTime()); - execute(); - - RuleDto rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getStatus()).isEqualTo(REMOVED); - assertThat(ruleIndex.search(new RuleQuery().setKey(RULE_KEY1.toString()), new SearchOptions()).getTotal()).isEqualTo(0); - - // Re-install rule - when(system.now()).thenReturn(DATE3.getTime()); - execute(new FakeRepositoryV1()); - - rule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule.getStatus()).isEqualTo(RuleStatus.BETA); - assertThat(ruleIndex.search(new RuleQuery().setKey(RULE_KEY1.toString()), new SearchOptions()).getTotal()).isEqualTo(1); - } - - @Test - public void do_not_update_rules_when_no_changes() { - execute(new FakeRepositoryV1()); - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(3); - - when(system.now()).thenReturn(DATE2.getTime()); - execute(new FakeRepositoryV1()); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); - assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1.getTime()); - } - - @Test - public void do_not_update_already_removed_rules() { - execute(new FakeRepositoryV1()); - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(3); - - RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY1); - RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY2); - RuleDto hotspotRule = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, HOTSPOT_RULE_KEY); - assertThat(es.getIds(RuleIndexDefinition.TYPE_RULE)).containsOnly(valueOf(rule1.getId()), valueOf(rule2.getId()), valueOf(hotspotRule.getId())); - - assertThat(rule2.getStatus()).isEqualTo(READY); - - when(system.now()).thenReturn(DATE2.getTime()); - execute(new FakeRepositoryV2()); - - // On MySQL, need to update a rule otherwise rule2 will be seen as READY, but why ??? - dbClient.ruleDao().update(db.getSession(), rule1.getDefinition()); - db.getSession().commit(); - - // rule2 is removed - rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY2); - RuleDto rule3 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY3); - assertThat(rule2.getStatus()).isEqualTo(REMOVED); - - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId()); - - when(system.now()).thenReturn(DATE3.getTime()); - execute(new FakeRepositoryV2()); - db.getSession().commit(); - - // -> rule2 is still removed, but not update at DATE3 - rule2 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), defaultOrganization, RULE_KEY2); - assertThat(rule2.getStatus()).isEqualTo(REMOVED); - assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime()); - - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule1.getId(), rule3.getId()); - } - - @Test - public void mass_insert() { - execute(new BigRepository()); - assertThat(db.countRowsOfTable("rules")).isEqualTo(BigRepository.SIZE); - assertThat(db.countRowsOfTable("rules_parameters")).isEqualTo(BigRepository.SIZE * 20); - assertThat(es.getIds(RuleIndexDefinition.TYPE_RULE)).hasSize(BigRepository.SIZE); - } - - @Test - public void manage_repository_extensions() { - execute(new FindbugsRepository(), new FbContribRepository()); - List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(db.getSession()); - assertThat(rules).hasSize(2); - for (RuleDefinitionDto rule : rules) { - assertThat(rule.getRepositoryKey()).isEqualTo("findbugs"); - } - } - - @Test - public void remove_system_tags_when_plugin_does_not_provide_any() { - // Rule already exists in DB, with some system tags - dbClient.ruleDao().insert(db.getSession(), new RuleDefinitionDto() - .setRuleKey("rule1") - .setRepositoryKey("findbugs") - .setName("Rule One") - .setScope(Scope.ALL) - .setDescription("Rule one description") - .setDescriptionFormat(RuleDto.Format.HTML) - .setSystemTags(newHashSet("tag1", "tag2"))); - db.getSession().commit(); - - // Synchronize rule without tag - execute(new FindbugsRepository()); - - List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(db.getSession()); - assertThat(rules).hasSize(1); - RuleDefinitionDto result = rules.get(0); - assertThat(result.getKey()).isEqualTo(RuleKey.of("findbugs", "rule1")); - assertThat(result.getSystemTags()).isEmpty(); - } - - @Test - public void ignore_template_rules_if_organizations_are_enabled() { - organizationFlags.enable(db.getSession()); - execute(new RepositoryWithOneTemplateRule()); - - List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(db.getSession()); - assertThat(rules).hasSize(0); - } - - @Test - public void log_ignored_template_rules_if_organizations_are_enabled() { - organizationFlags.enable(db.getSession()); - execute(new RepositoryWithOneTemplateRule()); - - assertThat(logTester.logs(LoggerLevel.INFO)).contains("Template rule test:rule1 will not be imported, because organizations are enabled."); - } - - @Test - public void rules_that_deprecate_previous_rule_must_be_recorded() { - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - repo.done(); - }); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA) - .addDeprecatedRuleKey("fake", "rule1") - .addDeprecatedRuleKey("fake", "rule2"); - repo.done(); - }); - - List<RuleDefinitionDto> rules = dbClient.ruleDao().selectAllDefinitions(db.getSession()); - Set<DeprecatedRuleKeyDto> deprecatedRuleKeys = dbClient.ruleDao().selectAllDeprecatedRuleKeys(db.getSession()); - assertThat(rules).hasSize(1); - assertThat(deprecatedRuleKeys).hasSize(2); - } - - @Test - public void rules_that_remove_deprecated_key_must_remove_records() { - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("rule1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - repo.done(); - }); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA) - .addDeprecatedRuleKey("fake", "rule1") - .addDeprecatedRuleKey("fake", "rule2"); - repo.done(); - }); - - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(1); - Set<DeprecatedRuleKeyDto> deprecatedRuleKeys = dbClient.ruleDao().selectAllDeprecatedRuleKeys(db.getSession()); - assertThat(deprecatedRuleKeys).hasSize(2); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - repo.done(); - }); - - assertThat(dbClient.ruleDao().selectAllDefinitions(db.getSession())).hasSize(1); - deprecatedRuleKeys = dbClient.ruleDao().selectAllDeprecatedRuleKeys(db.getSession()); - assertThat(deprecatedRuleKeys).hasSize(0); - } - - @Test - public void declaring_two_rules_with_same_deprecated_RuleKey_should_throw_ISE() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("The following deprecated rule keys are declared at least twice [fake:old]"); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .addDeprecatedRuleKey("fake", "old") - .setStatus(RuleStatus.BETA); - repo.createRule("newKey2") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .addDeprecatedRuleKey("fake", "old") - .setStatus(RuleStatus.BETA); - repo.done(); - }); - } - - @Test - public void declaring_a_rule_with_a_deprecated_RuleKey_still_used_should_throw_ISE() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("The following rule keys are declared both as deprecated and used key [fake:newKey1]"); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - - repo.createRule("newKey2") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .addDeprecatedRuleKey("fake", "newKey1") - .setStatus(RuleStatus.BETA); - repo.done(); - }); - } - - @Test - public void updating_the_deprecated_to_a_new_ruleKey_should_throw_an_ISE() { - // On this new rule add a deprecated key - execute(context -> createRule(context, "javascript", "javascript", "s103", - r -> r.addDeprecatedRuleKey("javascript", "linelength"))); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("An incorrect state of deprecated rule keys has been detected.\n " + - "The deprecated rule key [javascript:linelength] was previously deprecated by [javascript:s103]. [javascript:s103] should be a deprecated key of [sonarjs:s103],"); - - // This rule should have been moved to another repository - execute(context -> createRule(context, "javascript", "sonarjs", "s103", - r -> r.addDeprecatedRuleKey("javascript", "linelength"))); - } - - @Test - public void declaring_a_rule_with_an_existing_RuleKey_still_used_should_throw_IAE() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The rule 'newKey1' of repository 'fake' is declared several times"); - - execute(context -> { - NewRepository repo = context.createRepository("fake", "java"); - repo.createRule("newKey1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - - repo.createRule("newKey1") - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) - .addDeprecatedRuleKey("fake", "newKey1") - .setStatus(RuleStatus.BETA); - repo.done(); - }); - } - - private void execute(RulesDefinition... defs) { - ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); - when(pluginRepository.getPluginKey(any(RulesDefinition.class))).thenReturn(FAKE_PLUGIN_KEY); - RuleDefinitionsLoader loader = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), mock(CommonRuleDefinitionsImpl.class), pluginRepository, - defs); - Languages languages = mock(Languages.class); - when(languages.get(any())).thenReturn(mock(Language.class)); - reset(webServerRuleFinder); - - RegisterRules task = new RegisterRules(loader, qProfileRules, dbClient, ruleIndexer, activeRuleIndexer, - languages, system, organizationFlags, webServerRuleFinder, uuidFactory); - task.start(); - // Execute a commit to refresh session state as the task is using its own session - db.getSession().commit(); - - verify(webServerRuleFinder).startCaching(); - } - - @SafeVarargs - private final void createRule(RulesDefinition.Context context, String language, String repositoryKey, String ruleKey, Consumer<NewRule>... consumers) { - NewRepository repo = context.createRepository(repositoryKey, language); - NewRule newRule = repo.createRule(ruleKey) - .setName(ruleKey) - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - - Arrays.stream(consumers).forEach(c -> c.accept(newRule)); - repo.done(); - } - - private RuleParamDto getParam(List<RuleParamDto> params, String key) { - for (RuleParamDto param : params) { - if (param.getName().equals(key)) { - return param; - } - } - return null; - } - - static class FakeRepositoryV1 implements RulesDefinition { - @Override - public void define(Context context) { - NewRepository repo = context.createRepository("fake", "java"); - NewRule rule1 = repo.createRule(RULE_KEY1.rule()) - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setScope(RuleScope.ALL) - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA) - .setGapDescription("squid.S115.effortToFix"); - rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("5d", "10h")); - - rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1"); - rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default2"); - - repo.createRule(HOTSPOT_RULE_KEY.rule()) - .setName("Hotspot") - .setHtmlDescription("Minimal hotspot") - .setType(RuleType.SECURITY_HOTSPOT) - .addOwaspTop10(OwaspTop10.A1, OwaspTop10.A3) - .addCwe(1, 123, 863); - - repo.createRule(RULE_KEY2.rule()) - .setName("Two") - .setHtmlDescription("Minimal rule"); - repo.done(); - } - } - - /** - * FakeRepositoryV1 with some changes - */ - static class FakeRepositoryV2 implements RulesDefinition { - @Override - public void define(Context context) { - NewRepository repo = context.createRepository("fake", "java"); - - // almost all the attributes of rule1 are changed - NewRule rule1 = repo.createRule(RULE_KEY1.rule()) - .setName("One v2") - .setHtmlDescription("Description of One v2") - .setSeverity(INFO) - .setInternalKey("config1 v2") - // tag2 and tag3 removed, tag4 added - .setTags("tag1", "tag4") - .setType(RuleType.BUG) - .setStatus(READY) - .setGapDescription("squid.S115.effortToFix.v2"); - rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("6d", "2h")); - rule1.createParam("param1").setDescription("parameter one v2").setDefaultValue("default1 v2"); - rule1.createParam("param2").setDescription("parameter two v2").setDefaultValue("default2 v2"); - - // rule2 is dropped, rule3 is new - repo.createRule(RULE_KEY3.rule()) - .setName("Three") - .setHtmlDescription("Rule Three"); - - repo.done(); - } - } - - static class ExternalRuleRepository implements RulesDefinition { - @Override - public void define(Context context) { - NewRepository repo = context.createExternalRepository("eslint", "js"); - repo.createRule(RULE_KEY1.rule()) - .setName("One") - .setHtmlDescription("Description of One") - .setSeverity(BLOCKER) - .setInternalKey("config1") - .setTags("tag1", "tag2", "tag3") - .setScope(RuleScope.ALL) - .setType(RuleType.CODE_SMELL) - .setStatus(RuleStatus.BETA); - - repo.createRule(EXTERNAL_HOTSPOT_RULE_KEY.rule()) - .setName("Hotspot") - .setHtmlDescription("Minimal hotspot") - .setType(RuleType.SECURITY_HOTSPOT) - .addOwaspTop10(OwaspTop10.A1, OwaspTop10.A3) - .addCwe(1, 123, 863); - - repo.done(); - } - } - - static class BigRepository implements RulesDefinition { - static final int SIZE = 500; - - @Override - public void define(Context context) { - NewRepository repo = context.createRepository("big", "java"); - for (int i = 0; i < SIZE; i++) { - NewRule rule = repo.createRule("rule" + i) - .setName("name of " + i) - .setHtmlDescription("description of " + i); - for (int j = 0; j < 20; j++) { - rule.createParam("param" + j); - } - - } - repo.done(); - } - } - - static class FindbugsRepository implements RulesDefinition { - @Override - public void define(Context context) { - NewRepository repo = context.createRepository("findbugs", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One"); - repo.done(); - } - } - - static class FbContribRepository implements RulesDefinition { - @Override - public void define(Context context) { - NewExtendedRepository repo = context.extendRepository("findbugs", "java"); - repo.createRule("rule2") - .setName("Rule Two") - .setHtmlDescription("Description of Rule Two"); - repo.done(); - } - } - - static class RepositoryWithOneTemplateRule implements RulesDefinition { - @Override - public void define(Context context) { - NewRepository repo = context.createRepository("test", "java"); - repo.createRule("rule1") - .setName("Rule One") - .setHtmlDescription("Description of Rule One") - .setTemplate(true); - repo.done(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorTest.java deleted file mode 100644 index 45bef460214..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorTest.java +++ /dev/null @@ -1,519 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.rule; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; -import java.util.Date; -import java.util.List; -import org.assertj.core.api.Fail; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.server.debt.DebtRemediationFunction; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleDto.Format; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.rule.RuleTesting; -import org.sonar.server.es.EsTester; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.rule.index.RuleQuery; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.sonar.db.rule.RuleTesting.newRule; -import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations; - -public class RuleCreatorTest { - - private System2 system2 = mock(System2.class); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester dbTester = DbTester.create(system2); - - @Rule - public EsTester es = EsTester.create(); - - private RuleIndex ruleIndex = new RuleIndex(es.client(), system2); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), dbTester.getDbClient()); - private DbSession dbSession = dbTester.getSession(); - - private RuleCreator underTest = new RuleCreator(system2, new RuleIndexer(es.client(), dbTester.getDbClient()), dbTester.getDbClient(), newFullTypeValidations(), - TestDefaultOrganizationProvider.from(dbTester)); - - @Test - public void create_custom_rule() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - // Create custom rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setMarkdownDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - RuleKey customRuleKey = underTest.create(dbSession, newRule); - - RuleDto rule = dbTester.getDbClient().ruleDao().selectOrFailByKey(dbSession, dbTester.getDefaultOrganization(), customRuleKey); - assertThat(rule).isNotNull(); - assertThat(rule.getKey()).isEqualTo(RuleKey.of("java", "CUSTOM_RULE")); - assertThat(rule.getPluginKey()).isEqualTo("sonarjava"); - assertThat(rule.getTemplateId()).isEqualTo(templateRule.getId()); - assertThat(rule.getName()).isEqualTo("My custom"); - assertThat(rule.getDescription()).isEqualTo("Some description"); - assertThat(rule.getSeverityString()).isEqualTo("MAJOR"); - assertThat(rule.getStatus()).isEqualTo(RuleStatus.READY); - assertThat(rule.getLanguage()).isEqualTo("java"); - assertThat(rule.getConfigKey()).isEqualTo("S001"); - assertThat(rule.getDefRemediationFunction()).isEqualTo("LINEAR_OFFSET"); - assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1h"); - assertThat(rule.getDefRemediationBaseEffort()).isEqualTo("5min"); - assertThat(rule.getGapDescription()).isEqualTo("desc"); - assertThat(rule.getTags()).containsOnly("usertag1", "usertag2"); - assertThat(rule.getSystemTags()).containsOnly("tag1", "tag4"); - assertThat(rule.getSecurityStandards()).containsOnly("owaspTop10:a1", "cwe:123"); - assertThat(rule.isExternal()).isFalse(); - assertThat(rule.isAdHoc()).isFalse(); - - List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(1); - - RuleParamDto param = params.get(0); - // From template rule - assertThat(param.getName()).isEqualTo("regex"); - assertThat(param.getDescription()).isEqualTo("Reg ex"); - assertThat(param.getType()).isEqualTo("STRING"); - // From user - assertThat(param.getDefaultValue()).isEqualTo("a.*"); - - assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(rule.getId(), templateRule.getId()); - } - - @Test - public void create_custom_rule_with_empty_parameter_value() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "")); - - RuleKey customRuleKey = underTest.create(dbSession, newRule); - - List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(1); - RuleParamDto param = params.get(0); - assertThat(param.getName()).isEqualTo("regex"); - assertThat(param.getDescription()).isEqualTo("Reg ex"); - assertThat(param.getType()).isEqualTo("STRING"); - assertThat(param.getDefaultValue()).isNull(); - } - - @Test - public void create_custom_rule_with_no_parameter_value() { - // insert template rule - RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam(); - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY); - - RuleKey customRuleKey = underTest.create(dbSession, newRule); - - List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(1); - RuleParamDto param = params.get(0); - assertThat(param.getName()).isEqualTo("myIntegers"); - assertThat(param.getDescription()).isEqualTo("My Integers"); - assertThat(param.getType()).isEqualTo("INTEGER,multiple=true,values=1;2;3"); - assertThat(param.getDefaultValue()).isNull(); - } - - @Test - public void create_custom_rule_with_multiple_parameter_values() { - // insert template rule - RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam(); - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("myIntegers", "1,3")); - - RuleKey customRuleKey = underTest.create(dbSession, newRule); - - List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(1); - RuleParamDto param = params.get(0); - assertThat(param.getName()).isEqualTo("myIntegers"); - assertThat(param.getDescription()).isEqualTo("My Integers"); - assertThat(param.getType()).isEqualTo("INTEGER,multiple=true,values=1;2;3"); - assertThat(param.getDefaultValue()).isEqualTo("1,3"); - } - - @Test - public void fail_to_create_custom_rule_with_invalid_parameter() { - // insert template rule - RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Value 'polop' must be an integer."); - - // Create custom rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setMarkdownDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("myIntegers", "1,polop,2")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_with_invalid_parameters() { - // insert template rule - RuleDefinitionDto templateRule = createTemplateRuleWithTwoIntParams(); - - // Create custom rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setMarkdownDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("first", "polop", "second", "palap")); - try { - underTest.create(dbSession, newRule); - Fail.failBecauseExceptionWasNotThrown(BadRequestException.class); - } catch (BadRequestException badRequest) { - assertThat(badRequest.errors().toString()).contains("palap").contains("polop"); - } - } - - @Test - public void reactivate_custom_rule_if_already_exists_in_removed_status() { - String key = "CUSTOM_RULE"; - - // insert template rule - RuleDto templateRule = createTemplateRule(); - - // insert a removed rule - RuleDto rule = RuleTesting.newCustomRule(templateRule) - .setRuleKey(key) - .setStatus(RuleStatus.REMOVED) - .setName("Old name") - .setDescription("Old description") - .setDescriptionFormat(Format.MARKDOWN) - .setSeverity(Severity.INFO); - dbTester.rules().insert(rule.getDefinition()); - dbTester.rules().insertRuleParam(rule.getDefinition(), param -> param.setDefaultValue("a.*")); - dbSession.commit(); - - // Create custom rule with same key, but with different values - NewCustomRule newRule = NewCustomRule.createForCustomRule(key, templateRule.getKey()) - .setName("New name") - .setMarkdownDescription("New description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "c.*")); - RuleKey customRuleKey = underTest.create(dbSession, newRule); - - RuleDefinitionDto result = dbTester.getDbClient().ruleDao().selectOrFailDefinitionByKey(dbSession, customRuleKey); - assertThat(result.getKey()).isEqualTo(RuleKey.of("java", key)); - assertThat(result.getStatus()).isEqualTo(RuleStatus.READY); - - // These values should be the same than before - assertThat(result.getName()).isEqualTo("Old name"); - assertThat(result.getDescription()).isEqualTo("Old description"); - assertThat(result.getSeverityString()).isEqualTo(Severity.INFO); - - List<RuleParamDto> params = dbTester.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleKey); - assertThat(params).hasSize(1); - assertThat(params.get(0).getDefaultValue()).isEqualTo("a.*"); - } - - @Test - public void generate_reactivation_exception_when_rule_exists_in_removed_status_and_prevent_reactivation_parameter_is_true() { - String key = "CUSTOM_RULE"; - // insert template rule - RuleDto templateRule = createTemplateRule(); - // insert a removed rule - RuleDto rule = RuleTesting.newCustomRule(templateRule) - .setRuleKey(key) - .setStatus(RuleStatus.REMOVED) - .setName("Old name") - .setDescription("Old description") - .setSeverity(Severity.INFO); - dbTester.rules().insert(rule.getDefinition()); - dbTester.rules().insertRuleParam(rule.getDefinition(), param -> param.setDefaultValue("a.*")); - dbSession.commit(); - - // Create custom rule with same key, but with different values - NewCustomRule newRule = NewCustomRule.createForCustomRule(key, templateRule.getKey()) - .setName("New name") - .setHtmlDescription("New description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "c.*")) - .setPreventReactivation(true); - - try { - underTest.create(dbSession, newRule); - fail(); - } catch (Exception e) { - assertThat(e).isInstanceOf(ReactivationException.class); - ReactivationException reactivationException = (ReactivationException) e; - assertThat(reactivationException.ruleKey()).isEqualTo(rule.getKey()); - } - } - - @Test - public void fail_to_create_custom_rule_when_invalid_key() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The rule key \"*INVALID*\" is invalid, it should only contain: a-z, 0-9, \"_\""); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("*INVALID*", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_rule_key_already_exists() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - // Create a custom rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("A rule with the key 'CUSTOM_RULE' already exists"); - - // Create another custom rule having same key - newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My another custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_missing_name() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The name is missing"); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_missing_description() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The description is missing"); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_missing_severity() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The severity is missing"); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_invalid_severity() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Severity \"INVALID\" is invalid"); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity("INVALID") - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_missing_status() { - // insert template rule - RuleDto templateRule = createTemplateRule(); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The status is missing"); - - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_wrong_rule_template() { - // insert rule - RuleDefinitionDto rule = newRule(RuleKey.of("java", "S001")).setIsTemplate(false); - dbTester.rules().insert(rule); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("This rule is not a template rule: java:S001"); - - // Create custom rule with unknown template rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", rule.getKey()) - .setName("My custom") - .setHtmlDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "a.*")); - underTest.create(dbSession, newRule); - } - - @Test - public void fail_to_create_custom_rule_when_unknown_template() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The template key doesn't exist: java:S001"); - - // Create custom rule - NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", RuleKey.of("java", "S001")) - .setName("My custom") - .setMarkdownDescription("Some description") - .setSeverity(Severity.MAJOR) - .setStatus(RuleStatus.READY); - underTest.create(dbSession, newRule); - } - - private RuleDto createTemplateRule() { - RuleDto templateRule = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) - .setIsTemplate(true) - .setLanguage("java") - .setPluginKey("sonarjava") - .setConfigKey("S001") - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefRemediationGapMultiplier("1h") - .setDefRemediationBaseEffort("5min") - .setGapDescription("desc") - .setTags(Sets.newHashSet("usertag1", "usertag2")) - .setSystemTags(Sets.newHashSet("tag1", "tag4")) - .setSecurityStandards(Sets.newHashSet("owaspTop10:a1", "cwe:123")) - .setCreatedAt(new Date().getTime()) - .setUpdatedAt(new Date().getTime()); - dbTester.rules().insert(templateRule.getDefinition()); - dbTester.rules().insertOrUpdateMetadata(templateRule.getMetadata().setRuleId(templateRule.getId())); - dbTester.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*")); - ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getDefinition().getId()); - return templateRule; - } - - private RuleDefinitionDto createTemplateRuleWithIntArrayParam() { - RuleDefinitionDto templateRule = newRule(RuleKey.of("java", "S002")) - .setIsTemplate(true) - .setLanguage("java") - .setConfigKey("S002") - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefRemediationGapMultiplier("1h") - .setDefRemediationBaseEffort("5min") - .setGapDescription("desc") - .setCreatedAt(new Date().getTime()) - .setUpdatedAt(new Date().getTime()); - dbTester.rules().insert(templateRule); - dbTester.rules().insertRuleParam(templateRule, - param -> param.setName("myIntegers").setType("INTEGER,multiple=true,values=1;2;3").setDescription("My Integers").setDefaultValue("1")); - ruleIndexer.commitAndIndex(dbTester.getSession(), templateRule.getId()); - return templateRule; - } - - private RuleDefinitionDto createTemplateRuleWithTwoIntParams() { - RuleDefinitionDto templateRule = newRule(RuleKey.of("java", "S003")) - .setIsTemplate(true) - .setLanguage("java") - .setConfigKey("S003") - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefRemediationGapMultiplier("1h") - .setDefRemediationBaseEffort("5min") - .setGapDescription("desc") - .setCreatedAt(new Date().getTime()) - .setUpdatedAt(new Date().getTime()); - dbTester.rules().insert(templateRule); - dbTester.rules().insertRuleParam(templateRule, param -> param.setName("first").setType("INTEGER").setDescription("First integer").setDefaultValue("0")); - dbTester.rules().insertRuleParam(templateRule, param -> param.setName("second").setType("INTEGER").setDescription("Second integer").setDefaultValue("0")); - return templateRule; - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleTagHelperTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleTagHelperTest.java deleted file mode 100644 index 90d821e024f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleTagHelperTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.rule; - -import com.google.common.collect.Sets; -import org.junit.Test; -import org.sonar.db.rule.RuleDto; - -import java.util.Collections; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public class RuleTagHelperTest { - - @Test - public void applyTags() { - RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance")); - boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security")); - assertThat(rule.getTags()).containsOnly("java8", "security"); - assertThat(changed).isTrue(); - } - - @Test - public void applyTags_remove_all_existing_tags() { - RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance")); - boolean changed = RuleTagHelper.applyTags(rule, Collections.emptySet()); - assertThat(rule.getTags()).isEmpty(); - assertThat(changed).isTrue(); - } - - @Test - public void applyTags_no_changes() { - RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance")); - boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("performance")); - assertThat(rule.getTags()).containsOnly("performance"); - assertThat(changed).isFalse(); - } - - @Test - public void applyTags_validate_format() { - RuleDto rule = new RuleDto(); - boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security")); - assertThat(rule.getTags()).containsOnly("java8", "security"); - assertThat(changed).isTrue(); - - try { - RuleTagHelper.applyTags(rule, Sets.newHashSet("Java Eight")); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).startsWith("Tag 'Java Eight' is invalid"); - } - } - - @Test - public void applyTags_do_not_duplicate_system_tags() { - RuleDto rule = new RuleDto() - .setTags(Sets.newHashSet("performance")) - .setSystemTags(Sets.newHashSet("security")); - - boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security")); - - assertThat(changed).isTrue(); - assertThat(rule.getTags()).containsOnly("java8"); - assertThat(rule.getSystemTags()).containsOnly("security"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java deleted file mode 100644 index 7869b26b16a..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java +++ /dev/null @@ -1,587 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.rule; - -import com.google.common.base.Function; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.server.debt.DebtRemediationFunction; -import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.ActiveRuleKey; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.rule.RuleTesting; -import org.sonar.db.user.UserDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.tester.UserSessionRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.api.rule.Severity.CRITICAL; -import static org.sonar.db.rule.RuleTesting.newRule; -import static org.sonar.server.rule.RuleUpdate.createForCustomRule; -import static org.sonar.server.rule.RuleUpdate.createForPluginRule; - -public class RuleUpdaterTest { - - static final RuleKey RULE_KEY = RuleKey.of("squid", "S001"); - - private System2 system2 = mock(System2.class); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - @Rule - public DbTester db = DbTester.create(system2); - - @Rule - public EsTester es = EsTester.create(); - - private RuleIndex ruleIndex = new RuleIndex(es.client(), system2); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); - private DbSession dbSession = db.getSession(); - - private RuleUpdater underTest = new RuleUpdater(db.getDbClient(), ruleIndexer, system2); - - @Test - public void do_not_update_rule_with_removed_status() { - db.rules().insert(newRule(RULE_KEY).setStatus(RuleStatus.REMOVED)); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setTags(Sets.newHashSet("java9")) - .setOrganization(db.getDefaultOrganization()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Rule with REMOVED status cannot be updated: squid:S001"); - - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - } - - @Test - public void no_changes() { - RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - // the following fields are not supposed to be updated - .setNoteData("my *note*") - .setNoteUserUuid("me") - .setTags(ImmutableSet.of("tag1")) - .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) - .setRemediationGapMultiplier("1d") - .setRemediationBaseEffort("5min"); - db.rules().insert(ruleDto.getDefinition()); - db.rules().insertOrUpdateMetadata(ruleDto.getMetadata().setRuleId(ruleDto.getId())); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY); - assertThat(update.isEmpty()).isTrue(); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getNoteData()).isEqualTo("my *note*"); - assertThat(rule.getNoteUserUuid()).isEqualTo("me"); - assertThat(rule.getTags()).containsOnly("tag1"); - assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()); - assertThat(rule.getRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getRemediationBaseEffort()).isEqualTo("5min"); - } - - @Test - public void set_markdown_note() { - UserDto user = db.users().insertUser(); - userSessionRule.logIn(user); - - RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - .setNoteData(null) - .setNoteUserUuid(null) - - // the following fields are not supposed to be updated - .setTags(ImmutableSet.of("tag1")) - .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) - .setRemediationGapMultiplier("1d") - .setRemediationBaseEffort("5min"); - db.rules().insert(ruleDto.getDefinition()); - db.rules().insertOrUpdateMetadata(ruleDto.getMetadata().setRuleId(ruleDto.getId())); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setMarkdownNote("my *note*") - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getNoteData()).isEqualTo("my *note*"); - assertThat(rule.getNoteUserUuid()).isEqualTo(user.getUuid()); - assertThat(rule.getNoteCreatedAt()).isNotNull(); - assertThat(rule.getNoteUpdatedAt()).isNotNull(); - // no other changes - assertThat(rule.getTags()).containsOnly("tag1"); - assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()); - assertThat(rule.getRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getRemediationBaseEffort()).isEqualTo("5min"); - } - - @Test - public void remove_markdown_note() { - RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - .setNoteData("my *note*") - .setNoteUserUuid("me"); - db.rules().insert(ruleDto.getDefinition()); - db.rules().insertOrUpdateMetadata(ruleDto.getMetadata().setRuleId(ruleDto.getId())); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setMarkdownNote(null) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getNoteData()).isNull(); - assertThat(rule.getNoteUserUuid()).isNull(); - assertThat(rule.getNoteCreatedAt()).isNull(); - assertThat(rule.getNoteUpdatedAt()).isNull(); - } - - @Test - public void set_tags() { - // insert db - db.rules().insert(RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - .setTags(Sets.newHashSet("security")) - .setSystemTags(Sets.newHashSet("java8", "javadoc")).getDefinition()); - dbSession.commit(); - - // java8 is a system tag -> ignore - RuleUpdate update = createForPluginRule(RULE_KEY) - .setTags(Sets.newHashSet("bug", "java8")) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getTags()).containsOnly("bug"); - assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc"); - - // verify that tags are indexed in index - List<String> tags = ruleIndex.listTags(db.getDefaultOrganization(), null, 10); - assertThat(tags).containsExactly("bug", "java8", "javadoc"); - } - - @Test - public void remove_tags() { - RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - .setTags(Sets.newHashSet("security")) - .setSystemTags(Sets.newHashSet("java8", "javadoc")); - db.rules().insert(ruleDto.getDefinition()); - db.rules().insertOrUpdateMetadata(ruleDto.getMetadata()); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setTags(null) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getTags()).isEmpty(); - assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc"); - - // verify that tags are indexed in index - List<String> tags = ruleIndex.listTags(db.getDefaultOrganization(), null, 10); - assertThat(tags).containsExactly("java8", "javadoc"); - } - - @Test - public void override_debt() { - db.rules().insert(newRule(RULE_KEY) - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefRemediationGapMultiplier("1d") - .setDefRemediationBaseEffort("5min")); - dbSession.commit(); - - DefaultDebtRemediationFunction fn = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "1min"); - RuleUpdate update = createForPluginRule(RULE_KEY) - .setDebtRemediationFunction(fn) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - dbSession.clearCache(); - - // verify debt is overridden - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()); - assertThat(rule.getRemediationGapMultiplier()).isNull(); - assertThat(rule.getRemediationBaseEffort()).isEqualTo("1min"); - - assertThat(rule.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name()); - assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getDefRemediationBaseEffort()).isEqualTo("5min"); - } - - @Test - public void override_debt_only_offset() { - db.rules().insert(newRule(RULE_KEY) - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR.name()) - .setDefRemediationGapMultiplier("1d") - .setDefRemediationBaseEffort(null)); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "2d", null)) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - dbSession.clearCache(); - - // verify debt is overridden - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name()); - assertThat(rule.getRemediationGapMultiplier()).isEqualTo("2d"); - assertThat(rule.getRemediationBaseEffort()).isNull(); - - assertThat(rule.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name()); - assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getDefRemediationBaseEffort()).isNull(); - } - - @Test - public void override_debt_from_linear_with_offset_to_constant() { - db.rules().insert(newRule(RULE_KEY) - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefRemediationGapMultiplier("1d") - .setDefRemediationBaseEffort("5min")); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10min")) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - dbSession.clearCache(); - - // verify debt is overridden - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()); - assertThat(rule.getRemediationGapMultiplier()).isNull(); - assertThat(rule.getRemediationBaseEffort()).isEqualTo("10min"); - - assertThat(rule.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name()); - assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getDefRemediationBaseEffort()).isEqualTo("5min"); - } - - @Test - public void reset_remediation_function() { - RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) - .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR.name()) - .setDefRemediationGapMultiplier("1d") - .setDefRemediationBaseEffort("5min") - .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) - .setRemediationGapMultiplier(null) - .setRemediationBaseEffort("1min"); - db.rules().insert(ruleDto.getDefinition()); - db.rules().insertOrUpdateMetadata(ruleDto.getMetadata().setRuleId(ruleDto.getId())); - dbSession.commit(); - - RuleUpdate update = createForPluginRule(RULE_KEY) - .setDebtRemediationFunction(null) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - dbSession.clearCache(); - - // verify debt is coming from default values - RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); - assertThat(rule.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name()); - assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1d"); - assertThat(rule.getDefRemediationBaseEffort()).isEqualTo("5min"); - - assertThat(rule.getRemediationFunction()).isNull(); - assertThat(rule.getRemediationGapMultiplier()).isNull(); - assertThat(rule.getRemediationBaseEffort()).isNull(); - } - - @Test - public void update_custom_rule() { - // Create template rule - RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); - db.rules().insert(templateRule.getDefinition()); - db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*")); - db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("format").setType("STRING").setDescription("Format")); - - // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) - .setName("Old name") - .setDescription("Old description") - .setSeverity(Severity.MINOR) - .setStatus(RuleStatus.BETA) - .getDefinition(); - db.rules().insert(customRule); - db.rules().insertRuleParam(customRule, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue("a.*")); - db.rules().insertRuleParam(customRule, param -> param.setName("format").setType("STRING").setDescription("Format").setDefaultValue(null)); - - // Update custom rule - RuleUpdate update = createForCustomRule(customRule.getKey()) - .setName("New name") - .setMarkdownDescription("New description") - .setSeverity("MAJOR") - .setStatus(RuleStatus.READY) - .setParameters(ImmutableMap.of("regex", "b.*")) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - - // Verify custom rule is updated - RuleDto customRuleReloaded = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), customRule.getKey()); - assertThat(customRuleReloaded).isNotNull(); - assertThat(customRuleReloaded.getName()).isEqualTo("New name"); - assertThat(customRuleReloaded.getDescription()).isEqualTo("New description"); - assertThat(customRuleReloaded.getSeverityString()).isEqualTo("MAJOR"); - assertThat(customRuleReloaded.getStatus()).isEqualTo(RuleStatus.READY); - - List<RuleParamDto> params = db.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRuleReloaded.getKey()); - assertThat(params).extracting(RuleParamDto::getDefaultValue).containsOnly("b.*", null); - - // Verify in index - assertThat(ruleIndex.search(new RuleQuery().setQueryText("New name"), new SearchOptions()).getIds()).containsOnly(customRule.getId()); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("New description"), new SearchOptions()).getIds()).containsOnly(customRule.getId()); - - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Old name"), new SearchOptions()).getTotal()).isZero(); - assertThat(ruleIndex.search(new RuleQuery().setQueryText("Old description"), new SearchOptions()).getTotal()).isZero(); - } - - @Test - public void update_custom_rule_with_empty_parameter() { - // Create template rule - RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); - db.rules().insert(templateRule.getDefinition()); - db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(null)); - - // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) - .setName("Old name") - .setDescription("Old description") - .setSeverity(Severity.MINOR) - .setStatus(RuleStatus.BETA) - .getDefinition(); - db.rules().insert(customRule); - db.rules().insertRuleParam(customRule, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(null)); - - dbSession.commit(); - - // Update custom rule without setting a value for the parameter - RuleUpdate update = createForCustomRule(customRule.getKey()) - .setName("New name") - .setMarkdownDescription("New description") - .setSeverity("MAJOR") - .setStatus(RuleStatus.READY) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - dbSession.clearCache(); - - // Verify custom rule is updated - List<RuleParamDto> params = db.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRule.getKey()); - assertThat(params.get(0).getDefaultValue()).isNull(); - } - - @Test - public void update_active_rule_parameters_when_updating_custom_rule() { - // Create template rule with 3 parameters - RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")).setLanguage("xoo"); - RuleDefinitionDto templateRuleDefinition = templateRule.getDefinition(); - db.rules().insert(templateRuleDefinition); - db.rules().insertRuleParam(templateRuleDefinition, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*")); - db.rules().insertRuleParam(templateRuleDefinition, param -> param.setName("format").setType("STRING").setDescription("format").setDefaultValue("csv")); - db.rules().insertRuleParam(templateRuleDefinition, param -> param.setName("message").setType("STRING").setDescription("message")); - - // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule) - .setSeverity(Severity.MAJOR) - .setLanguage("xoo") - .getDefinition(); - db.rules().insert(customRule); - RuleParamDto ruleParam1 = db.rules().insertRuleParam(customRule, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue("a.*")); - db.rules().insertRuleParam(customRule, param -> param.setName("format").setType("STRING").setDescription("format").setDefaultValue("txt")); - db.rules().insertRuleParam(customRule, param -> param.setName("message").setType("STRING").setDescription("message")); - - // Create a quality profile - QProfileDto profileDto = QProfileTesting.newXooP1(db.getDefaultOrganization()); - db.getDbClient().qualityProfileDao().insert(dbSession, profileDto); - dbSession.commit(); - - // Activate the custom rule - ActiveRuleDto activeRuleDto = new ActiveRuleDto() - .setProfileId(profileDto.getId()) - .setRuleId(customRule.getId()) - .setSeverity(Severity.BLOCKER); - db.getDbClient().activeRuleDao().insert(dbSession, activeRuleDto); - db.getDbClient().activeRuleDao().insertParam(dbSession, activeRuleDto, new ActiveRuleParamDto() - .setActiveRuleId(activeRuleDto.getId()) - .setRulesParameterId(ruleParam1.getId()) - .setKey(ruleParam1.getName()) - .setValue(ruleParam1.getDefaultValue())); - dbSession.commit(); - - // Update custom rule parameter 'regex', add 'message' and remove 'format' - RuleUpdate update = createForCustomRule(customRule.getKey()) - .setParameters(ImmutableMap.of("regex", "b.*", "message", "a message")) - .setOrganization(db.getDefaultOrganization()); - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - - // Verify custom rule parameters has been updated - List<RuleParamDto> params = db.getDbClient().ruleDao().selectRuleParamsByRuleKey(dbSession, customRule.getKey()); - assertThat(params).hasSize(3); - - Map<String, RuleParamDto> paramsByKey = paramsByKey(params); - assertThat(paramsByKey.get("regex")).isNotNull(); - assertThat(paramsByKey.get("regex").getDefaultValue()).isEqualTo("b.*"); - assertThat(paramsByKey.get("message")).isNotNull(); - assertThat(paramsByKey.get("message").getDefaultValue()).isEqualTo("a message"); - assertThat(paramsByKey.get("format")).isNotNull(); - assertThat(paramsByKey.get("format").getDefaultValue()).isNull(); - - // Verify that severity has not changed - ActiveRuleDto activeRuleReloaded = db.getDbClient().activeRuleDao().selectByKey(dbSession, ActiveRuleKey.of(profileDto, customRule.getKey())).get(); - assertThat(activeRuleReloaded.getSeverityString()).isEqualTo(Severity.BLOCKER); - - // Verify active rule parameters has been updated - List<ActiveRuleParamDto> activeRuleParams = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(dbSession, activeRuleReloaded.getId()); - - assertThat(activeRuleParams).hasSize(2); - Map<String, ActiveRuleParamDto> activeRuleParamsByKey = ActiveRuleParamDto.groupByKey(activeRuleParams); - assertThat(activeRuleParamsByKey.get("regex").getValue()).isEqualTo("b.*"); - assertThat(activeRuleParamsByKey.get("message").getValue()).isEqualTo("a message"); - assertThat(activeRuleParamsByKey.get("format")).isNull(); - } - - @Test - public void fail_to_update_custom_rule_when_empty_name() { - // Create template rule - RuleDefinitionDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")).getDefinition(); - db.rules().insert(templateRule); - - // Create custom rule - RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule); - db.rules().insert(customRule); - - dbSession.commit(); - - // Update custom rule - RuleUpdate update = createForCustomRule(customRule.getKey()) - .setName("") - .setMarkdownDescription("New desc") - .setOrganization(db.getDefaultOrganization()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The name is missing"); - - underTest.update(dbSession, update, db.getDefaultOrganization(), userSessionRule); - } - - @Test - public void fail_to_update_custom_rule_when_empty_description() { - // Create template rule - RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); - db.rules().insert(templateRule.getDefinition()); - - // Create custom rule - RuleDto customRule = RuleTesting.newCustomRule(templateRule); - db.rules().insert(customRule.getDefinition()); - - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The description is missing"); - - underTest.update(dbSession, - createForCustomRule(customRule.getKey()).setName("New name").setMarkdownDescription("").setOrganization(db.getDefaultOrganization()), - db.getDefaultOrganization(), userSessionRule); - } - - @Test - public void fail_to_update_plugin_rule_if_name_is_set() { - RuleDefinitionDto ruleDefinition = db.rules().insert(newRule(RuleKey.of("squid", "S01"))); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Not a custom rule"); - - createForPluginRule(ruleDefinition.getKey()).setName("New name"); - } - - @Test - public void fail_to_update_plugin_rule_if_description_is_set() { - RuleDefinitionDto ruleDefinition = db.rules().insert(newRule(RuleKey.of("squid", "S01"))); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Not a custom rule"); - - createForPluginRule(ruleDefinition.getKey()).setMarkdownDescription("New description"); - } - - @Test - public void fail_to_update_plugin_rule_if_severity_is_set() { - RuleDefinitionDto ruleDefinition = db.rules().insert(newRule(RuleKey.of("squid", "S01"))); - dbSession.commit(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Not a custom rule"); - - createForPluginRule(ruleDefinition.getKey()).setSeverity(CRITICAL); - } - - private static Map<String, RuleParamDto> paramsByKey(List<RuleParamDto> params) { - return FluentIterable.from(params).uniqueIndex(RuleParamToKey.INSTANCE); - } - - private enum RuleParamToKey implements Function<RuleParamDto, String> { - INSTANCE; - - @Override - public String apply(@Nonnull RuleParamDto input) { - return input.getName(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/settings/ProjectConfigurationLoaderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/settings/ProjectConfigurationLoaderImplTest.java deleted file mode 100644 index 60944a2a608..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/settings/ProjectConfigurationLoaderImplTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.settings; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import java.util.Collections; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.config.Configuration; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.property.PropertiesDao; -import org.sonar.db.property.PropertyDto; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singleton; -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class ProjectConfigurationLoaderImplTest { - private DbClient dbClient = mock(DbClient.class); - private DbSession dbSession = mock(DbSession.class); - private PropertiesDao propertiesDao = mock(PropertiesDao.class); - private MapSettings globalSettings = new MapSettings(); - private ProjectConfigurationLoaderImpl underTest = new ProjectConfigurationLoaderImpl(globalSettings, dbClient); - - @Before - public void setUp() throws Exception { - when(dbClient.openSession(anyBoolean())) - .thenThrow(new IllegalStateException("ProjectConfigurationLoaderImpl should not open DB session")); - when(dbClient.propertiesDao()).thenReturn(propertiesDao); - } - - @Test - public void returns_empty_map_when_no_component() { - assertThat(underTest.loadProjectConfigurations(dbSession, Collections.emptySet())) - .isEmpty(); - - verifyZeroInteractions(propertiesDao); - } - - @Test - public void return_configuration_with_just_global_settings_when_no_component_settings() { - String key = randomAlphanumeric(3); - String value = randomAlphanumeric(4); - String componentDbKey = randomAlphanumeric(5); - String componentUuid = randomAlphanumeric(6); - globalSettings.setProperty(key, value); - when(propertiesDao.selectProjectProperties(dbSession, componentDbKey)) - .thenReturn(emptyList()); - ComponentDto component = newComponentDto(componentDbKey, componentUuid); - - Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component)); - - assertThat(configurations) - .containsOnlyKeys(componentUuid); - assertThat(configurations.get(componentUuid).get(key)).contains(value); - } - - @Test - public void return_configuration_with_global_settings_and_component_settings() { - String globalKey = randomAlphanumeric(3); - String globalValue = randomAlphanumeric(4); - String componentDbKey = randomAlphanumeric(5); - String componentUuid = randomAlphanumeric(6); - String projectPropKey1 = randomAlphanumeric(7); - String projectPropValue1 = randomAlphanumeric(8); - String projectPropKey2 = randomAlphanumeric(9); - String projectPropValue2 = randomAlphanumeric(10); - globalSettings.setProperty(globalKey, globalValue); - when(propertiesDao.selectProjectProperties(dbSession, componentDbKey)) - .thenReturn(ImmutableList.of(newPropertyDto(projectPropKey1, projectPropValue1), newPropertyDto(projectPropKey2, projectPropValue2))); - ComponentDto component = newComponentDto(componentDbKey, componentUuid); - - Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component)); - - assertThat(configurations) - .containsOnlyKeys(componentUuid); - assertThat(configurations.get(componentUuid).get(globalKey)).contains(globalValue); - assertThat(configurations.get(componentUuid).get(projectPropKey1)).contains(projectPropValue1); - assertThat(configurations.get(componentUuid).get(projectPropKey2)).contains(projectPropValue2); - } - - @Test - public void return_configuration_with_global_settings_main_branch_settings_and_branch_settings() { - String globalKey = randomAlphanumeric(3); - String globalValue = randomAlphanumeric(4); - String mainBranchDbKey = randomAlphanumeric(5); - String branchDbKey = mainBranchDbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5); - String branchUuid = randomAlphanumeric(6); - String mainBranchPropKey = randomAlphanumeric(7); - String mainBranchPropValue = randomAlphanumeric(8); - String branchPropKey = randomAlphanumeric(9); - String branchPropValue = randomAlphanumeric(10); - globalSettings.setProperty(globalKey, globalValue); - when(propertiesDao.selectProjectProperties(dbSession, mainBranchDbKey)) - .thenReturn(ImmutableList.of(newPropertyDto(mainBranchPropKey, mainBranchPropValue))); - when(propertiesDao.selectProjectProperties(dbSession, branchDbKey)) - .thenReturn(ImmutableList.of(newPropertyDto(branchPropKey, branchPropValue))); - ComponentDto component = newComponentDto(branchDbKey, branchUuid); - - Map<String, Configuration> configurations = underTest.loadProjectConfigurations(dbSession, singleton(component)); - - assertThat(configurations) - .containsOnlyKeys(branchUuid); - assertThat(configurations.get(branchUuid).get(globalKey)).contains(globalValue); - assertThat(configurations.get(branchUuid).get(mainBranchPropKey)).contains(mainBranchPropValue); - assertThat(configurations.get(branchUuid).get(branchPropKey)).contains(branchPropValue); - } - - @Test - public void loads_configuration_of_any_given_component_only_once() { - String mainBranch1DbKey = randomAlphanumeric(4); - String mainBranch1Uuid = randomAlphanumeric(5); - String branch1DbKey = mainBranch1DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5); - String branch1Uuid = randomAlphanumeric(6); - String branch2DbKey = mainBranch1DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(7); - String branch2Uuid = randomAlphanumeric(8); - String mainBranch2DbKey = randomAlphanumeric(14); - String mainBranch2Uuid = randomAlphanumeric(15); - String branch3DbKey = mainBranch2DbKey + ComponentDto.BRANCH_KEY_SEPARATOR + randomAlphabetic(5); - String branch3Uuid = randomAlphanumeric(16); - - ComponentDto mainBranch1 = newComponentDto(mainBranch1DbKey, mainBranch1Uuid); - ComponentDto branch1 = newComponentDto(branch1DbKey, branch1Uuid); - ComponentDto branch2 = newComponentDto(branch2DbKey, branch2Uuid); - ComponentDto mainBranch2 = newComponentDto(mainBranch2DbKey, mainBranch2Uuid); - ComponentDto branch3 = newComponentDto(branch3DbKey, branch3Uuid); - - underTest.loadProjectConfigurations(dbSession, ImmutableSet.of(mainBranch1, mainBranch2, branch1, branch2, branch3)); - - verify(propertiesDao, times(1)).selectProjectProperties(dbSession, mainBranch1DbKey); - verify(propertiesDao, times(1)).selectProjectProperties(dbSession, mainBranch2DbKey); - verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch1DbKey); - verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch2DbKey); - verify(propertiesDao, times(1)).selectProjectProperties(dbSession, branch3DbKey); - verifyNoMoreInteractions(propertiesDao); - } - - private ComponentDto newComponentDto(String componentDbKey, String componentUuid) { - return new ComponentDto().setDbKey(componentDbKey).setUuid(componentUuid); - } - - private PropertyDto newPropertyDto(String projectKey1, String projectValue1) { - return new PropertyDto() - .setKey(projectKey1) - .setValue(projectValue1); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/settings/TestProjectConfigurationLoader.java b/server/sonar-server/src/test/java/org/sonar/server/settings/TestProjectConfigurationLoader.java deleted file mode 100644 index 36820604f60..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/settings/TestProjectConfigurationLoader.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.settings; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import org.sonar.api.config.Configuration; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; - -public class TestProjectConfigurationLoader implements ProjectConfigurationLoader { - - private final Configuration config; - - public TestProjectConfigurationLoader(Configuration config) { - this.config = config; - } - - @Override - public Map<String, Configuration> loadProjectConfigurations(DbSession dbSession, Set<ComponentDto> projects) { - Map<String, Configuration> map = new HashMap<>(); - for (ComponentDto project : projects) { - map.put(project.uuid(), config); - } - return map; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/DecorationDataHolderTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/DecorationDataHolderTest.java deleted file mode 100644 index dbc493dafd2..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/source/DecorationDataHolderTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.source; - -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DecorationDataHolderTest { - - private static final String SAMPLE_SYNTAX_HIGHLIGHTING_RULES = "0,8,k;0,52,cppd;54,67,a;69,75,k;106,130,cppd;114,130,k;"; - private static final String SAMPLE_SYMBOLS_REFERENCES = "80,85,80,90,140;"; - - private DecorationDataHolder decorationDataHolder; - - @Before - public void setUpHighlightingContext() { - decorationDataHolder = new DecorationDataHolder(); - decorationDataHolder.loadSyntaxHighlightingData(SAMPLE_SYNTAX_HIGHLIGHTING_RULES); - decorationDataHolder.loadSymbolReferences(SAMPLE_SYMBOLS_REFERENCES); - } - - @Test - public void should_extract_lower_bounds_from_serialized_rules() { - - List<OpeningHtmlTag> openingTagsEntries = decorationDataHolder.getOpeningTagsEntries(); - - assertThat(openingTagsEntries.get(0)).isEqualTo(new OpeningHtmlTag(0, "k")); - assertThat(openingTagsEntries.get(1)).isEqualTo(new OpeningHtmlTag(0, "cppd")); - assertThat(openingTagsEntries.get(2)).isEqualTo(new OpeningHtmlTag(54, "a")); - assertThat(openingTagsEntries.get(3)).isEqualTo(new OpeningHtmlTag(69, "k")); - assertThat(openingTagsEntries.get(4)).isEqualTo(new OpeningHtmlTag(80, "sym-80 sym")); - assertThat(openingTagsEntries.get(5)).isEqualTo(new OpeningHtmlTag(90, "sym-80 sym")); - assertThat(openingTagsEntries.get(6)).isEqualTo(new OpeningHtmlTag(106, "cppd")); - assertThat(openingTagsEntries.get(7)).isEqualTo(new OpeningHtmlTag(114, "k")); - assertThat(openingTagsEntries.get(8)).isEqualTo(new OpeningHtmlTag(140, "sym-80 sym")); - } - - @Test - public void should_extract_upper_bounds_from_serialized_rules() { - - List<Integer> offsets = decorationDataHolder.getClosingTagsOffsets(); - - assertThat(offsets.get(0)).isEqualTo(8); - assertThat(offsets.get(1)).isEqualTo(52); - assertThat(offsets.get(2)).isEqualTo(67); - assertThat(offsets.get(3)).isEqualTo(75); - assertThat(offsets.get(4)).isEqualTo(85); - assertThat(offsets.get(5)).isEqualTo(95); - assertThat(offsets.get(6)).isEqualTo(130); - assertThat(offsets.get(7)).isEqualTo(130); - assertThat(offsets.get(8)).isEqualTo(145); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/HtmlSourceDecoratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/HtmlSourceDecoratorTest.java deleted file mode 100644 index ec38ac559e7..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/source/HtmlSourceDecoratorTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.source; - -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class HtmlSourceDecoratorTest { - - HtmlSourceDecorator sourceDecorator; - - @Before - public void setUpDatasets() { - sourceDecorator = new HtmlSourceDecorator(); - } - - @Test - public void should_decorate_single_line() { - String sourceLine = "package org.polop;"; - String highlighting = "0,7,k"; - String symbols = "8,17,42"; - assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, highlighting, symbols)).isEqualTo( - "<span class=\"k\">package</span> <span class=\"sym-42 sym\">org.polop</span>;"); - } - - @Test - public void should_handle_highlighting_too_long() { - String sourceLine = "abc"; - String highlighting = "0,5,c"; - String symbols = ""; - assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, highlighting, symbols)).isEqualTo("<span class=\"c\">abc</span>"); - } - - @Test - public void should_ignore_missing_highlighting() { - String sourceLine = " if (toto < 42) {"; - assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, null, null)).isEqualTo(" if (toto < 42) {"); - assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, "", null)).isEqualTo(" if (toto < 42) {"); - } - - @Test - public void should_ignore_null_source() { - assertThat(sourceDecorator.getDecoratedSourceAsHtml(null, null, null)).isNull(); - } - - @Test - public void should_ignore_empty_source() { - assertThat(sourceDecorator.getDecoratedSourceAsHtml("", "0,1,cppd", "")).isEqualTo(""); - } - - @Test - public void should_ignore_empty_rule() { - String sourceLine = "@Deprecated"; - String highlighting = "0,0,a;0,11,a"; - String symbols = "1,11,1"; - assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, highlighting, symbols)).isEqualTo("<span class=\"a\">@<span class=\"sym-1 sym\">Deprecated</span></span>"); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/HtmlTextDecoratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/HtmlTextDecoratorTest.java deleted file mode 100644 index 6494abc5897..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/source/HtmlTextDecoratorTest.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.source; - -import org.junit.Test; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.source.HtmlTextDecorator.CR_END_OF_LINE; -import static org.sonar.server.source.HtmlTextDecorator.LF_END_OF_LINE; - -public class HtmlTextDecoratorTest { - - @Test - public void should_decorate_simple_character_range() { - - String packageDeclaration = "package org.sonar.core.source;"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,7,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(packageDeclaration, decorationData); - - assertThat(htmlOutput).containsOnly("<span class=\"k\">package</span> org.sonar.core.source;"); - } - - @Test - public void should_decorate_multiple_lines_characters_range() { - - String firstCommentLine = "/*"; - String secondCommentLine = " * Test"; - String thirdCommentLine = " */"; - - String blockComment = firstCommentLine + LF_END_OF_LINE - + secondCommentLine + LF_END_OF_LINE - + thirdCommentLine + LF_END_OF_LINE; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,14,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(blockComment, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">" + firstCommentLine + "</span>", - "<span class=\"cppd\">" + secondCommentLine + "</span>", - "<span class=\"cppd\">" + thirdCommentLine + "</span>", - "" - ); - } - - @Test - public void should_highlight_multiple_words_in_one_line() { - - String classDeclaration = "public class MyClass implements MyInterface {"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,6,k;7,12,k;21,31,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(classDeclaration, decorationData); - - assertThat(htmlOutput).containsOnly( - "<span class=\"k\">public</span> " + - "<span class=\"k\">class</span> MyClass " + - "<span class=\"k\">implements</span> MyInterface {"); - } - - @Test - public void should_allow_multiple_levels_highlighting() { - - String javaDocSample = - "/**" + LF_END_OF_LINE + - " * Creates a FormulaDecorator" + LF_END_OF_LINE + - " *" + LF_END_OF_LINE + - " * @param metric the metric should have an associated formula" + LF_END_OF_LINE + - " * " + LF_END_OF_LINE + - " * @throws IllegalArgumentException if no formula is associated to the metric" + LF_END_OF_LINE + - " */" + LF_END_OF_LINE; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,184,cppd;47,53,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javaDocSample, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\"> * Creates a FormulaDecorator</span>", - "<span class=\"cppd\"> *</span>", - "<span class=\"cppd\"> * @param <span class=\"k\">metric</span> the metric should have an associated formula</span>", - "<span class=\"cppd\"> * </span>", - "<span class=\"cppd\"> * @throws IllegalArgumentException if no formula is associated to the metric</span>", - "<span class=\"cppd\"> */</span>", - "" - ); - } - - @Test - public void should_support_crlf_line_breaks() { - - String crlfCodeSample = - "/**" + CR_END_OF_LINE + LF_END_OF_LINE + - "* @return metric generated by the decorator" + CR_END_OF_LINE + LF_END_OF_LINE + - "*/" + CR_END_OF_LINE + LF_END_OF_LINE + - "@DependedUpon" + CR_END_OF_LINE + LF_END_OF_LINE + - "public Metric generatesMetric() {" + CR_END_OF_LINE + LF_END_OF_LINE + - " return metric;" + CR_END_OF_LINE + LF_END_OF_LINE + - "}" + CR_END_OF_LINE + LF_END_OF_LINE; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,52,cppd;54,67,a;69,75,k;106,112,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(crlfCodeSample, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\">* @return metric generated by the decorator</span>", - "<span class=\"cppd\">*/</span>", - "<span class=\"a\">@DependedUpon</span>", - "<span class=\"k\">public</span> Metric generatesMetric() {", - " <span class=\"k\">return</span> metric;", - "}", - "" - ); - } - - @Test - public void should_close_tags_at_end_of_file() { - - String classDeclarationSample = - "/*" + LF_END_OF_LINE + - " * Header" + LF_END_OF_LINE + - " */" + LF_END_OF_LINE + - LF_END_OF_LINE + - "public class HelloWorld {" + LF_END_OF_LINE + - "}"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,16,cppd;18,25,k;25,31,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(classDeclarationSample, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/*</span>", - "<span class=\"cppd\"> * Header</span>", - "<span class=\"cppd\"> */</span>", - "", - "<span class=\"k\">public </span><span class=\"k\">class </span>HelloWorld {", - "}" - ); - } - - @Test - public void should_escape_markup_chars() { - - String javadocWithHtml = - "/**\n" + - " * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.\n" + - " * \n" + - " * This framework can used for instance in order to :\n" + - " * <ul>\n" + - " * <li>Create a lexer in charge to generate a list of tokens from a character stream</li>\n" + - " * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li>\n" + - " * <li>Create a javadoc generator</li>\n" + - " * <li>...</li>\n" + - " * </ul>\n" + - " */\n"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,453,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javadocWithHtml, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\"> * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.</span>", - "<span class=\"cppd\"> * </span>", - "<span class=\"cppd\"> * This framework can used for instance in order to :</span>", - "<span class=\"cppd\"> * <ul></span>", - "<span class=\"cppd\"> * <li>Create a lexer in charge to generate a list of tokens from a character stream</li></span>", - "<span class=\"cppd\"> * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li></span>", - "<span class=\"cppd\"> * <li>Create a javadoc generator</li></span>", - "<span class=\"cppd\"> * <li>...</li></span>", - "<span class=\"cppd\"> * </ul></span>", - "<span class=\"cppd\"> */</span>", - ""); - } - - @Test - public void should_escape_ampersand_char() { - - String javadocWithAmpersandChar = - "/**\n" + - " * Definition of a dashboard.\n" + - " * <p/>\n" + - " * Its name and description can be retrieved using the i18n mechanism, using the keys \"dashboard.<id>.name\" and\n" + - " * \"dashboard.<id>.description\".\n" + - " *\n" + - " * @since 2.13\n" + - " */\n"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,220,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javadocWithAmpersandChar, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\"> * Definition of a dashboard.</span>", - "<span class=\"cppd\"> * <p/></span>", - "<span class=\"cppd\"> * Its name and description can be retrieved using the i18n mechanism, using the keys \"dashboard.&lt;id&gt;.name\" and</span>", - "<span class=\"cppd\"> * \"dashboard.&lt;id&gt;.description\".</span>", - "<span class=\"cppd\"> *</span>", - "<span class=\"cppd\"> * @since 2.13</span>", - "<span class=\"cppd\"> */</span>", - ""); - } - - @Test - public void should_support_cr_line_breaks() { - - String crCodeSample = - "/**" + CR_END_OF_LINE + - "* @return metric generated by the decorator" + CR_END_OF_LINE + - "*/" + CR_END_OF_LINE + - "@DependedUpon" + CR_END_OF_LINE + - "public Metric generatesMetric() {" + CR_END_OF_LINE + - " return metric;" + CR_END_OF_LINE + - "}" + CR_END_OF_LINE; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,50,cppd;51,64,a;65,71,k;101,107,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(crCodeSample, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\">* @return metric generated by the decorator</span>", - "<span class=\"cppd\">*/</span>", - "<span class=\"a\">@DependedUpon</span>", - "<span class=\"k\">public</span> Metric generatesMetric() {", - " <span class=\"k\">return</span> metric;", - "}", - "" - ); - - } - - @Test - public void should_support_multiple_empty_lines_at_end_of_file() { - - String classDeclarationSample = - "/*" + LF_END_OF_LINE + - " * Header" + LF_END_OF_LINE + - " */" + LF_END_OF_LINE + - LF_END_OF_LINE + - "public class HelloWorld {" + LF_END_OF_LINE + - "}" + LF_END_OF_LINE + LF_END_OF_LINE + LF_END_OF_LINE; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,16,cppd;18,25,k;25,31,k;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(classDeclarationSample, decorationData); - - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/*</span>", - "<span class=\"cppd\"> * Header</span>", - "<span class=\"cppd\"> */</span>", - "", - "<span class=\"k\">public </span><span class=\"k\">class </span>HelloWorld {", - "}", - "", - "", - "" - ); - } - - @Test - public void returned_code_begin_from_given_param() { - - String javadocWithHtml = - "/**\n" + - " * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.\n" + - " * \n" + - " * This framework can used for instance in order to :\n" + - " * <ul>\n" + - " * <li>Create a lexer in charge to generate a list of tokens from a character stream</li>\n" + - " * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li>\n" + - " * <li>Create a javadoc generator</li>\n" + - " * <li>...</li>\n" + - " * </ul>\n" + - " */\n"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,453,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javadocWithHtml, decorationData, 4, null); - assertThat(htmlOutput).hasSize(9); - - // Begin from line 4 - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\"> * This framework can used for instance in order to :</span>", - "<span class=\"cppd\"> * <ul></span>", - "<span class=\"cppd\"> * <li>Create a lexer in charge to generate a list of tokens from a character stream</li></span>", - "<span class=\"cppd\"> * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li></span>", - "<span class=\"cppd\"> * <li>Create a javadoc generator</li></span>", - "<span class=\"cppd\"> * <li>...</li></span>", - "<span class=\"cppd\"> * </ul></span>", - "<span class=\"cppd\"> */</span>", - ""); - } - - @Test - public void returned_code_end_to_given_param() { - - String javadocWithHtml = - "/**\n" + - " * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.\n" + - " * \n" + - " * This framework can used for instance in order to :\n" + - " * <ul>\n" + - " * <li>Create a lexer in charge to generate a list of tokens from a character stream</li>\n" + - " * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li>\n" + - " * <li>Create a javadoc generator</li>\n" + - " * <li>...</li>\n" + - " * </ul>\n" + - " */\n"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,453,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javadocWithHtml, decorationData, null, 4); - assertThat(htmlOutput).hasSize(4); - - // End at line 4 - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\">/**</span>", - "<span class=\"cppd\"> * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.</span>", - "<span class=\"cppd\"> * </span>", - "<span class=\"cppd\"> * This framework can used for instance in order to :</span>"); - } - - @Test - public void returned_code_is_between_from_and_to_params() { - - String javadocWithHtml = - "/**\n" + - " * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.\n" + - " * \n" + - " * This framework can used for instance in order to :\n" + - " * <ul>\n" + - " * <li>Create a lexer in charge to generate a list of tokens from a character stream</li>\n" + - " * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li>\n" + - " * <li>Create a javadoc generator</li>\n" + - " * <li>...</li>\n" + - " * </ul>\n" + - " */\n"; - - DecorationDataHolder decorationData = new DecorationDataHolder(); - decorationData.loadSyntaxHighlightingData("0,453,cppd;"); - - HtmlTextDecorator htmlTextDecorator = new HtmlTextDecorator(); - List<String> htmlOutput = htmlTextDecorator.decorateTextWithHtml(javadocWithHtml, decorationData, 4, 8); - assertThat(htmlOutput).hasSize(5); - - // Begin from line 4 and finish at line 8 - assertThat(htmlOutput).containsExactly( - "<span class=\"cppd\"> * This framework can used for instance in order to :</span>", - "<span class=\"cppd\"> * <ul></span>", - "<span class=\"cppd\"> * <li>Create a lexer in charge to generate a list of tokens from a character stream</li></span>", - "<span class=\"cppd\"> * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li></span>", - "<span class=\"cppd\"> * <li>Create a javadoc generator</li></span>" - ); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/OpeningHtmlTagTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/OpeningHtmlTagTest.java deleted file mode 100644 index ece48829aa9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/source/OpeningHtmlTagTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.source; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class OpeningHtmlTagTest { - - @Test - public void test_getters() { - OpeningHtmlTag openingHtmlTag = new OpeningHtmlTag(3, "tag"); - assertThat(openingHtmlTag.getStartOffset()).isEqualTo(3); - assertThat(openingHtmlTag.getCssClass()).isEqualTo("tag"); - } - - @Test - public void test_equals() { - OpeningHtmlTag openingHtmlTag = new OpeningHtmlTag(3, "tag"); - OpeningHtmlTag openingHtmlTagWithSameValues = new OpeningHtmlTag(3, "tag"); - OpeningHtmlTag openingHtmlTagWithDifferentValues = new OpeningHtmlTag(5, "tag2"); - OpeningHtmlTag openingHtmlTagWithNoCssClass = new OpeningHtmlTag(3, null); - - assertThat(openingHtmlTag).isEqualTo(openingHtmlTagWithSameValues); - assertThat(openingHtmlTag).isEqualTo(openingHtmlTag); - assertThat(openingHtmlTag).isNotEqualTo(openingHtmlTagWithDifferentValues); - assertThat(openingHtmlTag).isNotEqualTo(openingHtmlTagWithNoCssClass); - assertThat(openingHtmlTag).isNotEqualTo(new OpeningHtmlTag(3, "tag"){}); - } - - @Test - public void test_hashcode() { - OpeningHtmlTag openingHtmlTag = new OpeningHtmlTag(3, "tag"); - OpeningHtmlTag openingHtmlTagWithSameValues = new OpeningHtmlTag(3, "tag"); - OpeningHtmlTag openingHtmlTagWithDifferentValue = new OpeningHtmlTag(5, "tag2"); - - assertThat(openingHtmlTag.hashCode()).isEqualTo(openingHtmlTagWithSameValues.hashCode()); - assertThat(openingHtmlTag.hashCode()).isEqualTo(openingHtmlTag.hashCode()); - assertThat(openingHtmlTag.hashCode()).isNotEqualTo(openingHtmlTagWithDifferentValue.hashCode()); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java deleted file mode 100644 index 58d1c0b1c79..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.source; - -import com.google.common.collect.Lists; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.protobuf.DbFileSources; -import org.sonar.db.source.FileSourceDto; -import org.sonar.server.source.index.FileSourceTesting; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class SourceServiceTest { - - public static final String FILE_UUID = "FILE_UUID"; - - @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - HtmlSourceDecorator htmlDecorator = mock(HtmlSourceDecorator.class); - - SourceService underTest = new SourceService(dbTester.getDbClient(), htmlDecorator); - - @Before - public void injectFakeLines() { - FileSourceDto dto = new FileSourceDto(); - dto.setFileUuid(FILE_UUID).setProjectUuid("PROJECT_UUID"); - dto.setSourceData(FileSourceTesting.newFakeData(10).build()); - dbTester.getDbClient().fileSourceDao().insert(dbTester.getSession(), dto); - dbTester.commit(); - } - - @Test - public void get_range_of_lines() { - Set<Integer> lineNumbers = new HashSet<>(Arrays.asList(1, 5, 6)); - Optional<Iterable<DbFileSources.Line>> linesOpt = underTest.getLines(dbTester.getSession(), FILE_UUID, lineNumbers); - assertThat(linesOpt.isPresent()).isTrue(); - List<DbFileSources.Line> lines = Lists.newArrayList(linesOpt.get()); - assertThat(lines).hasSize(3); - assertThat(lines.get(0).getLine()).isEqualTo(1); - assertThat(lines.get(1).getLine()).isEqualTo(5); - assertThat(lines.get(2).getLine()).isEqualTo(6); - } - - @Test - public void get_set_of_lines() { - Optional<Iterable<DbFileSources.Line>> linesOpt = underTest.getLines(dbTester.getSession(), FILE_UUID, 5, 7); - assertThat(linesOpt.isPresent()).isTrue(); - List<DbFileSources.Line> lines = Lists.newArrayList(linesOpt.get()); - assertThat(lines).hasSize(3); - assertThat(lines.get(0).getLine()).isEqualTo(5); - assertThat(lines.get(1).getLine()).isEqualTo(6); - assertThat(lines.get(2).getLine()).isEqualTo(7); - } - - @Test - public void get_range_of_lines_as_raw_text() { - Optional<Iterable<String>> linesOpt = underTest.getLinesAsRawText(dbTester.getSession(), FILE_UUID, 5, 7); - assertThat(linesOpt.isPresent()).isTrue(); - List<String> lines = Lists.newArrayList(linesOpt.get()); - assertThat(lines).containsExactly("SOURCE_5", "SOURCE_6", "SOURCE_7"); - } - - @Test - public void get_range_of_lines_as_html() { - when(htmlDecorator.getDecoratedSourceAsHtml("SOURCE_5", "HIGHLIGHTING_5", "SYMBOLS_5")).thenReturn("HTML_5"); - when(htmlDecorator.getDecoratedSourceAsHtml("SOURCE_6", "HIGHLIGHTING_6", "SYMBOLS_6")).thenReturn("HTML_6"); - when(htmlDecorator.getDecoratedSourceAsHtml("SOURCE_7", "HIGHLIGHTING_7", "SYMBOLS_7")).thenReturn("HTML_7"); - - Optional<Iterable<String>> linesOpt = underTest.getLinesAsHtml(dbTester.getSession(), FILE_UUID, 5, 7); - assertThat(linesOpt.isPresent()).isTrue(); - List<String> lines = Lists.newArrayList(linesOpt.get()); - assertThat(lines).containsExactly("HTML_5", "HTML_6", "HTML_7"); - } - - @Test - public void getLines_fails_if_range_starts_at_zero() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Line number must start at 1, got 0"); - - underTest.getLines(dbTester.getSession(), FILE_UUID, 0, 2); - } - - @Test - public void getLines_fails_if_range_upper_bound_less_than_lower_bound() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Line number must greater than or equal to 5, got 4"); - - underTest.getLines(dbTester.getSession(), FILE_UUID, 5, 4); - } - - @Test - public void getLines_returns_empty_iterable_if_range_is_out_of_scope() { - Optional<Iterable<DbFileSources.Line>> lines = underTest.getLines(dbTester.getSession(), FILE_UUID, 500, 510); - assertThat(lines.isPresent()).isTrue(); - assertThat(lines.get()).isEmpty(); - } - - @Test - public void getLines_file_does_not_exist() { - Optional<Iterable<DbFileSources.Line>> lines = underTest.getLines(dbTester.getSession(), "FILE_DOES_NOT_EXIST", 1, 10); - assertThat(lines.isPresent()).isFalse(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java b/server/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java deleted file mode 100644 index 9a356bd4ff6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.text; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.platform.Server; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class MacroInterpreterTest { - - String path = "http://sonar"; - MacroInterpreter interpreter; - - @Before - public void setUp() { - Server server = mock(Server.class); - when(server.getContextPath()).thenReturn(path); - interpreter = new MacroInterpreter(server); - } - - @Test - public void should_do_nothing_if_no_macro_detected() { - String origin = "nothing to do"; - String result = interpreter.interpret(origin); - assertThat(result).isEqualTo(origin); - } - - @Test - public void should_replace_rule_macro() { - // key of repository and rule can contain alphanumeric latin characters, dashes, underscores and dots - String ruleKey = "Some_Repo-Key.1:Some_Rule-Key.1"; - String origin = "See {rule:" + ruleKey + "} for detail."; - String result = interpreter.interpret(origin); - // colon should be escaped - assertThat(result).isEqualTo("See <a href='" + path + "/coding_rules#rule_key=Some_Repo-Key.1%3ASome_Rule-Key.1'>Some_Rule-Key.1</a> for detail."); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/DeprecatedViewsTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/DeprecatedViewsTest.java deleted file mode 100644 index a25ff785be7..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/DeprecatedViewsTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ui; - -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.api.web.Page; -import org.sonar.api.web.View; -import org.sonar.api.web.Widget; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DeprecatedViewsTest { - - @Rule - public LogTester logger = new LogTester(); - - private DeprecatedViews underTest; - - @Test - public void no_log_when_no_views() { - underTest = new DeprecatedViews(); - underTest.start(); - - assertThat(logger.logs()).isEmpty(); - } - - @Test - public void log_one_warning_by_view() { - underTest = new DeprecatedViews(new View[] { - new FakePage("governance/my_page", "My Page"), - new FakeWidget("governance/my_widget", "My Widget")}); - assertThat(logger.logs()).isEmpty(); - - underTest.start(); - - assertThat(logger.logs()).hasSize(2); - assertThat(logger.logs(LoggerLevel.WARN)).containsExactly( - "Page 'My Page' (governance/my_page) is ignored. See org.sonar.api.web.page.PageDefinition to define pages.", - "Widget 'My Widget' (governance/my_widget) is ignored. See org.sonar.api.web.page.PageDefinition to define pages."); - } - - private static final class FakeWidget implements Widget { - private final String id; - private final String name; - - private FakeWidget(String id, String name) { - this.id = id; - this.name = name; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getTitle() { - return name; - } - } - - private static class FakePage implements Page { - private final String id; - private final String name; - - FakePage(String id, String name) { - this.id = id; - this.name = name; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getTitle() { - return name; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/PageDecorationsTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/PageDecorationsTest.java deleted file mode 100644 index f255c619ebe..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/PageDecorationsTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ui; - -import org.junit.Test; -import org.sonar.api.web.PageDecoration; - -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class PageDecorationsTest { - - @Test - public void should_not_fail_if_no_decorations() { - assertThat(new PageDecorations().get()).isEmpty(); - } - - @Test - public void should_register_decorations() { - PageDecoration deco1 = mock(PageDecoration.class); - PageDecoration deco2 = mock(PageDecoration.class); - - PageDecorations decorations = new PageDecorations(Arrays.asList(deco1, deco2)); - - assertThat(decorations.get()).hasSize(2); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/PageRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/PageRepositoryTest.java deleted file mode 100644 index 6202f24b2a9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/PageRepositoryTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ui; - -import java.util.List; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.web.page.Page; -import org.sonar.api.web.page.Page.Qualifier; -import org.sonar.api.web.page.PageDefinition; -import org.sonar.core.platform.PluginInfo; -import org.sonar.core.platform.PluginRepository; -import org.sonar.core.extension.CoreExtensionRepository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.web.page.Page.Scope.COMPONENT; -import static org.sonar.api.web.page.Page.Scope.GLOBAL; -import static org.sonar.api.web.page.Page.Scope.ORGANIZATION; - -public class PageRepositoryTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public LogTester logTester = new LogTester(); - - private PluginRepository pluginRepository = mock(PluginRepository.class); - private CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class); - - private PageRepository underTest = new PageRepository(pluginRepository, coreExtensionRepository); - - @Before - public void setUp() { - when(pluginRepository.hasPlugin(any())).thenReturn(true); - when(pluginRepository.getPluginInfo(any())).thenReturn(new PluginInfo("unused")); - } - - @Test - public void pages_from_different_page_definitions_ordered_by_key() { - PageDefinition firstPlugin = context -> context - .addPage(Page.builder("my_plugin/K1").setName("N1").build()) - .addPage(Page.builder("my_plugin/K3").setName("N3").build()); - PageDefinition secondPlugin = context -> context.addPage(Page.builder("my_plugin/K2").setName("N2").build()); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{firstPlugin, secondPlugin}); - underTest.start(); - - List<Page> result = underTest.getAllPages(); - - assertThat(result) - .extracting(Page::getKey, Page::getName) - .containsExactly( - tuple("my_plugin/K1", "N1"), - tuple("my_plugin/K2", "N2"), - tuple("my_plugin/K3", "N3")); - } - - @Test - public void filter_by_navigation_and_qualifier() { - PageDefinition plugin = context -> context - // Default with GLOBAL navigation and no qualifiers - .addPage(Page.builder("my_plugin/K1").setName("K1").build()) - .addPage(Page.builder("my_plugin/K2").setName("K2").setScope(COMPONENT).setComponentQualifiers(Qualifier.PROJECT).build()) - .addPage(Page.builder("my_plugin/K3").setName("K3").setScope(COMPONENT).setComponentQualifiers(Qualifier.MODULE).build()) - .addPage(Page.builder("my_plugin/K4").setName("K4").setScope(GLOBAL).build()) - .addPage(Page.builder("my_plugin/K5").setName("K5").setScope(COMPONENT).setComponentQualifiers(Qualifier.VIEW).build()) - .addPage(Page.builder("my_plugin/K6").setName("K6").setScope(COMPONENT).setComponentQualifiers(Qualifier.APP).build()); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{plugin}); - underTest.start(); - - List<Page> result = underTest.getComponentPages(false, Qualifiers.PROJECT); - - assertThat(result) - .extracting(Page::getKey) - .containsExactly("my_plugin/K2"); - } - - @Test - public void empty_pages_if_no_page_definition() { - underTest.start(); - - List<Page> result = underTest.getAllPages(); - - assertThat(result).isEmpty(); - } - - @Test - public void filter_pages_without_qualifier() { - PageDefinition plugin = context -> context - .addPage(Page.builder("my_plugin/K1").setName("N1").build()) - .addPage(Page.builder("my_plugin/K2").setName("N2").build()) - .addPage(Page.builder("my_plugin/K3").setName("N3").build()); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{plugin}); - underTest.start(); - - List<Page> result = underTest.getGlobalPages(false); - - assertThat(result) - .extracting(Page::getKey) - .containsExactly("my_plugin/K1", "my_plugin/K2", "my_plugin/K3"); - } - - @Test - public void get_organization_pages() { - PageDefinition plugin = context -> context - .addPage(Page.builder("my_plugin/G1").setName("G1").setScope(GLOBAL).build()) - .addPage(Page.builder("my_plugin/C1").setName("C1").setScope(COMPONENT).build()) - .addPage(Page.builder("my_plugin/O1").setName("O1").setScope(ORGANIZATION).build()) - .addPage(Page.builder("my_plugin/O2").setName("O2").setScope(ORGANIZATION).build()) - .addPage(Page.builder("my_plugin/O3").setName("O3").setScope(ORGANIZATION).build()) - .addPage(Page.builder("my_plugin/OA1").setName("OA1").setScope(ORGANIZATION).setAdmin(true).build()); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{plugin}); - underTest.start(); - - List<Page> result = underTest.getOrganizationPages(false); - - assertThat(result) - .extracting(Page::getKey) - .containsExactly("my_plugin/O1", "my_plugin/O2", "my_plugin/O3"); - } - - @Test - public void get_organization_admin_pages() { - PageDefinition plugin = context -> context - .addPage(Page.builder("my_plugin/O1").setName("O1").setScope(ORGANIZATION).build()) - .addPage(Page.builder("my_plugin/O2").setName("O2").setScope(ORGANIZATION).setAdmin(true).build()); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{plugin}); - underTest.start(); - - List<Page> result = underTest.getOrganizationPages(true); - - assertThat(result) - .extracting(Page::getKey) - .containsExactly("my_plugin/O2"); - } - - @Test - public void fail_if_pages_called_before_server_startup() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("Pages haven't been initialized yet"); - - underTest.getAllPages(); - } - - @Test - public void fail_if_page_with_unknown_plugin() { - PageDefinition governance = context -> context.addPage(Page.builder("governance/my_key").setName("N1").build()); - PageDefinition plugin42 = context -> context.addPage(Page.builder("plugin_42/my_key").setName("N2").build()); - pluginRepository = mock(PluginRepository.class); - when(pluginRepository.hasPlugin("governance")).thenReturn(true); - underTest = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{governance, plugin42}); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Page 'N2' references plugin 'plugin_42' that does not exist"); - - underTest.start(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/VersionFormatterTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/VersionFormatterTest.java deleted file mode 100644 index 35b65e8f720..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/VersionFormatterTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ui; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class VersionFormatterTest { - @Test - public void format_technical_version() { - assertThat(format("6.3")).isEqualTo("6.3"); - assertThat(format("6.3.2")).isEqualTo("6.3.2"); - assertThat(format("6.3.2.5498")).isEqualTo("6.3.2 (build 5498)"); - assertThat(format("6.3.0.5499")).isEqualTo("6.3 (build 5499)"); - } - - private static String format(String technicalVersion) { - return VersionFormatter.format(technicalVersion); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/WebAnalyticsLoaderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/WebAnalyticsLoaderImplTest.java deleted file mode 100644 index e7be923df8e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/WebAnalyticsLoaderImplTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.ui; - -import org.junit.Test; -import org.sonar.api.utils.MessageException; -import org.sonar.api.web.WebAnalytics; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WebAnalyticsLoaderImplTest { - - @Test - public void return_empty_if_no_analytics_plugin() { - assertThat(new WebAnalyticsLoaderImpl().getUrlPathToJs()).isEmpty(); - assertThat(new WebAnalyticsLoaderImpl(new WebAnalytics[0]).getUrlPathToJs()).isEmpty(); - } - - @Test - public void return_js_path_if_analytics_plugin_is_installed() { - WebAnalytics analytics = newWebAnalytics("api/google/analytics"); - WebAnalyticsLoaderImpl underTest = new WebAnalyticsLoaderImpl(new WebAnalytics[] {analytics}); - - assertThat(underTest.getUrlPathToJs()).hasValue("/api/google/analytics"); - } - - @Test - public void return_empty_if_path_starts_with_slash() { - WebAnalytics analytics = newWebAnalytics("/api/google/analytics"); - WebAnalyticsLoaderImpl underTest = new WebAnalyticsLoaderImpl(new WebAnalytics[] {analytics}); - - assertThat(underTest.getUrlPathToJs()).isEmpty(); - } - - @Test - public void return_empty_if_path_is_an_url() { - WebAnalytics analytics = newWebAnalytics("http://foo"); - WebAnalyticsLoaderImpl underTest = new WebAnalyticsLoaderImpl(new WebAnalytics[] {analytics}); - - assertThat(underTest.getUrlPathToJs()).isEmpty(); - } - - @Test - public void return_empty_if_path_has_up_operation() { - WebAnalytics analytics = newWebAnalytics("foo/../bar"); - WebAnalyticsLoaderImpl underTest = new WebAnalyticsLoaderImpl(new WebAnalytics[] {analytics}); - - assertThat(underTest.getUrlPathToJs()).isEmpty(); - } - - @Test - public void fail_if_multiple_analytics_plugins_are_installed() { - WebAnalytics analytics1 = newWebAnalytics("foo"); - WebAnalytics analytics2 = newWebAnalytics("bar"); - - Throwable thrown = catchThrowable(() -> new WebAnalyticsLoaderImpl(new WebAnalytics[] {analytics1, analytics2})); - - assertThat(thrown) - .isInstanceOf(MessageException.class) - .hasMessage("Limited to only one web analytics plugin. Found multiple implementations: [" + - analytics1.getClass().getName() + ", " + analytics2.getClass().getName() + "]"); - } - - private static WebAnalytics newWebAnalytics(String path) { - WebAnalytics analytics = mock(WebAnalytics.class); - when(analytics.getUrlPathToJs()).thenReturn(path); - return analytics; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/util/LanguageParamUtilsTest.java b/server/sonar-server/src/test/java/org/sonar/server/util/LanguageParamUtilsTest.java deleted file mode 100644 index ba47e982444..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/util/LanguageParamUtilsTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.util; - -import org.junit.Test; -import org.sonar.api.resources.AbstractLanguage; -import org.sonar.api.resources.Languages; - -import static org.assertj.core.api.Assertions.assertThat; - -public class LanguageParamUtilsTest { - - @Test - public void getOrderedLanguageKeys() { - assertThat(LanguageParamUtils.getOrderedLanguageKeys(new Languages())).isEmpty(); - - Languages languages = new Languages( - new TestLanguage("java"), - new TestLanguage("abap"), - new TestLanguage("js"), - new TestLanguage("cobol")); - assertThat(LanguageParamUtils.getOrderedLanguageKeys(languages)).containsExactly("abap", "cobol", "java", "js"); - } - - private static class TestLanguage extends AbstractLanguage { - TestLanguage(String key) { - super(key); - } - - @Override - public String[] getFileSuffixes() { - return new String[0]; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookQGChangeEventListenerTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookQGChangeEventListenerTest.java deleted file mode 100644 index 7d82731e6a3..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/webhook/WebhookQGChangeEventListenerTest.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.webhook; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.sonar.api.config.Configuration; -import org.sonar.api.measures.Metric; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.AnalysisPropertyDto; -import org.sonar.db.component.BranchDto; -import org.sonar.db.component.BranchType; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.SnapshotDto; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.qualitygate.EvaluatedQualityGate; -import org.sonar.server.qualitygate.changeevent.QGChangeEvent; -import org.sonar.server.qualitygate.changeevent.QGChangeEventListener; - -import static java.util.Arrays.stream; -import static java.util.Collections.emptySet; -import static java.util.stream.Stream.concat; -import static java.util.stream.Stream.of; -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.sonar.core.util.stream.MoreCollectors.toArrayList; -import static org.sonar.db.component.BranchType.LONG; -import static org.sonar.db.component.BranchType.SHORT; -import static org.sonar.db.component.ComponentTesting.newBranchDto; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; - -@RunWith(DataProviderRunner.class) -public class WebhookQGChangeEventListenerTest { - - private static final Set<QGChangeEventListener.ChangedIssue> CHANGED_ISSUES_ARE_IGNORED = emptySet(); - - @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - - private DbClient dbClient = dbTester.getDbClient(); - - private EvaluatedQualityGate newQualityGate = mock(EvaluatedQualityGate.class); - private WebHooks webHooks = mock(WebHooks.class); - private WebhookPayloadFactory webhookPayloadFactory = mock(WebhookPayloadFactory.class); - private DbClient spiedOnDbClient = Mockito.spy(dbClient); - private WebhookQGChangeEventListener underTest = new WebhookQGChangeEventListener(webHooks, webhookPayloadFactory, spiedOnDbClient); - private DbClient mockedDbClient = mock(DbClient.class); - private WebhookQGChangeEventListener mockedUnderTest = new WebhookQGChangeEventListener(webHooks, webhookPayloadFactory, mockedDbClient); - - @Test - @UseDataProvider("allCombinationsOfStatuses") - public void onIssueChanges_has_no_effect_if_no_webhook_is_configured(Metric.Level previousStatus, Metric.Level newStatus) { - Configuration configuration1 = mock(Configuration.class); - when(newQualityGate.getStatus()).thenReturn(newStatus); - QGChangeEvent qualityGateEvent = newQGChangeEvent(configuration1, previousStatus, newQualityGate); - mockWebhookDisabled(qualityGateEvent.getProject()); - - mockedUnderTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - verify(webHooks).isEnabled(qualityGateEvent.getProject()); - verifyZeroInteractions(webhookPayloadFactory, mockedDbClient); - } - - @DataProvider - public static Object[][] allCombinationsOfStatuses() { - Metric.Level[] levelsAndNull = concat(of((Metric.Level) null), stream(Metric.Level.values())) - .toArray(Metric.Level[]::new); - Object[][] res = new Object[levelsAndNull.length * levelsAndNull.length][2]; - int i = 0; - for (Metric.Level previousStatus : Arrays.asList(levelsAndNull)) { - for (Metric.Level newStatus : Arrays.asList(levelsAndNull)) { - res[i][0] = previousStatus; - res[i][1] = newStatus; - i++; - } - } - return res; - } - - @Test - public void onIssueChanges_has_no_effect_if_event_has_neither_previousQGStatus_nor_qualityGate() { - Configuration configuration = mock(Configuration.class); - QGChangeEvent qualityGateEvent = newQGChangeEvent(configuration, null, null); - mockWebhookEnabled(qualityGateEvent.getProject()); - - underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - verifyZeroInteractions(webhookPayloadFactory, mockedDbClient); - } - - @Test - public void onIssueChanges_has_no_effect_if_event_has_same_status_in_previous_and_new_QG() { - Configuration configuration = mock(Configuration.class); - Metric.Level previousStatus = randomLevel(); - when(newQualityGate.getStatus()).thenReturn(previousStatus); - QGChangeEvent qualityGateEvent = newQGChangeEvent(configuration, previousStatus, newQualityGate); - mockWebhookEnabled(qualityGateEvent.getProject()); - - underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - verifyZeroInteractions(webhookPayloadFactory, mockedDbClient); - } - - @Test - @UseDataProvider("newQGorNot") - public void onIssueChanges_calls_webhook_for_changeEvent_with_webhook_enabled(@Nullable EvaluatedQualityGate newQualityGate) { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto project = dbTester.components().insertPublicProject(organization); - ComponentAndBranch branch = insertProjectBranch(project, BranchType.SHORT, "foo"); - SnapshotDto analysis = insertAnalysisTask(branch); - Configuration configuration = mock(Configuration.class); - mockPayloadSupplierConsumedByWebhooks(); - Map<String, String> properties = new HashMap<>(); - properties.put("sonar.analysis.test1", randomAlphanumeric(50)); - properties.put("sonar.analysis.test2", randomAlphanumeric(5000)); - insertPropertiesFor(analysis.getUuid(), properties); - QGChangeEvent qualityGateEvent = newQGChangeEvent(branch, analysis, configuration, newQualityGate); - mockWebhookEnabled(qualityGateEvent.getProject()); - - underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - ProjectAnalysis projectAnalysis = verifyWebhookCalledAndExtractPayloadFactoryArgument(branch, analysis, qualityGateEvent.getProject()); - assertThat(projectAnalysis).isEqualTo( - new ProjectAnalysis( - new Project(project.uuid(), project.getKey(), project.name()), - null, - new Analysis(analysis.getUuid(), analysis.getCreatedAt(), analysis.getRevision()), - new Branch(false, "foo", Branch.Type.SHORT), - newQualityGate, - null, - properties)); - } - - @Test - @UseDataProvider("newQGorNot") - public void onIssueChanges_calls_webhook_on_main_branch(@Nullable EvaluatedQualityGate newQualityGate) { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentAndBranch mainBranch = insertMainBranch(organization); - SnapshotDto analysis = insertAnalysisTask(mainBranch); - Configuration configuration = mock(Configuration.class); - QGChangeEvent qualityGateEvent = newQGChangeEvent(mainBranch, analysis, configuration, newQualityGate); - mockWebhookEnabled(qualityGateEvent.getProject()); - - underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - verifyWebhookCalled(mainBranch, analysis, qualityGateEvent.getProject()); - } - - @Test - public void onIssueChanges_calls_webhook_on_long_branch() { - onIssueChangesCallsWebhookOnBranch(BranchType.LONG); - } - - @Test - public void onIssueChanges_calls_webhook_on_short_branch() { - onIssueChangesCallsWebhookOnBranch(SHORT); - } - - public void onIssueChangesCallsWebhookOnBranch(BranchType branchType) { - OrganizationDto organization = dbTester.organizations().insert(); - ComponentAndBranch mainBranch = insertMainBranch(organization); - ComponentAndBranch longBranch = insertProjectBranch(mainBranch.component, branchType, "foo"); - SnapshotDto analysis = insertAnalysisTask(longBranch); - Configuration configuration = mock(Configuration.class); - QGChangeEvent qualityGateEvent = newQGChangeEvent(longBranch, analysis, configuration, null); - mockWebhookEnabled(qualityGateEvent.getProject()); - - underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); - - verifyWebhookCalled(longBranch, analysis, qualityGateEvent.getProject()); - } - - @DataProvider - public static Object[][] newQGorNot() { - EvaluatedQualityGate newQualityGate = mock(EvaluatedQualityGate.class); - return new Object[][] { - {null}, - {newQualityGate} - }; - } - - private void mockWebhookEnabled(ComponentDto... projects) { - for (ComponentDto dto : projects) { - when(webHooks.isEnabled(dto)).thenReturn(true); - } - } - - private void mockWebhookDisabled(ComponentDto... projects) { - for (ComponentDto dto : projects) { - when(webHooks.isEnabled(dto)).thenReturn(false); - } - } - - private void mockPayloadSupplierConsumedByWebhooks() { - Mockito.doAnswer(invocationOnMock -> { - Supplier<WebhookPayload> supplier = (Supplier<WebhookPayload>) invocationOnMock.getArguments()[1]; - supplier.get(); - return null; - }).when(webHooks) - .sendProjectAnalysisUpdate(any(), any()); - } - - private void insertPropertiesFor(String snapshotUuid, Map<String, String> properties) { - List<AnalysisPropertyDto> analysisProperties = properties.entrySet().stream() - .map(entry -> new AnalysisPropertyDto() - .setUuid(UuidFactoryFast.getInstance().create()) - .setAnalysisUuid(snapshotUuid) - .setKey(entry.getKey()) - .setValue(entry.getValue())) - .collect(toArrayList(properties.size())); - dbTester.getDbClient().analysisPropertiesDao().insert(dbTester.getSession(), analysisProperties); - dbTester.getSession().commit(); - } - - private SnapshotDto insertAnalysisTask(ComponentAndBranch componentAndBranch) { - return dbTester.components().insertSnapshot(componentAndBranch.component); - } - - private ProjectAnalysis verifyWebhookCalledAndExtractPayloadFactoryArgument(ComponentAndBranch componentAndBranch, SnapshotDto analysis, ComponentDto project) { - verifyWebhookCalled(componentAndBranch, analysis, project); - - return extractPayloadFactoryArguments(1).iterator().next(); - } - - private void verifyWebhookCalled(ComponentAndBranch componentAndBranch, SnapshotDto analysis, ComponentDto project) { - verify(webHooks).isEnabled(project); - verify(webHooks).sendProjectAnalysisUpdate( - eq(new WebHooks.Analysis(componentAndBranch.uuid(), analysis.getUuid(), null)), - any()); - } - - private List<ProjectAnalysis> extractPayloadFactoryArguments(int time) { - ArgumentCaptor<ProjectAnalysis> projectAnalysisCaptor = ArgumentCaptor.forClass(ProjectAnalysis.class); - verify(webhookPayloadFactory, Mockito.times(time)).create(projectAnalysisCaptor.capture()); - return projectAnalysisCaptor.getAllValues(); - } - - public ComponentAndBranch insertMainBranch(OrganizationDto organization) { - ComponentDto project = newPrivateProjectDto(organization); - BranchDto branch = newBranchDto(project, LONG).setKey("master"); - dbTester.components().insertComponent(project); - dbClient.branchDao().insert(dbTester.getSession(), branch); - dbTester.commit(); - return new ComponentAndBranch(project, branch); - } - - public ComponentAndBranch insertProjectBranch(ComponentDto project, BranchType type, String branchKey) { - BranchDto branchDto = newBranchDto(project.projectUuid(), type).setKey(branchKey); - ComponentDto newComponent = dbTester.components().insertProjectBranch(project, branchDto); - return new ComponentAndBranch(newComponent, branchDto); - } - - private static class ComponentAndBranch { - private final ComponentDto component; - - private final BranchDto branch; - - private ComponentAndBranch(ComponentDto component, BranchDto branch) { - this.component = component; - this.branch = branch; - } - - public ComponentDto getComponent() { - return component; - } - - public BranchDto getBranch() { - return branch; - } - - public String uuid() { - return component.uuid(); - } - - } - - private static QGChangeEvent newQGChangeEvent(Configuration configuration, @Nullable Metric.Level previousQQStatus, @Nullable EvaluatedQualityGate evaluatedQualityGate) { - return new QGChangeEvent(new ComponentDto(), new BranchDto(), new SnapshotDto(), configuration, previousQQStatus, () -> Optional.ofNullable(evaluatedQualityGate)); - } - - private static QGChangeEvent newQGChangeEvent(ComponentAndBranch branch, SnapshotDto analysis, Configuration configuration, @Nullable EvaluatedQualityGate evaluatedQualityGate) { - Metric.Level previousStatus = randomLevel(); - if (evaluatedQualityGate != null) { - Metric.Level otherLevel = stream(Metric.Level.values()) - .filter(s -> s != previousStatus) - .toArray(Metric.Level[]::new)[new Random().nextInt(Metric.Level.values().length - 1)]; - when(evaluatedQualityGate.getStatus()).thenReturn(otherLevel); - } - return new QGChangeEvent(branch.component, branch.branch, analysis, configuration, previousStatus, () -> Optional.ofNullable(evaluatedQualityGate)); - } - - private static Metric.Level randomLevel() { - return Metric.Level.values()[new Random().nextInt(Metric.Level.values().length)]; - } - -} diff --git a/server/sonar-server/src/test/projects/.gitignore b/server/sonar-server/src/test/projects/.gitignore deleted file mode 100644 index a945b8525e6..00000000000 --- a/server/sonar-server/src/test/projects/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# see README.txt -!*/target/ -*/target/classes/ -*/target/maven-archiver/ -*/target/maven-status/ -*/target/test-*/ - diff --git a/server/sonar-server/src/test/projects/README.txt b/server/sonar-server/src/test/projects/README.txt deleted file mode 100644 index c53a66d52f2..00000000000 --- a/server/sonar-server/src/test/projects/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This directory provides the fake plugins used by tests. These tests are rarely changed, so generated -artifacts are stored in Git repository (see .gitignore). It avoids from adding unnecessary modules -to build. diff --git a/server/sonar-server/src/test/projects/fake-report-plugin/pom.xml b/server/sonar-server/src/test/projects/fake-report-plugin/pom.xml deleted file mode 100644 index 72a04dbe04f..00000000000 --- a/server/sonar-server/src/test/projects/fake-report-plugin/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>fake-report-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Fake Report Plugin</name> - <description>Fake Report Plugin</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>report</pluginKey> - <pluginClass>BasePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/fake-report-plugin/src/BasePlugin.java b/server/sonar-server/src/test/projects/fake-report-plugin/src/BasePlugin.java deleted file mode 100644 index d12daff3e57..00000000000 --- a/server/sonar-server/src/test/projects/fake-report-plugin/src/BasePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class BasePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/fake-report-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java b/server/sonar-server/src/test/projects/fake-report-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java deleted file mode 100644 index e0b54398eaf..00000000000 --- a/server/sonar-server/src/test/projects/fake-report-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.testbase.api; - -public class BaseApi { - public void doNothing() { - } -} diff --git a/server/sonar-server/src/test/projects/fake-report-plugin/target/fake-report-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/fake-report-plugin/target/fake-report-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 6085e44fdca..00000000000 --- a/server/sonar-server/src/test/projects/fake-report-plugin/target/fake-report-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/fake-sqale-plugin/pom.xml b/server/sonar-server/src/test/projects/fake-sqale-plugin/pom.xml deleted file mode 100644 index e417dd96fba..00000000000 --- a/server/sonar-server/src/test/projects/fake-sqale-plugin/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>fake-sqale-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Fake SQALE Plugin</name> - <description>Fake SQALE Plugin</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>sqale</pluginKey> - <pluginClass>BasePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/fake-sqale-plugin/src/BasePlugin.java b/server/sonar-server/src/test/projects/fake-sqale-plugin/src/BasePlugin.java deleted file mode 100644 index d12daff3e57..00000000000 --- a/server/sonar-server/src/test/projects/fake-sqale-plugin/src/BasePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class BasePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/fake-sqale-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java b/server/sonar-server/src/test/projects/fake-sqale-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java deleted file mode 100644 index e0b54398eaf..00000000000 --- a/server/sonar-server/src/test/projects/fake-sqale-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.testbase.api; - -public class BaseApi { - public void doNothing() { - } -} diff --git a/server/sonar-server/src/test/projects/fake-sqale-plugin/target/fake-sqale-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/fake-sqale-plugin/target/fake-sqale-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index b5c99f721b3..00000000000 --- a/server/sonar-server/src/test/projects/fake-sqale-plugin/target/fake-sqale-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/fake-views-plugin/pom.xml b/server/sonar-server/src/test/projects/fake-views-plugin/pom.xml deleted file mode 100644 index 1ef73d2ffda..00000000000 --- a/server/sonar-server/src/test/projects/fake-views-plugin/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>fake-views-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Fake Views Plugin</name> - <description>Fake Views Plugin</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>views</pluginKey> - <pluginClass>BasePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/fake-views-plugin/src/BasePlugin.java b/server/sonar-server/src/test/projects/fake-views-plugin/src/BasePlugin.java deleted file mode 100644 index d12daff3e57..00000000000 --- a/server/sonar-server/src/test/projects/fake-views-plugin/src/BasePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class BasePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/fake-views-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java b/server/sonar-server/src/test/projects/fake-views-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java deleted file mode 100644 index e0b54398eaf..00000000000 --- a/server/sonar-server/src/test/projects/fake-views-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.testbase.api; - -public class BaseApi { - public void doNothing() { - } -} diff --git a/server/sonar-server/src/test/projects/fake-views-plugin/target/fake-views-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/fake-views-plugin/target/fake-views-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index a47d93d94a8..00000000000 --- a/server/sonar-server/src/test/projects/fake-views-plugin/target/fake-views-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/pom.xml b/server/sonar-server/src/test/projects/pom.xml deleted file mode 100644 index 37338313ac0..00000000000 --- a/server/sonar-server/src/test/projects/pom.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>parent</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>pom</packaging> - <modules> - <module>test-base-plugin</module> - <module>test-base-plugin-v2</module> - <module>test-core-plugin</module> - <module>test-extend-plugin</module> - <module>test-libs-plugin</module> - <module>test-require-plugin</module> - <module>test-requirenew-plugin</module> - <module>fake-report-plugin</module> - <module>fake-sqale-plugin</module> - <module>fake-views-plugin</module> - </modules> - -</project> diff --git a/server/sonar-server/src/test/projects/test-base-plugin-v2/pom.xml b/server/sonar-server/src/test/projects/test-base-plugin-v2/pom.xml deleted file mode 100644 index 982be1c0170..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin-v2/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-base-plugin</artifactId> - <version>0.2-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Base Plugin</name> - <description>Simple standalone plugin. Used by other fake plugins.</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testbase</pluginKey> - <pluginClass>BasePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-base-plugin-v2/src/BasePlugin.java b/server/sonar-server/src/test/projects/test-base-plugin-v2/src/BasePlugin.java deleted file mode 100644 index d12daff3e57..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin-v2/src/BasePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class BasePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-base-plugin-v2/src/org/sonar/plugins/testbase/api/BaseApi.java b/server/sonar-server/src/test/projects/test-base-plugin-v2/src/org/sonar/plugins/testbase/api/BaseApi.java deleted file mode 100644 index e0b54398eaf..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin-v2/src/org/sonar/plugins/testbase/api/BaseApi.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.testbase.api; - -public class BaseApi { - public void doNothing() { - } -} diff --git a/server/sonar-server/src/test/projects/test-base-plugin-v2/target/test-base-plugin-0.2-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-base-plugin-v2/target/test-base-plugin-0.2-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 1d4ef5430c7..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin-v2/target/test-base-plugin-0.2-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-base-plugin/pom.xml b/server/sonar-server/src/test/projects/test-base-plugin/pom.xml deleted file mode 100644 index c4e95936e74..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-base-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Base Plugin</name> - <description>Simple standalone plugin. Used by other fake plugins.</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testbase</pluginKey> - <pluginClass>BasePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-base-plugin/src/BasePlugin.java b/server/sonar-server/src/test/projects/test-base-plugin/src/BasePlugin.java deleted file mode 100644 index d12daff3e57..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin/src/BasePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class BasePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-base-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java b/server/sonar-server/src/test/projects/test-base-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java deleted file mode 100644 index e0b54398eaf..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin/src/org/sonar/plugins/testbase/api/BaseApi.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.testbase.api; - -public class BaseApi { - public void doNothing() { - } -} diff --git a/server/sonar-server/src/test/projects/test-base-plugin/target/test-base-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-base-plugin/target/test-base-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 739a22fcdae..00000000000 --- a/server/sonar-server/src/test/projects/test-base-plugin/target/test-base-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-core-plugin/pom.xml b/server/sonar-server/src/test/projects/test-core-plugin/pom.xml deleted file mode 100644 index d3e86d6cf95..00000000000 --- a/server/sonar-server/src/test/projects/test-core-plugin/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-core-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Test Core Plugin</name> - <description>Fake core plugin used by tests</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>core</pluginKey> - <pluginClass>CorePlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-core-plugin/src/CorePlugin.java b/server/sonar-server/src/test/projects/test-core-plugin/src/CorePlugin.java deleted file mode 100644 index 29bc924ff25..00000000000 --- a/server/sonar-server/src/test/projects/test-core-plugin/src/CorePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class CorePlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-core-plugin/target/test-core-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-core-plugin/target/test-core-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 831cc364b5c..00000000000 --- a/server/sonar-server/src/test/projects/test-core-plugin/target/test-core-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-extend-plugin/pom.xml b/server/sonar-server/src/test/projects/test-extend-plugin/pom.xml deleted file mode 100644 index e23667e6318..00000000000 --- a/server/sonar-server/src/test/projects/test-extend-plugin/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-extend-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Test Extend Plugin</name> - <description>Fake plugin that extends the plugin with key "base"</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testextend</pluginKey> - <pluginClass>ExtendPlugin</pluginClass> - <basePlugin>testbase</basePlugin> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-extend-plugin/src/ExtendPlugin.java b/server/sonar-server/src/test/projects/test-extend-plugin/src/ExtendPlugin.java deleted file mode 100644 index d364a2f9dd4..00000000000 --- a/server/sonar-server/src/test/projects/test-extend-plugin/src/ExtendPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class ExtendPlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-extend-plugin/target/test-extend-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-extend-plugin/target/test-extend-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 2f63c2e652c..00000000000 --- a/server/sonar-server/src/test/projects/test-extend-plugin/target/test-extend-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-libs-plugin/pom.xml b/server/sonar-server/src/test/projects/test-libs-plugin/pom.xml deleted file mode 100644 index 2d49cca2cf2..00000000000 --- a/server/sonar-server/src/test/projects/test-libs-plugin/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-libs-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Test Libs Plugin</name> - <description>Fake plugin that embeds some libraries</description> - - <dependencies> - <!-- embedded libs. Chosen because small ! --> - <dependency> - <groupId>commons-email</groupId> - <artifactId>commons-email</artifactId> - <version>20030310.165926</version> - </dependency> - <dependency> - <groupId>commons-daemon</groupId> - <artifactId>commons-daemon</artifactId> - <version>1.0.15</version> - </dependency> - - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - </dependencies> - - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testlibs</pluginKey> - <pluginClass>LibsPlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-libs-plugin/src/LibsPlugin.java b/server/sonar-server/src/test/projects/test-libs-plugin/src/LibsPlugin.java deleted file mode 100644 index 7e3ebe0909c..00000000000 --- a/server/sonar-server/src/test/projects/test-libs-plugin/src/LibsPlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class LibsPlugin extends Plugin { - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-libs-plugin/target/test-libs-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-libs-plugin/target/test-libs-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 6ebe8652d8b..00000000000 --- a/server/sonar-server/src/test/projects/test-libs-plugin/target/test-libs-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-require-plugin/pom.xml b/server/sonar-server/src/test/projects/test-require-plugin/pom.xml deleted file mode 100644 index 62462ffbf34..00000000000 --- a/server/sonar-server/src/test/projects/test-require-plugin/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-require-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Test Require Plugin</name> - <description>This fake plugin depends on test-base-plugin</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-base-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <type>sonar-plugin</type> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testrequire</pluginKey> - <pluginClass>RequirePlugin</pluginClass> - <requirePlugins>testbase:0.1</requirePlugins> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-require-plugin/src/RequirePlugin.java b/server/sonar-server/src/test/projects/test-require-plugin/src/RequirePlugin.java deleted file mode 100644 index 847ae2d994e..00000000000 --- a/server/sonar-server/src/test/projects/test-require-plugin/src/RequirePlugin.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class RequirePlugin extends Plugin { - - public RequirePlugin() { - // call a class that is in the api published by the base plugin - new org.sonar.plugins.testbase.api.BaseApi().doNothing(); - } - - public void define(Plugin.Context context) { - - } -} diff --git a/server/sonar-server/src/test/projects/test-require-plugin/target/test-require-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-require-plugin/target/test-require-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index f5fc95f9d0d..00000000000 --- a/server/sonar-server/src/test/projects/test-require-plugin/target/test-require-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/projects/test-requirenew-plugin/pom.xml b/server/sonar-server/src/test/projects/test-requirenew-plugin/pom.xml deleted file mode 100644 index 044cd94e8f0..00000000000 --- a/server/sonar-server/src/test/projects/test-requirenew-plugin/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-requirenew-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>sonar-plugin</packaging> - <name>Test Require New Plugin</name> - <description>This fake plugin requires a version of test-base-plugin that is not installed</description> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <version>4.5.4</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.sonarsource.sonarqube.tests</groupId> - <artifactId>test-base-plugin</artifactId> - <version>0.1-SNAPSHOT</version> - <type>sonar-plugin</type> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <version>1.15</version> - <extensions>true</extensions> - <configuration> - <pluginKey>testrequire</pluginKey> - <pluginClass>RequirePlugin</pluginClass> - <requirePlugins>testbase:0.2</requirePlugins> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/server/sonar-server/src/test/projects/test-requirenew-plugin/src/RequirePlugin.java b/server/sonar-server/src/test/projects/test-requirenew-plugin/src/RequirePlugin.java deleted file mode 100644 index 0d14cde33c1..00000000000 --- a/server/sonar-server/src/test/projects/test-requirenew-plugin/src/RequirePlugin.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import org.sonar.api.Plugin; - -import java.util.Collections; -import java.util.List; - -public class RequirePlugin extends Plugin { - - public RequirePlugin() { - // call a class that is in the api published by the base plugin - new org.sonar.plugins.testbase.api.BaseApi().doNothing(); - } - - public void define(Plugin.Context context) { - - } - -} diff --git a/server/sonar-server/src/test/projects/test-requirenew-plugin/target/test-requirenew-plugin-0.1-SNAPSHOT.jar b/server/sonar-server/src/test/projects/test-requirenew-plugin/target/test-requirenew-plugin-0.1-SNAPSHOT.jar Binary files differdeleted file mode 100644 index 0dd577fc360..00000000000 --- a/server/sonar-server/src/test/projects/test-requirenew-plugin/target/test-requirenew-plugin-0.1-SNAPSHOT.jar +++ /dev/null diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml deleted file mode 100644 index 4a41aa0b275..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileBackuperMediumTest/duplicates-xml-backup.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<profile> - <name>P1</name> - <language>xoo</language> - <rules> - <rule> - <repositoryKey>xoo</repositoryKey> - <key>x1</key> - <priority>BLOCKER</priority> - <parameters> - <parameter> - <key>max</key> - <value>7</value> - </parameter> - </parameters> - </rule> - <rule> - <repositoryKey>xoo</repositoryKey> - <key>x2</key> - <priority>CRITICAL</priority> - </rule> - <rule> - <repositoryKey>xoo</repositoryKey> - <key>x1</key> - <priority>MAJOR</priority> - <parameters> - <parameter> - <key>max</key> - <value>5</value> - </parameter> - </parameters> - </rule> - <rule> - <repositoryKey>xoo</repositoryKey> - <key>x2</key> - <priority>MINOR</priority> - </rule> - - </rules> -</profile> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule25.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule25.json deleted file mode 100644 index c38e4a347f9..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule25.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 25, - "severity": "MINOR", - "profileId": 1, - "inheritance": null -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule391.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule391.json deleted file mode 100644 index fb70c854fde..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_active_rules_with_inheritance/active_rule391.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "id": 391, - "severity": "MINOR", - "profileId": 2, - "inheritance": "INHERITED", - "activeRuleParentId": 25 -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_A.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_A.json deleted file mode 100644 index bcd7657a309..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_A.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 2303, - "key": "RuleA", - "language": "xoo", - "name": "A first rule", - "description": "First rule of Fight Club is: you do not talk about Fight Club.", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_C.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_C.json deleted file mode 100644 index edd28e543ca..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_C.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 2305, - "key": "RuleC", - "language": "xoo", - "name": "C third rule", - "description": "Third rule of Fight Club: someone yells stop, goes limp, taps out, the fight is over.", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "BLOCKER", - "status": "READY", - "createdAt": "2013-07-04T07:38:05.543Z", - "updatedAt": "2013-03-27T08:52:40.370Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_b.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_b.json deleted file mode 100644 index 89ce23ad769..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_sorted_ignoring_case/rule_b.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 2304, - "key": "Ruleb", - "language": "xoo", - "name": "b second rule", - "description": "Second rule of Fight Club is: you do NOT talk about Fight Club.", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "MAJOR", - "status": "READY", - "createdAt": "2013-12-04T10:24:11.000Z", - "updatedAt": "2013-12-12T15:20:01.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_ace.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_ace.json deleted file mode 100644 index 50548b21f07..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_ace.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 2307, - "severity": "CRITICAL", - "profileId": 2, - "inheritance": null -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_empty.json deleted file mode 100644 index ed94424e6ac..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/active_rule_empty.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 2303, - "severity": "INFO", - "profileId": 2, - "inheritance": null -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_a.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_a.json deleted file mode 100644 index 948107d967b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_a.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": 2304, - "key": "RuleWithTagA", - "language": "xoo", - "name": "Rule with tag taga", - "description": "This rule has tag 'taga'", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "systemTags": ["taga"], - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ab.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ab.json deleted file mode 100644 index 3ca733480ae..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ab.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "id": 2305, - "key": "RuleWithTagsAB", - "language": "xoo", - "name": "Rule with tags taga and tagb", - "description": "This rule has tags 'taga' and 'tagb'", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "systemTags": ["tagb"], - "adminTags": ["taga"], - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ace.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ace.json deleted file mode 100644 index 44243bb1fdb..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_ace.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "id": 2307, - "key": "RuleWithTagsACE", - "language": "xoo", - "name": "Rule with tags taga, tagc and tage", - "description": "This rule has tags 'taga', 'tagc' and 'tage'", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "systemTags": ["taga", "tagc"], - "adminTags": ["tage"], - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_bc.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_bc.json deleted file mode 100644 index 59ca77178d4..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_bc.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": 2306, - "key": "RuleWithTagsBC", - "language": "xoo", - "name": "Rule with tags tagb and tagc", - "description": "This rule has tags 'tagb' and 'tagc'", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "systemTags": ["tagb", "tagc"], - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_empty.json deleted file mode 100644 index 43ca4f94522..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/find_inactive_rules_with_tags/tags_empty.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 2303, - "key": "RuleWithoutTags", - "language": "xoo", - "name": "Rule without tags", - "description": "This rule has no tag", - "parentKey": null, - "repositoryKey": "xoo", - "severity": "INFO", - "status": "READY", - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule25.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule25.json deleted file mode 100644 index 38c9040b3b5..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule25.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 25, - "severity": "MINOR", - "profileId": 1, - "inheritance": "OVERRIDES" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule2702.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule2702.json deleted file mode 100644 index 2025fbe362c..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule2702.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": 2702, - "severity": "CRITICAL", - "profileId": 1, - "inheritance": null, - "params": [ - { - "key": "fromClasses", - "value": "**.core.**" - }, - { - "key": "toClasses", - "value": "**.server.**" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule391.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule391.json deleted file mode 100644 index 2bb34dc2042..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule391.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "id": 391, - "severity": "MAJOR", - "profileId": 1, - "inheritance": "INHERITED", - "activeRuleParentId": 25 -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule523.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule523.json deleted file mode 100644 index 96af0f464a5..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/active_rule523.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "id": 523, - "severity": "MAJOR", - "profileId": 2, - "inheritance": null -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule1482.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule1482.json deleted file mode 100644 index 3f2ca70c432..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule1482.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "id": 1482, - "key": "ArchitecturalConstraint", - "language": "java", - "name": "Architectural constraint", - "description": "<p>A source code comply to an architectural model when it fully\n\tadheres to a set of architectural constraints. A constraint allows to\n\tdeny references between classes by pattern.</p>\n<p>You can for instance use this rule to :</p>\n<ul>\n\t<li>forbid access to **.web.** from **.dao.** classes</li>\n\t<li>forbid access to java.util.Vector, java.util.Hashtable and\n\t\tjava.util.Enumeration from any classes</li>\n\t<li>forbid access to java.sql.** from **.ui.** and **.web.**\n\t\tclasses</li>\n</ul>", - "parentKey": null, - "repositoryKey": "squid", - "severity": "MAJOR", - "status": "READY", - "createdAt": "2013-12-11T13:48:00.799Z", - "updatedAt": "2013-12-13T17:26:35.767Z", - "params": [ - { - "key": "toClasses", - "type": "STRING", - "defaultValue": "", - "description": "Mandatory. Ex : java.util.Vector, java.util.Hashtable, java.util.Enumeration" - }, - { - "key": "fromClasses", - "type": "STRING", - "defaultValue": "", - "description": "Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.web.**" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule25.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule25.json deleted file mode 100644 index 6fff4e43a57..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule25.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 25, - "key": "DM_CONVERT_CASE", - "language": "java", - "name": "Internationalization - Consider using Locale parameterized version of invoked method", - "description": "<p> A String is being converted to upper or lowercase, using the platform's default encoding. This may\n result in improper conversions when used with international characters. Use the </p>\n <table><tr><td>String.toUpperCase( Locale l )</td></tr><tr><td>String.toLowerCase( Locale l )</td></tr></table>\n <p>versions instead.</p>", - "parentKey": null, - "repositoryKey": "findbugs", - "severity": "INFO", - "status": "READY", - "createdAt": "2013-12-04T10:24:09.000Z", - "updatedAt": "2013-12-12T15:19:59.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule719.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule719.json deleted file mode 100644 index 7dc6d03b585..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule719.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": 719, - "key": "com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck", - "language": "java", - "name": "Double Checked Locking", - "description": null, - "parentKey": null, - "repositoryKey": "checkstyle", - "severity": "MAJOR", - "status": "READY", - "cardinality": "SINGLE", - "createdAt": "2013-07-04T07:38:05.543Z", - "updatedAt": "2013-03-27T08:52:40.370Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule759.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule759.json deleted file mode 100644 index ceecbbff6de..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule759.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": 759, - "key": "UnusedNullCheckInEquals", - "language": "java", - "name": "Unused Null Check In Equals", - "description": "After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method.", - "parentKey": null, - "repositoryKey": "pmd", - "severity": "MAJOR", - "status": "READY", - "createdAt": "2013-12-04T10:24:11.000Z", - "updatedAt": "2013-12-12T15:20:01.000Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule860.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule860.json deleted file mode 100644 index dc42767a299..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule860.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": 860, - "key": "Snippet", - "language": null, - "name": null, - "description": null, - "parentKey": null, - "repositoryKey": "squid", - "severity": "MAJOR", - "status": "REMOVED", - "cardinality": "MULTIPLE", - "createdAt": "2013-07-04T07:38:05.543Z", - "updatedAt": "2013-03-27T08:52:40.370Z" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule944.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule944.json deleted file mode 100644 index a8a2d311d71..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/QProfileRuleLookupTest/shared/rule944.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": 944, - "key": "S1125", - "language": "java", - "name": "Boolean expressions should not be compared to true or false", - "description": "<p> Boolean expressions should not be compared against boolean literals, as their value can be directly used. </p> <p>The following code:</p> <pre> if (booleanVariable == true) { /* ... */ } // Non-Compliant if (booleanVariable != true) { /* ... */ } // Non-Compliant </pre> <p>should be refactored into:</p> <pre> if (booleanVariable) { /* ... */ } // Compliant if (!booleanVariable) { /* ... */ } // Compliant </pre>", - "parentKey": null, - "repositoryKey": "squid", - "severity": "MAJOR", - "status": "READY", - "cardinality": "SINGLE", - "createdAt": "2013-07-26T07:40:51.977Z", - "updatedAt": "2014-01-10T15:38:27.386Z" -} |