aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2018-03-29 17:09:18 +0200
committerSonarTech <sonartech@sonarsource.com>2018-04-05 20:20:48 +0200
commit492942631b3c2612fd8ed9b03bd7db3261a38e58 (patch)
tree33059afc664bb0711675eaf563c755e75162d652 /tests
parent2104453573fa15d1c5c3f8cee703d2cf3ccced55 (diff)
downloadsonarqube-492942631b3c2612fd8ed9b03bd7db3261a38e58.tar.gz
sonarqube-492942631b3c2612fd8ed9b03bd7db3261a38e58.zip
SONAR-10511 Project key renaming should rename deleted components too
Diffstat (limited to 'tests')
-rw-r--r--tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java241
1 files changed, 217 insertions, 24 deletions
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 f77c1d4fb9d..d4f004dd9f1 100644
--- a/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdateTest.java
@@ -21,31 +21,43 @@ package org.sonarqube.tests.project;
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;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonarqube.qa.util.Tester;
import org.sonarqube.ws.Components;
import org.sonarqube.ws.Organizations;
import org.sonarqube.ws.Projects;
+import org.sonarqube.ws.Projects.BulkUpdateKeyWsResponse.Key;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.WsResponse;
import org.sonarqube.ws.client.components.SearchProjectsRequest;
import org.sonarqube.ws.client.components.ShowRequest;
+import org.sonarqube.ws.client.components.TreeRequest;
+import org.sonarqube.ws.client.projects.BulkUpdateKeyRequest;
import org.sonarqube.ws.client.projects.UpdateKeyRequest;
-import org.sonarqube.ws.client.projects.CreateRequest;
import util.ItUtils;
+import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
import static util.ItUtils.projectDir;
public class ProjectKeyUpdateTest {
@@ -57,7 +69,8 @@ public class ProjectKeyUpdateTest {
@Rule
public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
-
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
@Rule
public Tester tester = new Tester(orchestrator).setElasticsearchHttpPort(ProjectSuite.SEARCH_HTTP_PORT);
@@ -67,17 +80,18 @@ public class ProjectKeyUpdateTest {
}
@Test
- public void update_key() {
- analyzeXooSample();
- String newProjectKey = "another_project_key";
- Components.Component project = tester.wsClient().components().show(new ShowRequest().setComponent(PROJECT_KEY)).getComponent();
- assertThat(project.getKey()).isEqualTo(PROJECT_KEY);
+ public void update_key() throws IOException {
+ Organizations.Organization organization = tester.organizations().generate();
+ File projectDir = new XooProjectBuilder(PROJECT_KEY)
+ .build(temp.newFolder());
+ analyze(organization, projectDir);
+ assertThat(tester.projects().exists(PROJECT_KEY)).isTrue();
- tester.wsClient().projects().updateKey(new UpdateKeyRequest()
- .setFrom(PROJECT_KEY)
- .setTo(newProjectKey));
+ String newProjectKey = "renamed";
+ updateProjectKey(PROJECT_KEY, newProjectKey, false);
- assertThat(tester.wsClient().components().show(new ShowRequest().setComponentId(project.getId())).getComponent().getKey()).isEqualTo(newProjectKey);
+ assertThat(tester.projects().exists(PROJECT_KEY)).isFalse();
+ assertThat(tester.projects().exists(newProjectKey)).isTrue();
}
@Test
@@ -85,7 +99,7 @@ public class ProjectKeyUpdateTest {
Organizations.Organization organization = tester.organizations().generate();
Projects.CreateWsResponse.Project project = createProject(organization, "one", "Foo");
- updateKey(project, "two");
+ updateProjectKey(project.getKey(), "two", false);
assertThat(isProjectInDatabase("one")).isFalse();
assertThat(isProjectInDatabase("two")).isTrue();
@@ -102,7 +116,7 @@ public class ProjectKeyUpdateTest {
lockWritesOnProjectIndices();
- updateKey(project, "two");
+ updateProjectKey(project.getKey(), "two", false);
assertThat(isProjectInDatabase("one")).isFalse();
@@ -142,7 +156,7 @@ public class ProjectKeyUpdateTest {
String initialKey = "com.sonarsource.it.samples:multi-modules-sample:module_a";
String newKey = "com.sonarsource.it.samples:multi-modules-sample:module_c";
- updateKey(initialKey, newKey);
+ updateModuleKey(initialKey, newKey);
assertThat(isComponentInDatabase(initialKey)).isFalse();
assertThat(isComponentInDatabase(newKey)).isTrue();
@@ -168,7 +182,7 @@ public class ProjectKeyUpdateTest {
String newKey = "com.sonarsource.it.samples:multi-modules-sample:module_c";
lockWritesOnProjectIndices();
- updateKey(initialKey, newKey);
+ updateModuleKey(initialKey, newKey);
// api/components/search loads keys from db, so results are consistent
assertThat(isComponentInDatabase(initialKey)).isFalse();
@@ -193,7 +207,133 @@ public class ProjectKeyUpdateTest {
Thread.sleep(1_000L);
recovered = keysInComponentSuggestions(newKey).contains(newKey) && keysInComponentSuggestions(initialKey).isEmpty();
}
+ }
+
+ /**
+ * SONAR-10511
+ */
+ @Test
+ public void update_key_of_disabled_files() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+ // first analysis
+ File projectWith2Files = new XooProjectBuilder(PROJECT_KEY)
+ .setFilesPerModule(2)
+ .build(temp.newFolder());
+ analyze(organization, projectWith2Files);
+ assertThat(countFilesInProject()).isEqualTo(2);
+
+ // second analysis emulates a deletion of file
+ File projectWith1File = new XooProjectBuilder(PROJECT_KEY)
+ .setFilesPerModule(1)
+ .build(temp.newFolder());
+ analyze(organization, projectWith1File);
+ assertThat(countFilesInProject()).isEqualTo(1);
+
+ // update the project key
+ updateProjectKey(PROJECT_KEY, "renamed", false);
+ ItUtils.expectNotFoundError(() -> tester.wsClient().components().show(new ShowRequest().setComponent(PROJECT_KEY)));
+
+ // first analysis of the new project, which re-enables the deleted file
+ analyze(organization, projectWith2Files);
+ assertThat(countFilesInProject()).isEqualTo(2);
+ }
+
+ /**
+ * SONAR-10511
+ */
+ @Test
+ public void update_of_project_key_includes_disabled_modules() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+
+ // first analysis
+ File projectWithModulesAB = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_a", "module_b")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModulesAB);
+ assertThat(countFilesInProject()).isEqualTo(3);
+
+ // second analysis emulates deletion of module_b
+ File projectWithModuleA = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_a")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModuleA);
+ assertThat(countFilesInProject()).isEqualTo(2);
+
+ // update the project key
+ updateProjectKey(PROJECT_KEY, "renamed", false);
+ assertThat(tester.projects().exists(PROJECT_KEY)).isFalse();
+
+ // analysis of new project, re-enabling the deleted module
+ File projectWithModulesBC = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_b", "module_c")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModulesBC);
+ assertThat(countFilesInProject()).isEqualTo(3);
+ }
+
+ @Test
+ public void simulate_update_key_of_modules() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+
+ File project = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_a", "module_b")
+ .build(temp.newFolder());
+ analyze(organization, project);
+ assertThat(tester.projects().exists(PROJECT_KEY)).isTrue();
+
+ // simulate update of project key
+ Projects.BulkUpdateKeyWsResponse response = updateProjectKey(PROJECT_KEY, "renamed", true);
+
+ assertThat(tester.projects().exists(PROJECT_KEY)).isTrue();
+ assertThat(tester.projects().exists("renamed")).isFalse();
+ assertThat(response.getKeysList())
+ .extracting(Key::getKey, Key::getNewKey)
+ .containsExactlyInAnyOrder(
+ tuple(PROJECT_KEY, "renamed"),
+ tuple(PROJECT_KEY + ":module_a", "renamed:module_a"),
+ tuple(PROJECT_KEY + ":module_b", "renamed:module_b"));
+ }
+
+ @Test
+ public void simulate_update_key_of_disabled_modules() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+
+ // first analysis
+ File projectWithModulesAB = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_a", "module_b")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModulesAB);
+ assertThat(countFilesInProject()).isEqualTo(3);
+
+ // second analysis emulates deletion of module_b
+ File projectWithModuleA = new XooProjectBuilder(PROJECT_KEY)
+ .addModules("module_a")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModuleA);
+ assertThat(countFilesInProject()).isEqualTo(2);
+
+ // update the project key
+ Projects.BulkUpdateKeyWsResponse response = updateProjectKey(PROJECT_KEY, "renamed", true);
+
+ assertThat(tester.projects().exists(PROJECT_KEY)).isTrue();
+ assertThat(tester.projects().exists("renamed")).isFalse();
+ assertThat(response.getKeysList())
+ .extracting(Key::getKey, Key::getNewKey)
+ .containsExactlyInAnyOrder(
+ tuple(PROJECT_KEY, "renamed"),
+ tuple(PROJECT_KEY + ":module_a", "renamed:module_a"));
+ }
+
+ private int countFilesInProject() {
+ TreeRequest request = new TreeRequest().setComponent(PROJECT_KEY).setQualifiers(asList("FIL"));
+ return tester.wsClient().components().tree(request).getComponentsCount();
+ }
+
+ private void analyze(Organizations.Organization organization, File projectDir) {
+ orchestrator.executeBuild(SonarScanner.create(projectDir,
+ "sonar.organization", organization.getKey(),
+ "sonar.login", "admin", "sonar.password", "admin"));
}
private void lockWritesOnProjectIndices() throws Exception {
@@ -206,17 +346,20 @@ public class ProjectKeyUpdateTest {
tester.elasticsearch().unlockWrites("projectmeasures");
}
- private void updateKey(Projects.CreateWsResponse.Project project, String newKey) {
- tester.wsClient().projects().updateKey(new UpdateKeyRequest().setFrom(project.getKey()).setTo(newKey));
+ private void updateModuleKey(String initialKey, String newKey) {
+ tester.wsClient().projects().updateKey(new UpdateKeyRequest().setFrom(initialKey).setTo(newKey));
}
- private void updateKey(String initialKey, String newKey) {
- tester.wsClient().projects().updateKey(new UpdateKeyRequest().setFrom(initialKey).setTo(newKey));
+ private Projects.BulkUpdateKeyWsResponse updateProjectKey(String initialKey, String newKey, boolean dryRun) {
+ return tester.wsClient().projects().bulkUpdateKey(new BulkUpdateKeyRequest()
+ .setProject(initialKey)
+ .setFrom(initialKey)
+ .setTo(newKey)
+ .setDryRun(String.valueOf(dryRun)));
}
private Projects.CreateWsResponse.Project createProject(Organizations.Organization organization, String key, String name) {
- CreateRequest createRequest = new CreateRequest().setProject(key).setName(name).setOrganization(organization.getKey());
- return tester.wsClient().projects().create(createRequest).getProject();
+ return tester.projects().provision(organization, r -> r.setProject(key).setName(name));
}
private boolean isProjectInDatabase(String projectKey) {
@@ -255,8 +398,58 @@ public class ProjectKeyUpdateTest {
.collect(Collectors.toList());
}
- private void analyzeXooSample() {
- SonarScanner build = SonarScanner.create(projectDir("shared/xoo-sample"));
- orchestrator.executeBuild(build);
+ private static class XooProjectBuilder {
+ private final String key;
+ private final List<String> 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);
+ }
+ }
}
+
}