From: Simon Brandhof Date: Tue, 3 Apr 2018 11:54:14 +0000 (+0200) Subject: SONAR-10536 refactoring, no functional changes X-Git-Tag: 7.5~1400 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c58ff4caa54f4d1da9e3103afc01d64a211aef66;p=sonarqube.git SONAR-10536 refactoring, no functional changes --- diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java index 6a0ea848516..8bc0a216bb8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java @@ -56,7 +56,7 @@ public class ComponentKeyUpdaterDao implements Dao { } // must SELECT first everything - ResourceDto project = mapper.selectProject(projectOrModuleUuid); + ResourceDto project = mapper.selectProjectByUuid(projectOrModuleUuid); String projectOldKey = project.getKey(); List resources = mapper.selectProjectResources(projectOrModuleUuid); resources.add(project); @@ -67,7 +67,7 @@ public class ComponentKeyUpdaterDao implements Dao { .filter(branch -> !projectOrModuleUuid.equals(branch.getUuid())) .forEach(branch -> { resources.addAll(mapper.selectProjectResources(branch.getUuid())); - resources.add(mapper.selectProject(branch.getUuid())); + resources.add(mapper.selectProjectByUuid(branch.getUuid())); }); // and then proceed with the batch UPDATE at once @@ -166,7 +166,7 @@ public class ComponentKeyUpdaterDao implements Dao { } private static Set collectAllModules(String projectUuid, String stringToReplace, ComponentKeyUpdaterMapper mapper, boolean includeDisabled) { - ResourceDto project = mapper.selectProject(projectUuid); + ResourceDto project = mapper.selectProjectByUuid(projectUuid); Set modules = new HashSet<>(); if (project.getKey().contains(stringToReplace) && (project.isEnabled() || includeDisabled)) { modules.add(project); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java index 75cfc798e7a..364fe67eae3 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java @@ -22,14 +22,11 @@ package org.sonar.db.component; import java.util.List; import org.apache.ibatis.annotations.Param; -/** - * @since 3.2 - */ public interface ComponentKeyUpdaterMapper { int countResourceByKey(String key); - ResourceDto selectProject(@Param("uuid") String uuid); + ResourceDto selectProjectByUuid(@Param("uuid") String uuid); List selectProjectResources(@Param("rootUuid") String rootUuid); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml index 51f2114ab66..f0afa194b75 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml @@ -19,7 +19,7 @@ WHERE kee = #{key,jdbcType=VARCHAR} - select * from projects where uuid = #{uuid,jdbcType=VARCHAR} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java index ee5c0b64875..22165c43d74 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java @@ -125,9 +125,9 @@ public class ReportSubmitter { if (!Qualifiers.PROJECT.equals(component.qualifier()) || !Scopes.PROJECT.equals(component.scope())) { errors.add(format("Component '%s' is not a project", rawProjectKey)); } - if (!project.get().projectUuid().equals(project.get().uuid())) { + if (!component.projectUuid().equals(component.uuid())) { // Project key is already used as a module of another project - ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, project.get().projectUuid()); + ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, component.projectUuid()); errors.add(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'.", rawProjectKey, anotherBaseProject.getKey(), anotherBaseProject.getKey(), rawProjectKey)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java index 2908be1dfbc..16bd63ab837 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java @@ -19,6 +19,7 @@ */ package org.sonar.server.project.ws; +import com.google.common.base.Optional; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -26,12 +27,8 @@ import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.component.ComponentFinder.ParamNames; import org.sonar.server.component.ComponentService; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; +import org.sonar.server.exceptions.NotFoundException; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; @@ -42,12 +39,10 @@ import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO; public class UpdateKeyAction implements ProjectsWsAction { private final DbClient dbClient; - private final ComponentFinder componentFinder; private final ComponentService componentService; - public UpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService) { + public UpdateKeyAction(DbClient dbClient, ComponentService componentService) { this.dbClient = dbClient; - this.componentFinder = componentFinder; this.componentService = componentService; } @@ -59,19 +54,20 @@ public class UpdateKeyAction implements ProjectsWsAction { public WebService.NewAction doDefine(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY) .setDescription("Update a project or module key and all its sub-components keys.
" + - "Either '%s' or '%s' must be provided.
" + - "Requires one of the following permissions: " + - "
    " + - "
  • 'Administer System'
  • " + - "
  • 'Administer' rights on the specified project
  • " + - "
