From 56844138c6d4b5a0a0365c08fd44d94135395154 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 19 Apr 2018 15:14:31 +0200 Subject: [PATCH] SONAR-10593 SONAR-10315 support plugin uninstall before CE processing --- .../LoadReportAnalysisMetadataHolderStep.java | 8 +- ...dReportAnalysisMetadataHolderStepTest.java | 71 +++++++++++--- .../qa/bluegreen/BlueGreenPlugin.java | 3 +- .../qa/bluegreen/BuiltInProfilesV1.java | 8 +- .../qa/bluegreen/MetricsDefinitionV1.java | 34 +++++++ .../qa/bluegreen/RulesDefinitionV1.java | 13 ++- .../{RuleSensorV1.java => SensorV1.java} | 20 +++- .../qa/bluegreen/BlueGreenPlugin.java | 3 +- .../qa/bluegreen/BuiltInProfilesV2.java | 5 +- .../qa/bluegreen/MetricsDefinitionV2.java | 35 +++++++ .../qa/bluegreen/RulesDefinitionV2.java | 14 ++- .../{RuleSensorV2.java => SensorV2.java} | 20 +++- .../tests/serverSystem/BlueGreenTest.java | 93 +++++++++++++------ 13 files changed, 268 insertions(+), 59 deletions(-) create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV1.java rename tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/{RuleSensorV1.java => SensorV1.java} (79%) create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV2.java rename tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/{RuleSensorV2.java => SensorV2.java} (79%) diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java index 88bcb8fffaf4..3ef211cc2cbf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java @@ -29,7 +29,6 @@ import org.sonar.api.utils.MessageException; import org.sonar.ce.queue.CeTask; import org.sonar.core.component.ComponentKeys; -import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; @@ -42,13 +41,13 @@ import org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile; import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder; import org.sonar.server.computation.task.projectanalysis.analysis.Organization; -import org.sonar.server.project.Project; import org.sonar.server.computation.task.projectanalysis.analysis.ScannerPlugin; import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader; import org.sonar.server.computation.task.projectanalysis.component.BranchLoader; import org.sonar.server.computation.task.step.ComputationStep; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.OrganizationFlags; +import org.sonar.server.project.Project; import org.sonar.server.qualityprofile.QualityProfile; import static com.google.common.base.Preconditions.checkState; @@ -153,13 +152,12 @@ private void loadQualityProfiles(ScannerReport.Metadata reportMetadata, Organiza @CheckForNull private String getBasePluginKey(Plugin p) { - PluginInfo pluginInfo = pluginRepository.getPluginInfo(p.getKey()); - if (pluginInfo == null) { + if (!pluginRepository.hasPlugin(p.getKey())) { // May happen if plugin was uninstalled between start of scanner analysis and now. // But it doesn't matter since all active rules are removed anyway, so no issues will be reported return null; } - return pluginInfo.getBasePlugin(); + return pluginRepository.getPluginInfo(p.getKey()).getBasePlugin(); } /** diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java index 587d5ae53493..8a392927a17b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java @@ -22,11 +22,15 @@ import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; +import org.sonar.api.Plugin; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.System2; import org.sonar.ce.queue.CeTask; @@ -39,7 +43,6 @@ import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule; import org.sonar.server.computation.task.projectanalysis.analysis.Organization; -import org.sonar.server.project.Project; import org.sonar.server.computation.task.projectanalysis.analysis.ScannerPlugin; import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule; import org.sonar.server.computation.task.projectanalysis.component.BranchLoader; @@ -47,7 +50,9 @@ import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.OrganizationFlags; import org.sonar.server.organization.TestDefaultOrganizationProvider; +import org.sonar.server.project.Project; +import static java.util.Arrays.stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.ArgumentMatchers.any; @@ -71,7 +76,7 @@ public class LoadReportAnalysisMetadataHolderStepTest { private DbClient dbClient = db.getDbClient(); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private PluginRepository pluginRepository = mock(PluginRepository.class); + private TestPluginRepository pluginRepository = new TestPluginRepository(); private OrganizationFlags organizationFlags = mock(OrganizationFlags.class); private ComponentDto project; private ComputationStep underTest; @@ -330,8 +335,8 @@ public void execute_fails_with_MessageException_when_report_has_quality_profiles metadataBuilder .setOrganizationKey(organization1.getKey()) .setProjectKey(projectInOrg1.getDbKey()); - metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build()); - metadataBuilder.getMutableQprofilesPerLanguage().put("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build()); + metadataBuilder.putQprofilesPerLanguage("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build()); + metadataBuilder.putQprofilesPerLanguage("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build()); reportReader.setMetadata(metadataBuilder.build()); db.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1")); @@ -353,7 +358,7 @@ public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_no metadataBuilder .setOrganizationKey(organization.getKey()) .setProjectKey(project.getDbKey()); - metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build()); + metadataBuilder.putQprofilesPerLanguage("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build()); reportReader.setMetadata(metadataBuilder.build()); ComputationStep underTest = createStep(createCeTask(project.getDbKey(), organization.getUuid())); @@ -363,22 +368,28 @@ public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_no @Test public void execute_read_plugins_from_report() { - ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder(); - metadataBuilder.getMutablePluginsByKey().put("java", ScannerReport.Metadata.Plugin.newBuilder().setKey("java").setUpdatedAt(12345L).build()); - metadataBuilder.getMutablePluginsByKey().put("php", ScannerReport.Metadata.Plugin.newBuilder().setKey("php").setUpdatedAt(678910L).build()); - metadataBuilder.getMutablePluginsByKey().put("customjava", ScannerReport.Metadata.Plugin.newBuilder().setKey("customjava").setUpdatedAt(111111L).build()); - when(pluginRepository.getPluginInfo("customjava")).thenReturn(new PluginInfo("customjava").setBasePlugin("java")); + // the installed plugins + pluginRepository.add( + new PluginInfo("java"), + new PluginInfo("customjava").setBasePlugin("java"), + new PluginInfo("php")); + // the plugins sent by scanner + ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder(); + metadataBuilder.putPluginsByKey("java", ScannerReport.Metadata.Plugin.newBuilder().setKey("java").setUpdatedAt(10L).build()); + metadataBuilder.putPluginsByKey("php", ScannerReport.Metadata.Plugin.newBuilder().setKey("php").setUpdatedAt(20L).build()); + metadataBuilder.putPluginsByKey("customjava", ScannerReport.Metadata.Plugin.newBuilder().setKey("customjava").setUpdatedAt(30L).build()); + metadataBuilder.putPluginsByKey("uninstalled", ScannerReport.Metadata.Plugin.newBuilder().setKey("uninstalled").setUpdatedAt(40L).build()); reportReader.setMetadata(metadataBuilder.build()); underTest.execute(); - assertThat(analysisMetadataHolder.getScannerPluginsByKey()).containsOnlyKeys("java", "php", "customjava"); assertThat(analysisMetadataHolder.getScannerPluginsByKey().values()).extracting(ScannerPlugin::getKey, ScannerPlugin::getBasePluginKey, ScannerPlugin::getUpdatedAt) - .containsOnly( - tuple("java", null, 12345L), - tuple("customjava", "java", 111111L), - tuple("php", null, 678910L)); + .containsExactlyInAnyOrder( + tuple("java", null, 10L), + tuple("php", null, 20L), + tuple("customjava", "java", 30L), + tuple("uninstalled", null, 40L)); } private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) { @@ -398,4 +409,34 @@ private CeTask createCeTask(String projectKey, String organizationUuid) { return res; } + private static class TestPluginRepository implements PluginRepository { + private final Map pluginsMap = new HashMap<>(); + + void add(PluginInfo... plugins) { + stream(plugins).forEach(p -> pluginsMap.put(p.getKey(), p)); + } + + @Override + public Collection getPluginInfos() { + return pluginsMap.values(); + } + + @Override + public PluginInfo getPluginInfo(String key) { + if (!pluginsMap.containsKey(key)) { + throw new IllegalArgumentException(); + } + return pluginsMap.get(key); + } + + @Override + public Plugin getPluginInstance(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasPlugin(String key) { + return pluginsMap.containsKey(key); + } + } } diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java index ea0eea80322a..046347e345ab 100644 --- a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java @@ -27,9 +27,10 @@ public class BlueGreenPlugin implements Plugin { public void define(Context context) { context.addExtensions( BuiltInProfilesV1.class, + MetricsDefinitionV1.class, PageDefinitionV1.class, RulesDefinitionV1.class, - RuleSensorV1.class); + SensorV1.class); } } diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java index 1d19f4e5ad92..911781faf525 100644 --- a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java @@ -25,8 +25,12 @@ public class BuiltInProfilesV1 implements BuiltInQualityProfilesDefinition { @Override public void define(Context context) { NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("Blue Profile", "xoo"); - profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "a").overrideSeverity("BLOCKER"); - profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "b").overrideSeverity("CRITICAL"); + profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "a") + .overrideSeverity("BLOCKER"); + NewBuiltInActiveRule activeB = profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "b") + .overrideSeverity("CRITICAL"); + activeB.overrideParam("p1", "one"); + activeB.overrideParam("p2", "two"); profile.done(); } } diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV1.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV1.java new file mode 100644 index 000000000000..e681d679d36c --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV1.java @@ -0,0 +1,34 @@ +/* + * 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.sonarqube.qa.bluegreen; + +import java.util.Arrays; +import java.util.List; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +public class MetricsDefinitionV1 implements Metrics { + @Override + public List getMetrics() { + return Arrays.asList( + new Metric.Builder("blue", "Blue", Metric.ValueType.INT).create(), + new Metric.Builder("bluegreen", "BlueGreen", Metric.ValueType.INT).create()); + } +} diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java index e6fbc56bbe45..4ef3ed24c01b 100644 --- a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java @@ -19,6 +19,7 @@ */ package org.sonarqube.qa.bluegreen; +import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition; public class RulesDefinitionV1 implements RulesDefinition { @@ -28,8 +29,16 @@ public class RulesDefinitionV1 implements RulesDefinition { @Override public void define(Context context) { NewRepository repo = context.createRepository(REPOSITORY_KEY, "xoo").setName("BlueGreen"); - repo.createRule("a").setName("Rule A").setHtmlDescription("Rule A"); - repo.createRule("b").setName("Rule B").setHtmlDescription("Rule B"); + repo.createRule("a") + .setName("Rule A") + .setHtmlDescription("Rule A") + .setType(RuleType.VULNERABILITY); + NewRule ruleB = repo.createRule("b") + .setName("Rule B") + .setHtmlDescription("Rule B") + .setType(RuleType.VULNERABILITY); + ruleB.createParam("p1").setName("Param One"); + ruleB.createParam("p2").setName("Param Two"); repo.done(); } } diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/SensorV1.java similarity index 79% rename from tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java rename to tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/SensorV1.java index 1d377825a3fe..35004ad5893b 100644 --- a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/SensorV1.java @@ -20,6 +20,7 @@ package org.sonarqube.qa.bluegreen; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; @@ -28,7 +29,13 @@ import static org.sonarqube.qa.bluegreen.RulesDefinitionV1.REPOSITORY_KEY; -public class RuleSensorV1 implements Sensor { +public class SensorV1 implements Sensor { + + private final MetricFinder metricFinder; + + public SensorV1(MetricFinder metricFinder) { + this.metricFinder = metricFinder; + } @Override public void describe(SensorDescriptor descriptor) { @@ -43,6 +50,17 @@ public void execute(SensorContext context) { saveIssue(context, inputFile, "a"); saveIssue(context, inputFile, "b"); } + + context.newMeasure() + .forMetric(metricFinder.findByKey("blue")) + .on(context.module()) + .withValue(10) + .save(); + context.newMeasure() + .forMetric(metricFinder.findByKey("bluegreen")) + .on(context.module()) + .withValue(20) + .save(); } private void saveIssue(SensorContext context, InputFile inputFile, String ruleKey) { diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java index 156bf7a612f5..e10434bf6d6d 100644 --- a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java @@ -27,9 +27,10 @@ public class BlueGreenPlugin implements Plugin { public void define(Context context) { context.addExtensions( BuiltInProfilesV2.class, + MetricsDefinitionV2.class, PageDefinitionV2.class, RulesDefinitionV2.class, - RuleSensorV2.class); + SensorV2.class); } } diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java index ccb8e096010b..42434bd0218b 100644 --- a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java @@ -25,7 +25,10 @@ public class BuiltInProfilesV2 implements BuiltInQualityProfilesDefinition { @Override public void define(Context context) { NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("Green Profile", "xoo"); - profile.activateRule(RulesDefinitionV2.REPOSITORY_KEY, "b").overrideSeverity("MINOR"); + NewBuiltInActiveRule activeB = profile.activateRule(RulesDefinitionV2.REPOSITORY_KEY, "b") + .overrideSeverity("MINOR"); + activeB.overrideParam("p2", "two"); + activeB.overrideParam("p3", "three"); profile.activateRule(RulesDefinitionV2.REPOSITORY_KEY, "c").overrideSeverity("INFO"); profile.done(); } diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV2.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV2.java new file mode 100644 index 000000000000..5b98a5dc1366 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/MetricsDefinitionV2.java @@ -0,0 +1,35 @@ +/* + * 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.sonarqube.qa.bluegreen; + +import java.util.Arrays; +import java.util.List; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +public class MetricsDefinitionV2 implements Metrics { + @Override + public List getMetrics() { + return Arrays.asList( + // the metric "blue" has been dropped + new Metric.Builder("bluegreen", "BlueGreen", Metric.ValueType.INT).create(), + new Metric.Builder("green", "Green", Metric.ValueType.INT).create()); + } +} diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java index 3e04908a5703..41f563a506c5 100644 --- a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java @@ -19,6 +19,7 @@ */ package org.sonarqube.qa.bluegreen; +import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition; public class RulesDefinitionV2 implements RulesDefinition { @@ -28,8 +29,17 @@ public class RulesDefinitionV2 implements RulesDefinition { @Override public void define(Context context) { NewRepository repo = context.createRepository(REPOSITORY_KEY, "xoo").setName("BlueGreen"); - repo.createRule("b").setName("Rule B").setHtmlDescription("Rule B"); - repo.createRule("c").setName("Rule C").setHtmlDescription("Rule C"); + NewRule ruleB = repo.createRule("b") + .setName("Rule B") + .setHtmlDescription("Rule B") + .setType(RuleType.VULNERABILITY); + ruleB.createParam("p2").setName("Param Two"); + ruleB.createParam("p3").setName("Param Three"); + + repo.createRule("c") + .setName("Rule C") + .setHtmlDescription("Rule C") + .setType(RuleType.VULNERABILITY); repo.done(); } } diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/SensorV2.java similarity index 79% rename from tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java rename to tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/SensorV2.java index 5dde5ddd1b2a..3edd3c6aeaff 100644 --- a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/SensorV2.java @@ -20,6 +20,7 @@ package org.sonarqube.qa.bluegreen; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; @@ -28,7 +29,13 @@ import static org.sonarqube.qa.bluegreen.RulesDefinitionV2.REPOSITORY_KEY; -public class RuleSensorV2 implements Sensor { +public class SensorV2 implements Sensor { + + private final MetricFinder metricFinder; + + public SensorV2(MetricFinder metricFinder) { + this.metricFinder = metricFinder; + } @Override public void describe(SensorDescriptor descriptor) { @@ -43,6 +50,17 @@ public void execute(SensorContext context) { saveIssue(context, inputFile, "b"); saveIssue(context, inputFile, "c"); } + + context.newMeasure() + .forMetric(metricFinder.findByKey("bluegreen")) + .on(context.module()) + .withValue(30) + .save(); + context.newMeasure() + .forMetric(metricFinder.findByKey("green")) + .on(context.module()) + .withValue(40) + .save(); } private void saveIssue(SensorContext context, InputFile inputFile, String ruleKey) { diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java index 106a47a1e827..cc81e8e60742 100644 --- a/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java +++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java @@ -23,7 +23,6 @@ import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarScanner; import java.io.File; -import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -34,11 +33,12 @@ import org.junit.rules.TestRule; import org.junit.rules.Timeout; import org.sonarqube.qa.util.Tester; -import org.sonarqube.qa.util.pageobjects.Navigation; import org.sonarqube.ws.Ce; import org.sonarqube.ws.Projects; import org.sonarqube.ws.client.ce.ActivityStatusRequest; +import org.sonarqube.ws.client.plugins.UninstallRequest; import org.sonarqube.ws.client.qualityprofiles.AddProjectRequest; +import util.ItUtils; import util.XooProjectBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -68,7 +68,7 @@ public void tearDown() { } @Test - public void test_change_of_version_at_runtime() throws Exception { + public void upgrade_analyzer_when_analysis_is_pending_in_compute_engine_queue() throws Exception { orchestrator = newOrchestratorBuilder() .addPlugin(pluginArtifact("blue-green-plugin-v1")) .addPlugin(xooPlugin()) @@ -77,44 +77,50 @@ public void test_change_of_version_at_runtime() throws Exception { orchestrator.start(); tester.before(); - // pause compute engine so that analysis is kept pending - tester.wsClient().ce().pause(); - Projects.CreateWsResponse.Project project = tester.projects().provision(); - associateProjectToProfile(project, "Blue Profile"); - analyze(project); - assertThat(loadCeActivity().getPending()).isEqualTo(1); + Project project = new Project(); + project.associateToXooProfile("Blue Profile"); + project.analyzeAndWait(); + // assert 2 issues + security rating E (rule A is blocker, rule B is critical) + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "violations")).isEqualTo(2.0); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "security_rating")).isEqualTo(5.0); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "blue")).isEqualTo(10.0); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "bluegreen")).isEqualTo(20.0); - // open browser - Navigation browser = tester.openBrowser(); + // remove rule "A" and metric "blue" between analysis and execution of Compute Engine + // 1. pause compute engine so that the second analysis is kept pending + tester.wsClient().ce().pause(); + project.analyze(); + assertThat(loadCeActivity().getPending()).isEqualTo(1); - // upgrade plugin + // 2. upgrade plugin and verify that analysis is still pending in CE queue File pluginV2 = pluginArtifact("blue-green-plugin-v2").getFile(); FileUtils.copyFileToDirectory(pluginV2, new File(orchestrator.getServer().getHome(), "extensions/downloads")); orchestrator.restartServer(); - - // analysis task is still pending Ce.ActivityStatusWsResponse ceActivity = loadCeActivity(); assertThat(ceActivity.getInProgress()).isEqualTo(0); assertThat(ceActivity.getPending()).isEqualTo(1); + // 3. resume the queue and verify that the issue on rule A is ignored. Only + // the critical issue on rule B is remaining resumeAndWaitForCeQueueEmpty(); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "violations")).isEqualTo(1.0); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "security_rating")).isEqualTo(4.0); + assertThat(ItUtils.getMeasure(orchestrator, project.getKey(), "blue")).isNull(); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "bluegreen")).isEqualTo(20.0); - // TODO check issues and measures - } - - private void analyze(Projects.CreateWsResponse.Project project) throws IOException { - File projectDir = new XooProjectBuilder(project.getKey()) - .setFilesPerModule(1) - .build(temp.newFolder()); - orchestrator.executeBuild(SonarScanner.create(projectDir), false); - } + // test removal of analyzer. Analysis should not fail when queue is resumed. + tester.wsClient().ce().pause(); + project.analyze(); + tester.wsClient().plugins().uninstall(new UninstallRequest().setKey("xoo")); + tester.wsClient().plugins().uninstall(new UninstallRequest().setKey("bluegreen")); + orchestrator.restartServer(); - private void associateProjectToProfile(Projects.CreateWsResponse.Project project, String xooProfileName) { - tester.wsClient().qualityprofiles().addProject(new AddProjectRequest() - .setProject(project.getKey()) - .setLanguage("xoo") - .setQualityProfile(xooProfileName)); + resumeAndWaitForCeQueueEmpty(); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "violations")).isEqualTo(0.0); + assertThat(ItUtils.getMeasureAsDouble(orchestrator, project.getKey(), "security_rating")).isEqualTo(1.0); + assertThat(ItUtils.getMeasure(orchestrator, project.getKey(), "blue")).isNull(); + assertThat(ItUtils.getMeasure(orchestrator, project.getKey(), "bluegreen")).isNull(); } private void resumeAndWaitForCeQueueEmpty() { @@ -131,4 +137,35 @@ private void resumeAndWaitForCeQueueEmpty() { private Ce.ActivityStatusWsResponse loadCeActivity() { return tester.wsClient().ce().activityStatus(new ActivityStatusRequest()); } + + private class Project { + private final Projects.CreateWsResponse.Project project; + private final File dir; + + Project() throws Exception { + this.project = tester.projects().provision(); + this.dir = new XooProjectBuilder(project.getKey()) + .setFilesPerModule(1) + .build(temp.newFolder()); + } + + String getKey() { + return project.getKey(); + } + + void associateToXooProfile(String name) { + tester.wsClient().qualityprofiles().addProject(new AddProjectRequest() + .setProject(project.getKey()) + .setLanguage("xoo") + .setQualityProfile(name)); + } + + void analyzeAndWait() { + orchestrator.executeBuild(SonarScanner.create(dir), true); + } + + void analyze() { + orchestrator.executeBuild(SonarScanner.create(dir), false); + } + } }