]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10311 add IT on rule rekeying applying to issues
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 5 Feb 2018 15:59:48 +0000 (16:59 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 8 Feb 2018 12:41:00 +0000 (13:41 +0100)
tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java
tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java [new file with mode: 0644]
tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java
tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/RekeyingRulesSensor.java [new file with mode: 0644]
tests/projects/foo-sample/sonar-project.properties [new file with mode: 0644]
tests/projects/foo-sample/src/main/foo/sample/Sample.foo [new file with mode: 0644]
tests/projects/foo-sample/src/main/foo/sample/Sample2.foo [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/rule/RuleReKeyingTest.java

index 673c8a002cda790ab17ec4ffd583f01ac570ae29..c8c15a8ed3d617b6acebe557ea2cb845d07608c6 100644 (file)
@@ -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 (file)
index 0000000..0e69550
--- /dev/null
@@ -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();
+    }
+  }
+}
index 673c8a002cda790ab17ec4ffd583f01ac570ae29..c8c15a8ed3d617b6acebe557ea2cb845d07608c6 100644 (file)
@@ -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 (file)
index 0000000..8ea99d8
--- /dev/null
@@ -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 (file)
index 0000000..a51aa21
--- /dev/null
@@ -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 (file)
index 0000000..41871e1
--- /dev/null
@@ -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 (file)
index 0000000..41871e1
--- /dev/null
@@ -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();
+               }
+       }
+}
index 0f0ec465846421140cba6e63e05819026cc710a8..719b2ec6dfc4e9c2173b79130e52a5739346d018 100644 (file)
 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.Issue> 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<Issues.Issue> 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<Issues.Issue> 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<Issues.Issue> issuesAfterDowngrade, String... ruleKeys) {
+    assertThat(issuesAfterDowngrade)
+      .extracting(Issues.Issue::getRule)
+      .containsOnly(ruleKeys);
+  }
+
+  private static void verifyDate(List<Issues.Issue> issuesAfterUpgrade, ThrowingExtractor<Issues.Issue, String, RuntimeException> 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));
+  }
 }