", + "Either '%s' or '%s' must be provided.
" + + "Requires one of the following permissions: " + + "
    " + + "
  • 'Administer System'
  • " + + "
  • 'Administer' rights on the specified project
  • " + + "
", PARAM_FROM, PARAM_PROJECT_ID) .setSince("6.1") .setPost(true) .setHandler(this); action.setChangelog( - new Change("6.4", "Move from api/components/update_key to api/projects/update_key")); + new Change("6.4", "Move from api/components/update_key to api/projects/update_key"), + new Change("7.1", "Ability to update key of a disabled module")); action.createParam(PARAM_PROJECT_ID) .setDescription("Project or module id") @@ -95,82 +91,24 @@ public class UpdateKeyAction implements ProjectsWsAction { @Override public void handle(Request request, Response response) throws Exception { - doHandle(toWsRequest(request)); - response.noContent(); - } + String uuid = request.param(PARAM_PROJECT_ID); + String key = request.param(PARAM_FROM); + String newKey = request.mandatoryParam(PARAM_TO); + checkArgument(uuid != null ^ key != null, "Either '%s' or '%s' must be provided", PARAM_PROJECT_ID, PARAM_FROM); - private void doHandle(UpdateKeyRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { - ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_FROM); - componentService.updateKey(dbSession, projectOrModule, request.getNewKey()); - } - } - - private static UpdateKeyRequest toWsRequest(Request request) { - return UpdateKeyRequest.builder() - .setId(request.param(PARAM_PROJECT_ID)) - .setKey(request.param(PARAM_FROM)) - .setNewKey(request.mandatoryParam(PARAM_TO)) - .build(); - } - - private static class UpdateKeyRequest { - private final String id; - private final String key; - private final String newKey; - - public UpdateKeyRequest(Builder builder) { - this.id = builder.id; - this.key = builder.key; - this.newKey = builder.newKey; - } - - @CheckForNull - public String getId() { - return id; - } - - @CheckForNull - public String getKey() { - return key; - } - - public String getNewKey() { - return newKey; - } - - public static Builder builder() { - return new Builder(); - } - } - - private static class Builder { - private String id; - private String key; - private String newKey; - - private Builder() { - // enforce method constructor - } - - public Builder setId(@Nullable String id) { - this.id = id; - return this; - } - - public Builder setKey(@Nullable String key) { - this.key = key; - return this; - } - - public Builder setNewKey(String newKey) { - this.newKey = newKey; - return this; - } - - public UpdateKeyRequest build() { - checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty"); - return new UpdateKeyRequest(this); + Optional component; + if (uuid != null) { + component = dbClient.componentDao().selectByUuid(dbSession, uuid); + } else { + component = dbClient.componentDao().selectByKey(dbSession, key); + } + if (!component.isPresent() || component.get().getMainBranchProjectUuid() != null) { + throw new NotFoundException("Component not found"); + } + + componentService.updateKey(dbSession, component.get(), newKey); } + response.noContent(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java index 91b7df17ec7..bca7c9f01a1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.project.ws; +import com.google.common.base.Optional; import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; @@ -26,23 +27,21 @@ import org.junit.rules.ExpectedException; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; 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.component.ComponentService; -import org.sonar.server.component.TestComponentFinder; +import org.sonar.server.es.ProjectIndexers; +import org.sonar.server.es.ProjectIndexersImpl; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; 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.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO; @@ -54,55 +53,104 @@ public class UpdateKeyActionTest { public ExpectedException expectedException = ExpectedException.none(); @Rule public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + private DbClient dbClient = db.getDbClient(); + private ProjectIndexers projectIndexers = new ProjectIndexersImpl(); + private ComponentService componentService = new ComponentService(dbClient, userSessionRule, projectIndexers); + private WsActionTester ws = new WsActionTester(new UpdateKeyAction(dbClient, componentService)); - ComponentDbTester componentDb = new ComponentDbTester(db); - DbClient dbClient = db.getDbClient(); + @Test + public void update_key_of_project_referenced_by_its_key() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - ComponentService componentService = mock(ComponentService.class); + callByKey(project.getKey(), ANOTHER_KEY); - WsActionTester ws = new WsActionTester(new org.sonar.server.project.ws.UpdateKeyAction(dbClient, TestComponentFinder.from(db), componentService)); + assertThat(selectByKey(project.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid()); + } @Test - public void call_by_key() { + public void update_key_of_project_referenced_by_its_uuid() { ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - callByKey(project.getDbKey(), ANOTHER_KEY); + callByUuid(project.uuid(), ANOTHER_KEY); - assertCallComponentService(ANOTHER_KEY); + assertThat(selectByKey(project.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid()); } @Test - public void call_by_uuid() { + public void update_key_of_module_referenced_by_its_uuid() { ComponentDto project = insertProject(); + ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project)); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - callByUuid(project.uuid(), ANOTHER_KEY); + callByUuid(module.uuid(), ANOTHER_KEY); - assertCallComponentService(ANOTHER_KEY); + assertThat(selectByKey(project.getKey()).isPresent()).isTrue(); + assertThat(selectByKey(module.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(module.uuid()); } @Test - public void fail_if_new_key_is_not_provided() { - expectedException.expect(IllegalArgumentException.class); + public void update_key_of_disabled_module() { + ComponentDto project = insertProject(); + ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setEnabled(false)); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + + callByKey(module.getKey(), ANOTHER_KEY); + + assertThat(selectByKey(project.getKey()).isPresent()).isTrue(); + assertThat(selectByKey(module.getKey()).isPresent()).isFalse(); + ComponentDto loadedModule = selectByKey(ANOTHER_KEY).get(); + assertThat(loadedModule.uuid()).isEqualTo(module.uuid()); + assertThat(loadedModule.isEnabled()).isFalse(); + } + + + @Test + public void fail_if_not_authorized() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.USER, project); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + callByKey(project.getKey(), ANOTHER_KEY); + } + @Test + public void fail_if_new_key_is_not_provided() { ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'to' parameter is missing"); - callByKey(project.getDbKey(), null); + callByKey(project.getKey(), null); } @Test public void fail_if_uuid_nor_key_provided() { expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Either 'projectId' or 'from' must be provided"); call(null, null, ANOTHER_KEY); } @Test - public void fail_if_uuid_and_key_provided() { + public void fail_if_both_uuid_and_key_provided() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Either 'projectId' or 'from' must be provided"); - ComponentDto project = insertProject(); - call(project.uuid(), project.getDbKey(), ANOTHER_KEY); + call(project.uuid(), project.getKey(), ANOTHER_KEY); } @Test @@ -116,9 +164,10 @@ public class UpdateKeyActionTest { public void fail_when_using_branch_db_key() throws Exception { ComponentDto project = db.components().insertMainBranch(); ComponentDto branch = db.components().insertProjectBranch(project); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); expectedException.expect(NotFoundException.class); - expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey())); + expectedException.expectMessage("Component not found"); callByKey(branch.getDbKey(), ANOTHER_KEY); } @@ -127,9 +176,10 @@ public class UpdateKeyActionTest { public void fail_when_using_branch_uuid() { ComponentDto project = db.components().insertMainBranch(); ComponentDto branch = db.components().insertProjectBranch(project); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); expectedException.expect(NotFoundException.class); - expectedException.expectMessage(String.format("Component id '%s' not found", branch.uuid())); + expectedException.expectMessage("Component not found"); callByUuid(branch.uuid(), ANOTHER_KEY); } @@ -141,26 +191,23 @@ public class UpdateKeyActionTest { assertThat(definition.since()).isEqualTo("6.1"); assertThat(definition.isPost()).isTrue(); assertThat(definition.key()).isEqualTo("update_key"); + assertThat(definition.changelog()).hasSize(2); assertThat(definition.params()) .hasSize(3) .extracting(Param::key) .containsOnlyOnce("projectId", "from", "to"); } - private void assertCallComponentService(@Nullable String newKey) { - verify(componentService).updateKey(any(DbSession.class), any(ComponentDto.class), eq(newKey)); - } - private ComponentDto insertProject() { - return componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert())); + return db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert())); } - private String callByUuid(@Nullable String uuid, @Nullable String newKey) { - return call(uuid, null, newKey); + private void callByUuid(@Nullable String uuid, @Nullable String newKey) { + call(uuid, null, newKey); } - private String callByKey(@Nullable String key, @Nullable String newKey) { - return call(null, key, newKey); + private void callByKey(@Nullable String key, @Nullable String newKey) { + call(null, key, newKey); } private String call(@Nullable String uuid, @Nullable String key, @Nullable String newKey) { @@ -178,4 +225,8 @@ public class UpdateKeyActionTest { return request.execute().getInput(); } + + private Optional selectByKey(String key) { + return db.getDbClient().componentDao().selectByKey(db.getSession(), key); + } } diff --git a/tests/src/test/java/org/sonarqube/tests/component/ComponentSuite.java b/tests/src/test/java/org/sonarqube/tests/component/ComponentSuite.java index 0384ce9562b..9d08069bc36 100644 --- a/tests/src/test/java/org/sonarqube/tests/component/ComponentSuite.java +++ b/tests/src/test/java/org/sonarqube/tests/component/ComponentSuite.java @@ -31,15 +31,14 @@ import static util.ItUtils.xooPlugin; @Suite.SuiteClasses({ BranchTest.class, CodePageTest.class, - ComponentsWsTest.class + ComponentsWsTest.class, + ModuleTest.class }) public class ComponentSuite { @ClassRule public static final Orchestrator ORCHESTRATOR = ItUtils.newOrchestratorBuilder() - .addPlugin(xooPlugin()) - .build(); } diff --git a/tests/src/test/java/org/sonarqube/tests/component/ModuleTest.java b/tests/src/test/java/org/sonarqube/tests/component/ModuleTest.java new file mode 100644 index 00000000000..ffc3f4e1a47 --- /dev/null +++ b/tests/src/test/java/org/sonarqube/tests/component/ModuleTest.java @@ -0,0 +1,115 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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.sonarqube.tests.component; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.BuildFailureException; +import com.sonar.orchestrator.build.SonarScanner; +import java.io.File; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonarqube.qa.util.Tester; +import org.sonarqube.ws.Organizations; +import org.sonarqube.ws.client.components.ShowRequest; +import org.sonarqube.ws.client.components.TreeRequest; +import org.sonarqube.ws.client.projects.UpdateKeyRequest; +import util.XooProjectBuilder; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; + +public class ModuleTest { + + private static final String PROJECT_KEY = "sample"; + + @ClassRule + public static Orchestrator orchestrator = ComponentSuite.ORCHESTRATOR; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + @Rule + public Tester tester = new Tester(orchestrator); + + /** + * SONAR-10536 + */ + @Test + public void analyze_disabled_module_as_a_new_project() throws Exception { + Organizations.Organization organization = tester.organizations().generate(); + String projectKey = PROJECT_KEY; + String moduleKey = projectKey + ":module_a"; + + // analyze project "sample" with module "sample:module_a" + File projectWithModule = new XooProjectBuilder(projectKey) + .addModules("module_a") + .build(temp.newFolder()); + analyze(organization, projectWithModule); + assertThat(tester.projects().exists(moduleKey)).isTrue(); + assertThat(countFilesInProject(projectKey)).isEqualTo(2 /* 1 file in project and 1 file in module */); + + // analyze project "sample" without module "sample:module_a". The latter + // is considered as disabled + File projectWithoutModule = new XooProjectBuilder(projectKey) + .build(temp.newFolder()); + analyze(organization, projectWithoutModule); + assertThat(tester.projects().exists(moduleKey)).isFalse(); + assertThat(countFilesInProject(projectKey)).isEqualTo(1 /* 1 file in project */); + + // analyze module_a as a project + File moduleAsProject = new XooProjectBuilder(moduleKey) + .build(temp.newFolder()); + try { + analyze(organization, moduleAsProject); + fail(); + } catch (BuildFailureException e) { + assertThat(e.getResult().getLogs()).contains("The project '" + moduleKey + "' is already defined in SonarQube but as a module of project '" + projectKey + "'"); + assertThat(tester.projects().exists(moduleKey)).isFalse(); + } + + // the only workaround is to rename the key of the disabled module + updateModuleKey(moduleKey, moduleKey + "_old"); + + // module_a can now be analyzed as a project + analyze(organization, moduleAsProject); + assertThat(tester.projects().exists(moduleKey)).isTrue(); + assertThat(countFilesInProject(moduleKey)).isEqualTo(1); + assertThat(tester.wsClient().components().show(new ShowRequest().setComponent(moduleKey)).getComponent().getQualifier()).isEqualTo("TRK"); + } + + private void analyze(Organizations.Organization organization, File projectDir) { + orchestrator.executeBuild(SonarScanner.create(projectDir, + "sonar.organization", organization.getKey(), + "sonar.login", "admin", "sonar.password", "admin")); + } + + private int countFilesInProject(String projectKey) { + TreeRequest request = new TreeRequest().setComponent(projectKey).setQualifiers(asList("FIL")); + return tester.wsClient().components().tree(request).getComponentsCount(); + } + + private void updateModuleKey(String fromKey, String toKey) { + tester.wsClient().projects().updateKey(new UpdateKeyRequest() + .setFrom(fromKey) + .setTo(toKey)); + } +} diff --git a/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java b/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java index d4f004dd9f1..b1486e5f539 100644 --- a/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java +++ b/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java @@ -23,16 +23,11 @@ import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarScanner; import java.io.File; import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.stream.Collectors; import javax.annotation.CheckForNull; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; import org.junit.After; import org.junit.ClassRule; import org.junit.Rule; @@ -54,6 +49,7 @@ import org.sonarqube.ws.client.components.TreeRequest; import org.sonarqube.ws.client.projects.BulkUpdateKeyRequest; import org.sonarqube.ws.client.projects.UpdateKeyRequest; import util.ItUtils; +import util.XooProjectBuilder; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; @@ -398,58 +394,4 @@ public class ProjectKeyUpdateTest { .collect(Collectors.toList()); } - private static class XooProjectBuilder { - private final String key; - private final List moduleKeys = new ArrayList<>(); - private int filesPerModule = 1; - - XooProjectBuilder(String projectKey) { - this.key = projectKey; - } - - XooProjectBuilder addModules(String key, String... otherKeys) { - this.moduleKeys.add(key); - this.moduleKeys.addAll(asList(otherKeys)); - return this; - } - - XooProjectBuilder setFilesPerModule(int i) { - this.filesPerModule = i; - return this; - } - - File build(File dir) { - for (String moduleKey : moduleKeys) { - generateModule(moduleKey, new File(dir, moduleKey), new Properties()); - } - Properties additionalProps = new Properties(); - additionalProps.setProperty("sonar.modules", StringUtils.join(moduleKeys, ",")); - generateModule(key, dir, additionalProps); - return dir; - } - - private void generateModule(String key, File dir, Properties additionalProps) { - try { - File sourceDir = new File(dir, "src"); - FileUtils.forceMkdir(sourceDir); - for (int i = 0; i < filesPerModule; i++) { - File sourceFile = new File(sourceDir, "File" + i + ".xoo"); - FileUtils.write(sourceFile, "content of " + sourceFile.getName()); - } - Properties props = new Properties(); - props.setProperty("sonar.projectKey", key); - props.setProperty("sonar.projectName", key); - props.setProperty("sonar.projectVersion", "1.0"); - props.setProperty("sonar.sources", sourceDir.getName()); - props.putAll(additionalProps); - File propsFile = new File(dir, "sonar-project.properties"); - try (OutputStream output = FileUtils.openOutputStream(propsFile)) { - props.store(output, "generated"); - } - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - } diff --git a/tests/src/test/java/util/XooProjectBuilder.java b/tests/src/test/java/util/XooProjectBuilder.java new file mode 100644 index 00000000000..0eaf934572b --- /dev/null +++ b/tests/src/test/java/util/XooProjectBuilder.java @@ -0,0 +1,85 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 util; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; + +import static java.util.Arrays.asList; + +public class XooProjectBuilder { + private final String key; + private final List moduleKeys = new ArrayList<>(); + private int filesPerModule = 1; + + public XooProjectBuilder(String projectKey) { + this.key = projectKey; + } + + public XooProjectBuilder addModules(String key, String... otherKeys) { + this.moduleKeys.add(key); + this.moduleKeys.addAll(asList(otherKeys)); + return this; + } + + public XooProjectBuilder setFilesPerModule(int i) { + this.filesPerModule = i; + return this; + } + + public File build(File dir) { + for (String moduleKey : moduleKeys) { + generateModule(moduleKey, new File(dir, moduleKey), new Properties()); + } + Properties additionalProps = new Properties(); + additionalProps.setProperty("sonar.modules", StringUtils.join(moduleKeys, ",")); + generateModule(key, dir, additionalProps); + return dir; + } + + private void generateModule(String key, File dir, Properties additionalProps) { + try { + File sourceDir = new File(dir, "src"); + FileUtils.forceMkdir(sourceDir); + for (int i = 0; i < filesPerModule; i++) { + File sourceFile = new File(sourceDir, "File" + i + ".xoo"); + FileUtils.write(sourceFile, "content of " + sourceFile.getName()); + } + Properties props = new Properties(); + props.setProperty("sonar.projectKey", key); + props.setProperty("sonar.projectName", key); + props.setProperty("sonar.projectVersion", "1.0"); + props.setProperty("sonar.sources", sourceDir.getName()); + props.putAll(additionalProps); + File propsFile = new File(dir, "sonar-project.properties"); + try (OutputStream output = FileUtils.openOutputStream(propsFile)) { + props.store(output, "generated"); + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } +}