aboutsummaryrefslogtreecommitdiffstats
path: root/it
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2015-12-21 13:54:14 +0100
committerDuarte Meneses <duarte.meneses@sonarsource.com>2015-12-21 14:37:03 +0100
commitd1e303f8412f61f426a6c746cc2ac10b584940bd (patch)
treeb68693cc8caced2aeee5b06a3590b3e1392e8011 /it
parent6fe8b0cd64c4b4e2386d994016b465b0386ed09c (diff)
downloadsonarqube-d1e303f8412f61f426a6c746cc2ac10b584940bd.tar.gz
sonarqube-d1e303f8412f61f426a6c746cc2ac10b584940bd.zip
SONAR-2867 Standard copy-paste detection should happen within a project, not only within a module
Diffstat (limited to 'it')
-rw-r--r--it/it-projects/duplications/cross-module/module1/sonar-project.properties5
-rw-r--r--it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo35
-rw-r--r--it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo.measures1
-rw-r--r--it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo23
-rw-r--r--it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo.measures1
-rw-r--r--it/it-projects/duplications/cross-module/module2/sonar-project.properties5
-rw-r--r--it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo35
-rw-r--r--it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo.measures1
-rw-r--r--it/it-projects/duplications/cross-module/sonar-project.properties4
-rw-r--r--it/it-tests/src/test/java/it/duplication/CrossModuleDuplicationsTest.java152
10 files changed, 262 insertions, 0 deletions
diff --git a/it/it-projects/duplications/cross-module/module1/sonar-project.properties b/it/it-projects/duplications/cross-module/module1/sonar-project.properties
new file mode 100644
index 00000000000..a4b8c4853a5
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module1/sonar-project.properties
@@ -0,0 +1,5 @@
+sonar.projectKey=module1
+sonar.projectName=Module 1
+sonar.projectVersion=1.0-SNAPSHOT
+sonar.sources=src/main/xoo
+sonar.language=xoo
diff --git a/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo
new file mode 100644
index 00000000000..5e494b196ab
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo
@@ -0,0 +1,35 @@
+package sample;
+
+public class File1 {
+
+ public File1() {
+ }
+
+ public void test() {
+ char[] charList = new char[30];
+ for (int i = 0; i < 10; i++) {
+ charList[i] = 'a';
+ }
+ for (int i = 0; i < 10; i++) {
+ charList[i] = 'a';
+ }
+ int intergerToBeIncremented = 0;
+ while (intergerToBeIncremented < 100) {
+ intergerToBeIncremented++;
+ }
+ int intergerToBeIncremented2 = 0;
+ while (intergerToBeIncremented2 < 100) {
+ intergerToBeIncremented2++;
+ }
+ String temp = "";
+ for (int i=0; i<10; i++){
+ temp += "say something"+i;
+ }
+ for (int i=0; i<20; i++){
+ temp += "say nothing"+i;
+ }
+ for (int i=0; i<30; i++){
+ temp += "always say nothing"+i;
+ }
+ }
+}
diff --git a/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo.measures b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo.measures
new file mode 100644
index 00000000000..5a79b0b5dbb
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File1.xoo.measures
@@ -0,0 +1 @@
+ncloc:36
diff --git a/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo
new file mode 100644
index 00000000000..00b502d423a
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo
@@ -0,0 +1,23 @@
+package sample;
+
+public class File1 {
+
+ public File1() {
+ }
+
+ public void otherMethod() {
+ String temp = "";
+ for (int i=0; i<10; i++){
+ temp += "say something"+i;
+ int nothing = 0;
+ }
+ for (int i=0; i<20; i++){
+ temp += "say nothing"+i;
+ int nothing = 1;
+ }
+ for (int i=0; i<30; i++){
+ temp += "always say nothing"+i;
+ int nothing = 2;
+ }
+ }
+}
diff --git a/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo.measures b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo.measures
new file mode 100644
index 00000000000..d90983a3e9f
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module1/src/main/xoo/sample/File2.xoo.measures
@@ -0,0 +1 @@
+ncloc:24
diff --git a/it/it-projects/duplications/cross-module/module2/sonar-project.properties b/it/it-projects/duplications/cross-module/module2/sonar-project.properties
new file mode 100644
index 00000000000..0b71b3d7548
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module2/sonar-project.properties
@@ -0,0 +1,5 @@
+sonar.projectKey=module2
+sonar.projectName=Module 2
+sonar.projectVersion=1.0-SNAPSHOT
+sonar.sources=src/main/xoo
+sonar.language=xoo
diff --git a/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo b/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo
new file mode 100644
index 00000000000..cc0b6612812
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo
@@ -0,0 +1,35 @@
+package sample;
+
+public class File1 {
+
+ public File1() {
+ }
+
+ public void test2() {
+ char[] charList = new char[30];
+ for (int i = 0; i < 10; i++) {
+ charList[i] = 'a';
+ }
+ for (int i = 0; i < 10; i++) {
+ charList[i] = 'a';
+ }
+ int intergerToBeIncremented = 0;
+ while (intergerToBeIncremented < 100) {
+ intergerToBeIncremented++;
+ }
+ int intergerToBeIncremented2 = 0;
+ while (intergerToBeIncremented2 < 100) {
+ intergerToBeIncremented2++;
+ }
+ String temp = "";
+ for (int i=0; i<10; i++){
+ temp += "say something"+i;
+ }
+ for (int i=0; i<20; i++){
+ temp += "say nothing"+i;
+ }
+ for (int i=0; i<30; i++){
+ temp += "always say nothing"+i;
+ }
+ }
+}
diff --git a/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo.measures b/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo.measures
new file mode 100644
index 00000000000..5a79b0b5dbb
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/module2/src/main/xoo/sample/File1.xoo.measures
@@ -0,0 +1 @@
+ncloc:36
diff --git a/it/it-projects/duplications/cross-module/sonar-project.properties b/it/it-projects/duplications/cross-module/sonar-project.properties
new file mode 100644
index 00000000000..f4c7496f179
--- /dev/null
+++ b/it/it-projects/duplications/cross-module/sonar-project.properties
@@ -0,0 +1,4 @@
+sonar.projectKey=cross-module
+sonar.projectName=Cross Module Duplication
+sonar.projectVersion=1.0-SNAPSHOT
+sonar.modules=module1,module2
diff --git a/it/it-tests/src/test/java/it/duplication/CrossModuleDuplicationsTest.java b/it/it-tests/src/test/java/it/duplication/CrossModuleDuplicationsTest.java
new file mode 100644
index 00000000000..39bad0abe2e
--- /dev/null
+++ b/it/it-tests/src/test/java/it/duplication/CrossModuleDuplicationsTest.java
@@ -0,0 +1,152 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 it.duplication;
+
+import com.google.common.collect.ImmutableMap;
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarRunner;
+import com.sonar.orchestrator.locator.FileLocation;
+import it.Category4Suite;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.wsclient.services.Resource;
+import org.sonar.wsclient.services.ResourceQuery;
+import util.ItUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CrossModuleDuplicationsTest {
+ private static final String PROJECT_KEY = "cross-module";
+ private static final String PROJECT_DIR = "duplications/" + PROJECT_KEY;
+ private File projectDir;
+
+ @ClassRule
+ public static Orchestrator orchestrator = Category4Suite.ORCHESTRATOR;
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @BeforeClass
+ public static void analyzeProjects() {
+
+ }
+
+ @Before
+ public void setUpProject() throws IOException {
+ orchestrator.resetData();
+ orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/duplication/xoo-duplication-profile.xml"));
+
+ FileUtils.copyDirectory(ItUtils.projectDir(PROJECT_DIR), temp.getRoot());
+ projectDir = temp.getRoot();
+ }
+
+ @Test
+ public void testDuplications() throws IOException {
+ analyzeProject(projectDir, PROJECT_KEY, true);
+ verifyDuplicationMeasures(PROJECT_KEY, 2, 54, 2, 56.3);
+
+ // File1 is the one duplicated in both modules
+ verifyDuplicationMeasures(PROJECT_KEY + ":module1:src/main/xoo/sample/File1.xoo", 1, 27, 1, 75);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module2:src/main/xoo/sample/File1.xoo", 1, 27, 1, 75);
+ }
+
+ @Test
+ // SONAR-6184
+ public void testGhostDuplication() throws IOException {
+ analyzeProject(projectDir, PROJECT_KEY, true);
+
+ verifyDuplicationMeasures(PROJECT_KEY + ":module1", 1, 27, 1, 45);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module2", 1, 27, 1, 75);
+
+ // move File2 from module1 to module2
+ File src = FileUtils.getFile(projectDir, "module1", "src", "main", "xoo", "sample", "File2.xoo");
+ File dst = FileUtils.getFile(projectDir, "module2", "src", "main", "xoo", "sample", "File2.xoo");
+ FileUtils.moveFile(src, dst);
+
+ src = new File(src.getParentFile(), "File2.xoo.measures");
+ dst = new File(dst.getParentFile(), "File2.xoo.measures");
+ FileUtils.moveFile(src, dst);
+
+ // duplication should remain unchanged (except for % of duplication)
+ analyzeProject(projectDir, PROJECT_KEY, false);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module1", 1, 27, 1, 75);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module2", 1, 27, 1, 45);
+ }
+
+ @Test
+ // SONAR-6184
+ public void testDuplicationFix() throws IOException {
+ analyzeProject(projectDir, PROJECT_KEY, true);
+
+ verifyDuplicationMeasures(PROJECT_KEY + ":module1", 1, 27, 1, 45);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module2", 1, 27, 1, 75);
+
+ // remove File1 from module1
+ File f1 = FileUtils.getFile(projectDir, "module1", "src", "main", "xoo", "sample", "File1.xoo");
+ File f1m = FileUtils.getFile(projectDir, "module2", "src", "main", "xoo", "sample", "File1.xoo.measures");
+ f1.delete();
+ f1m.delete();
+
+ // duplication should be 0
+ analyzeProject(projectDir, PROJECT_KEY, false);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module1", 0, 0, 0, 0);
+ verifyDuplicationMeasures(PROJECT_KEY + ":module2", 0, 0, 0, 0);
+ }
+
+ private static SonarRunner analyzeProject(File projectDir, String projectKey, boolean create, String... additionalProperties) {
+ if (create) {
+ orchestrator.getServer().provisionProject(projectKey, projectKey);
+ orchestrator.getServer().associateProjectToQualityProfile(projectKey, "xoo", "xoo-duplication-profile");
+ }
+
+ SonarRunner sonarRunner = SonarRunner.create(projectDir);
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+
+ for (int i = 0; i < additionalProperties.length; i += 2) {
+ builder.put(additionalProperties[i], additionalProperties[i + 1]);
+ }
+ SonarRunner scan = sonarRunner.setDebugLogs(true).setProperties(builder.build());
+ orchestrator.executeBuild(scan);
+ return scan;
+ }
+
+ private static void verifyDuplicationMeasures(String componentKey, int duplicatedBlocks, int duplicatedLines, int duplicatedFiles, double duplicatedLinesDensity) {
+ Resource file = getComponent(componentKey);
+ assertThat(file.getMeasureValue("duplicated_blocks").intValue()).isEqualTo(duplicatedBlocks);
+ assertThat(file.getMeasureValue("duplicated_lines").intValue()).isEqualTo(duplicatedLines);
+ assertThat(file.getMeasureValue("duplicated_files").intValue()).isEqualTo(duplicatedFiles);
+ assertThat(file.getMeasureValue("duplicated_lines_density")).isEqualTo(duplicatedLinesDensity);
+ }
+
+ private static Resource getComponent(String key) {
+ Resource component = orchestrator.getServer().getWsClient()
+ .find(ResourceQuery.createForMetrics(key, "duplicated_lines", "duplicated_blocks", "duplicated_files", "duplicated_lines_density"));
+ assertThat(component).isNotNull();
+ return component;
+ }
+}