diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-12-21 13:54:14 +0100 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-12-21 14:37:03 +0100 |
commit | d1e303f8412f61f426a6c746cc2ac10b584940bd (patch) | |
tree | b68693cc8caced2aeee5b06a3590b3e1392e8011 /it | |
parent | 6fe8b0cd64c4b4e2386d994016b465b0386ed09c (diff) | |
download | sonarqube-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')
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; + } +} |