From fc7ff3ff910868bd3e1032b21d79ba67edcf1abe Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 5 Feb 2018 16:59:48 +0100 Subject: [PATCH] SONAR-10311 add IT on rule rekeying applying to issues --- .../main/java/org/sonar/foo/FooPlugin.java | 4 +- .../sonar/foo/rule/RekeyingRulesSensor.java | 54 ++++++++++++++++++ .../main/java/org/sonar/foo/FooPlugin.java | 4 +- .../sonar/foo/rule/RekeyingRulesSensor.java | 55 +++++++++++++++++++ .../foo-sample/sonar-project.properties | 5 ++ .../foo-sample/src/main/foo/sample/Sample.foo | 16 ++++++ .../src/main/foo/sample/Sample2.foo | 16 ++++++ .../tests/rule/RuleReKeyingTest.java | 50 +++++++++++++++++ 8 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java create mode 100644 tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java create mode 100644 tests/projects/foo-sample/sonar-project.properties create mode 100644 tests/projects/foo-sample/src/main/foo/sample/Sample.foo create mode 100644 tests/projects/foo-sample/src/main/foo/sample/Sample2.foo diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java index 673c8a002cd..c8c15a8ed3d 100644 --- a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java +++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java @@ -22,6 +22,7 @@ package org.sonar.foo; import org.sonar.api.Plugin; import org.sonar.foo.rule.FooBasicProfile; import org.sonar.foo.rule.FooRulesDefinition; +import org.sonar.foo.rule.RekeyingRulesSensor; /** * Plugin entry-point, as declared in pom.xml. @@ -33,7 +34,8 @@ public class FooPlugin implements Plugin { context.addExtensions( Foo.class, FooRulesDefinition.class, - FooBasicProfile.class); + FooBasicProfile.class, + RekeyingRulesSensor.class); } } diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java new file mode 100644 index 00000000000..0e69550382b --- /dev/null +++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java @@ -0,0 +1,54 @@ +/* + * 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.sonar.foo.rule; + +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.foo.Foo; + +import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY; + +public class RekeyingRulesSensor implements Sensor { + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(FOO_REPOSITORY) + .onlyOnLanguage(Foo.KEY) + .name("Sensor generating one issue per Foo file for re-keyed rules"); + + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage(Foo.KEY))) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile)) + .forRule(RuleKey.of(FOO_REPOSITORY, "ToBeRenamed")) + .save(); + newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile)) + .forRule(RuleKey.of(FOO_REPOSITORY, "ToBeRenamedAndMoved")) + .save(); + } + } +} diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java index 673c8a002cd..c8c15a8ed3d 100644 --- a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java +++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java @@ -22,6 +22,7 @@ package org.sonar.foo; import org.sonar.api.Plugin; import org.sonar.foo.rule.FooBasicProfile; import org.sonar.foo.rule.FooRulesDefinition; +import org.sonar.foo.rule.RekeyingRulesSensor; /** * Plugin entry-point, as declared in pom.xml. @@ -33,7 +34,8 @@ public class FooPlugin implements Plugin { context.addExtensions( Foo.class, FooRulesDefinition.class, - FooBasicProfile.class); + FooBasicProfile.class, + RekeyingRulesSensor.class); } } diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java new file mode 100644 index 00000000000..8ea99d828e6 --- /dev/null +++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java @@ -0,0 +1,55 @@ +/* + * 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.sonar.foo.rule; + +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.foo.Foo; + +import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY; +import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY_2; + +public class RekeyingRulesSensor implements Sensor { + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(FOO_REPOSITORY, FOO_REPOSITORY_2) + .onlyOnLanguage(Foo.KEY) + .name("Sensor generating one issue per Xoo file for re-keyed rules"); + + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage(Foo.KEY))) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile)) + .forRule(RuleKey.of(FOO_REPOSITORY, "Renamed")) + .save(); + newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile)) + .forRule(RuleKey.of(FOO_REPOSITORY_2, "RenamedAndMoved")) + .save(); + } + } +} diff --git a/tests/projects/foo-sample/sonar-project.properties b/tests/projects/foo-sample/sonar-project.properties new file mode 100644 index 00000000000..a51aa21ebfa --- /dev/null +++ b/tests/projects/foo-sample/sonar-project.properties @@ -0,0 +1,5 @@ +sonar.projectKey=sample +sonar.projectName=Sample +sonar.projectVersion=1.0-SNAPSHOT +sonar.sources=src/main/foo +sonar.language=foo diff --git a/tests/projects/foo-sample/src/main/foo/sample/Sample.foo b/tests/projects/foo-sample/src/main/foo/sample/Sample.foo new file mode 100644 index 00000000000..41871e123a3 --- /dev/null +++ b/tests/projects/foo-sample/src/main/foo/sample/Sample.foo @@ -0,0 +1,16 @@ +package sample; + +public class Sample { + + public Sample(int i) { + int j = i++; + } + + private String myMethod() { + if (foo == bar) { + return "hello"; + } else { + throw new IllegalStateException(); + } + } +} diff --git a/tests/projects/foo-sample/src/main/foo/sample/Sample2.foo b/tests/projects/foo-sample/src/main/foo/sample/Sample2.foo new file mode 100644 index 00000000000..41871e123a3 --- /dev/null +++ b/tests/projects/foo-sample/src/main/foo/sample/Sample2.foo @@ -0,0 +1,16 @@ +package sample; + +public class Sample { + + public Sample(int i) { + int j = i++; + } + + private String myMethod() { + if (foo == bar) { + return "hello"; + } else { + throw new IllegalStateException(); + } + } +} diff --git a/tests/src/test/java/org/sonarqube/tests/rule/RuleReKeyingTest.java b/tests/src/test/java/org/sonarqube/tests/rule/RuleReKeyingTest.java index 0f0ec465846..719b2ec6dfc 100644 --- a/tests/src/test/java/org/sonarqube/tests/rule/RuleReKeyingTest.java +++ b/tests/src/test/java/org/sonarqube/tests/rule/RuleReKeyingTest.java @@ -20,14 +20,21 @@ package org.sonarqube.tests.rule; import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarScanner; import java.io.File; +import java.util.List; +import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.After; import org.junit.Test; import org.sonarqube.qa.util.Tester; +import org.sonarqube.ws.Issues; import org.sonarqube.ws.client.PostRequest; +import org.sonarqube.ws.client.issues.SearchRequest; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static util.ItUtils.pluginArtifact; +import static util.ItUtils.projectDir; public class RuleReKeyingTest { @@ -56,6 +63,14 @@ public class RuleReKeyingTest { verifyRuleCount(16, 16); + analyseProject("2017-12-31"); + List issues = tester.wsClient().issues() + .search(new SearchRequest().setProjects(singletonList("sample"))) + .getIssuesList(); + verifyRuleKey(issues, "foo:ToBeRenamed", "foo:ToBeRenamedAndMoved"); + verifyDate(issues, Issues.Issue::getCreationDate, "2017-12-31"); + verifyDate(issues, Issues.Issue::getUpdateDate, "2017-12-31"); + // uninstall plugin V1 tester.wsClient().wsConnector().call(new PostRequest("api/plugins/uninstall").setParam("key", "foo")).failIfNotSuccessful(); // install plugin V2 @@ -67,6 +82,14 @@ public class RuleReKeyingTest { // one rule deleted, one rule added, two rules re-keyed verifyRuleCount(16, 17); + analyseProject("2018-01-02"); + List issuesAfterUpgrade = tester.wsClient().issues() + .search(new SearchRequest().setProjects(singletonList("sample"))) + .getIssuesList(); + verifyRuleKey(issuesAfterUpgrade, "foo:Renamed", "foo2:RenamedAndMoved"); + verifyDate(issuesAfterUpgrade, Issues.Issue::getCreationDate, "2017-12-31"); + verifyDate(issuesAfterUpgrade, Issues.Issue::getUpdateDate, "2018-01-02"); + // uninstall plugin V2 tester.wsClient().wsConnector().call(new PostRequest("api/plugins/uninstall").setParam("key", "foo")).failIfNotSuccessful(); // install plugin V1 @@ -76,10 +99,37 @@ public class RuleReKeyingTest { // new rule removed, removed rule recreated, two rules re-keyed back verifyRuleCount(16, 17); + + analyseProject("2018-01-16"); + List issuesAfterDowngrade = tester.wsClient().issues() + .search(new SearchRequest().setProjects(singletonList("sample"))) + .getIssuesList(); + verifyRuleKey(issuesAfterDowngrade, "foo:ToBeRenamed", "foo:ToBeRenamedAndMoved"); + verifyDate(issuesAfterDowngrade, Issues.Issue::getCreationDate, "2017-12-31"); + verifyDate(issuesAfterDowngrade, Issues.Issue::getUpdateDate, "2018-01-16"); + } + + private static void verifyRuleKey(List issuesAfterDowngrade, String... ruleKeys) { + assertThat(issuesAfterDowngrade) + .extracting(Issues.Issue::getRule) + .containsOnly(ruleKeys); + } + + private static void verifyDate(List issuesAfterUpgrade, ThrowingExtractor getUpdateDate, String date) { + assertThat(issuesAfterUpgrade) + .extracting(getUpdateDate) + .usingElementComparator((a, b) -> a.startsWith(b) ? 0 : -1) + .containsOnly(date + "T00:00:00"); } private void verifyRuleCount(int wsRuleCount, int dbRuleCount) { assertThat(tester.wsClient().rules().list().getRulesList()).hasSize(wsRuleCount); assertThat(orchestrator.getDatabase().countSql("select count(*) from rules")).isEqualTo(dbRuleCount); } + + private void analyseProject(String projectDate) { + orchestrator.executeBuild( + SonarScanner.create(projectDir("foo-sample")) + .setProperty("sonar.projectDate", projectDate)); + } } -- 2.39.5