From a2956e174784930170e1d6839c0924af24f27ce1 Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Thu, 4 May 2017 11:21:31 +0200 Subject: [PATCH] SONAR-9156 fail persisting components if project is not persisted MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When an analysis is processed, we expect the analysis’ project to be already stored in the database. --- .../step/PersistComponentsStep.java | 15 +++- .../step/PersistComponentsStepTest.java | 72 +++++++++++++++ .../step/ReportPersistComponentsStepTest.java | 88 +++++-------------- 3 files changed, 105 insertions(+), 70 deletions(-) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStepTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java index 8b76b57cded..dfc37c29305 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java @@ -92,7 +92,7 @@ public class PersistComponentsStep implements ComputationStep { dbClient.componentDao().resetBChangedForRootComponentUuid(dbSession, projectUuid); Map existingDtosByKeys = indexExistingDtosByKey(dbSession); - boolean isRootPrivate = isRootPrivate(treeRootHolder.getRoot().getKey(), existingDtosByKeys); + boolean isRootPrivate = isRootPrivate(treeRootHolder.getRoot(), existingDtosByKeys); // Insert or update the components in database. They are removed from existingDtosByKeys // at the same time. new PathAwareCrawler<>(new PersistComponentStepsVisitor(existingDtosByKeys, dbSession)) @@ -118,9 +118,16 @@ public class PersistComponentsStep implements ComputationStep { dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, projectUuid, isRootPrivate); } - private static boolean isRootPrivate(String rootKey, Map existingDtosByKeys) { - ComponentDto projectDto = existingDtosByKeys.get(rootKey); - return projectDto == null ? false /*FIXME actually use default configured for current organization*/ : projectDto.isPrivate(); + private static boolean isRootPrivate(Component root, Map existingDtosByKeys) { + String rootKey = root.getKey(); + ComponentDto rootDto = existingDtosByKeys.get(rootKey); + if (rootDto == null) { + if (Component.Type.VIEW == root.getType()) { + return false; + } + throw new IllegalStateException(String.format("The project '%s' is not stored in the database, during a project analysis.", rootKey)); + } + return rootDto.isPrivate(); } /** diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStepTest.java new file mode 100644 index 00000000000..eca5ea07c00 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStepTest.java @@ -0,0 +1,72 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.computation.task.projectanalysis.step; + +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.component.ComponentDao; +import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; +import org.sonar.server.computation.task.projectanalysis.component.Component; +import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepository; +import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder; +import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder; + +import static java.util.Collections.emptyList; +import static org.apache.commons.lang.RandomStringUtils.random; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class PersistComponentsStepTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void should_fail_if_project_is_not_stored_in_database_yet() { + TreeRootHolder treeRootHolder = mock(TreeRootHolder.class); + Component component = mock(Component.class); + DbClient dbClient = mock(DbClient.class); + ComponentDao componentDao = mock(ComponentDao.class); + String projectKey = random(20); + + doReturn(component).when(treeRootHolder).getRoot(); + doReturn(projectKey).when(component).getKey(); + doReturn(componentDao).when(dbClient).componentDao(); + doReturn(emptyList()).when(componentDao).selectAllComponentsFromProjectKey(any(DbSession.class), eq(projectKey)); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("The project '" + projectKey + "' is not stored in the database, during a project analysis"); + + new PersistComponentsStep( + dbClient, + treeRootHolder, + mock(MutableDbIdsRepository.class), + System2.INSTANCE, + mock(MutableDisabledComponentsHolder.class), + mock(AnalysisMetadataHolder.class)).execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java index 4e2b40940bc..0584c5eab5f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java @@ -97,6 +97,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { @Test public void persist_components() { + ComponentDto projectDto = insertProject(); Component file = builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java") .setPath("src/main/java/dir/Foo.java") .setFileAttributes(new FileAttributes(false, "java", 1)) @@ -111,32 +112,15 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { .setDescription("Module description") .addChildren(directory) .build(); - Component project = builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY) - .setName("Project") - .setDescription("Project description") + Component treeRoot = asTreeRoot(projectDto) .addChildren(module) .build(); - treeRootHolder.setRoot(project); + treeRootHolder.setRoot(treeRoot); underTest.execute(); assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4); - ComponentDto projectDto = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get(); - assertThat(projectDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); - assertThat(projectDto.name()).isEqualTo("Project"); - assertThat(projectDto.description()).isEqualTo("Project description"); - assertThat(projectDto.path()).isNull(); - assertThat(projectDto.uuid()).isEqualTo("ABCD"); - assertThat(projectDto.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT); - assertThat(projectDto.moduleUuid()).isNull(); - assertThat(projectDto.moduleUuidPath()).isEqualTo("." + projectDto.uuid() + "."); - assertThat(projectDto.projectUuid()).isEqualTo(projectDto.uuid()); - assertThat(projectDto.qualifier()).isEqualTo("TRK"); - assertThat(projectDto.scope()).isEqualTo("PRJ"); - assertThat(projectDto.getRootUuid()).isEqualTo("ABCD"); - assertThat(projectDto.getCreatedAt()).isEqualTo(now); - ComponentDto moduleDto = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get(); assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(moduleDto.name()).isEqualTo("Module"); @@ -183,7 +167,6 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(fileDto.getRootUuid()).isEqualTo(moduleDto.uuid()); assertThat(fileDto.getCreatedAt()).isEqualTo(now); - assertThat(dbIdsRepository.getComponentId(project)).isEqualTo(projectDto.getId()); assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId()); assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId()); assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); @@ -191,8 +174,9 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { @Test public void persist_file_directly_attached_on_root_directory() { + ComponentDto projectDto = insertProject(); treeRootHolder.setRoot( - builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY).setName("Project") + asTreeRoot(projectDto) .addChildren( builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":/").setPath("/") .addChildren( @@ -214,9 +198,9 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { @Test public void persist_unit_test() { + ComponentDto projectDto = insertProject(); treeRootHolder.setRoot( - builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY) - .setName("Project") + asTreeRoot(projectDto) .addChildren( builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":src/test/java/dir") .setPath("src/test/java/dir") @@ -298,9 +282,9 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { @Test public void compute_root_uuid() { + ComponentDto project = insertProject(); treeRootHolder.setRoot( - builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY) - .setName("Project") + asTreeRoot(project) .addChildren( builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY) .setName("Module") @@ -323,32 +307,36 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(5); - Optional project = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY); - assertThat(project).isPresent(); - assertThat(project.get().getRootUuid()).isEqualTo("ABCD"); - assertThat(project.get().getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT); - Optional module = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY); assertThat(module).isPresent(); - assertThat(module.get().getRootUuid()).isEqualTo(project.get().uuid()); + assertThat(module.get().getRootUuid()).isEqualTo(project.uuid()); Optional subModule1 = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_1_KEY"); assertThat(subModule1).isPresent(); - assertThat(subModule1.get().getRootUuid()).isEqualTo(project.get().uuid()); + assertThat(subModule1.get().getRootUuid()).isEqualTo(project.uuid()); Optional subModule2 = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_2_KEY"); assertThat(subModule2).isPresent(); - assertThat(subModule2.get().getRootUuid()).isEqualTo(project.get().uuid()); + assertThat(subModule2.get().getRootUuid()).isEqualTo(project.uuid()); Optional directory = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_2_KEY:src/main/java/dir"); assertThat(directory).isPresent(); assertThat(directory.get().getRootUuid()).isEqualTo(subModule2.get().uuid()); } + private ReportComponent.Builder asTreeRoot(ComponentDto project) { + return builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.key()).setName(project.name()); + } + + public ComponentDto insertProject() { + return dbTester.components().insertPrivateProject(dbTester.organizations().insert()); + } + @Test public void persist_multi_modules() { + ComponentDto project = insertProject(); treeRootHolder.setRoot( - builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY) + asTreeRoot(project) .setName("Project") .addChildren( builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey("MODULE_A") @@ -367,12 +355,6 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4); - ComponentDto project = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get(); - assertThat(project.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT); - assertThat(project.moduleUuid()).isNull(); - assertThat(project.moduleUuidPath()).isEqualTo("." + project.uuid() + "."); - assertThat(project.getRootUuid()).isEqualTo("ABCD"); - ComponentDto moduleA = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_A").get(); assertThat(moduleA.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR); assertThat(moduleA.moduleUuid()).isEqualTo(project.uuid()); @@ -784,32 +766,6 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { assertThat(fileReloaded.isEnabled()).isTrue(); } - @Test - public void persists_new_components_as_private_if_root_does_not_exist_yet_out_of_functional_transaction() { - treeRootHolder.setRoot(createSampleProjectComponentTree("ABCD", PROJECT_KEY)); - - underTest.execute(); - - Stream.of("ABCD", "BCDE", "DEFG", "CDEF") - .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(dbTester.getSession(), uuid).get().isPrivate()).isFalse()); - } - - @Test - public void persists_new_components_with_visibility_of_root_in_db_out_of_functional_transaction() { - boolean isRootPrivate = new Random().nextBoolean(); - OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto project = newPrivateProjectDto(organization, "ABCD").setKey(PROJECT_KEY).setName("Project").setPrivate(isRootPrivate); - dbTester.components().insertComponent(project); - treeRootHolder.setRoot(createSampleProjectComponentTree(project)); - - underTest.execute(); - - Stream.of("ABCD", "BCDE", "DEFG", "CDEF") - .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(dbTester.getSession(), uuid).get().isPrivate()) - .describedAs("for uuid " + uuid) - .isEqualTo(isRootPrivate)); - } - @Test public void persists_existing_components_with_visibility_of_root_in_db_out_of_functional_transaction() { boolean isRootPrivate = new Random().nextBoolean(); -- 2.39.5