From efdcb66474cb9fea9d77501e8dad428cd81cdd1e Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 19 Apr 2018 14:28:00 +0200 Subject: [PATCH] SONAR-10593 CE should ignore issues on inactive rules --- .../issue/IssueCreationDateCalculator.java | 8 +- .../projectanalysis/issue/IssueVisitor.java | 3 + .../issue/TrackerRawInputFactory.java | 14 +- .../issue/IntegrateIssuesVisitorTest.java | 41 +++--- .../issue/TrackerRawInputFactoryTest.java | 112 +++++++++++---- .../AlwaysActiveRulesHolderImpl.java | 34 +++++ settings.gradle | 2 + tests/build.gradle | 2 + .../plugins/blue-green-plugin-v1/build.gradle | 26 ++++ .../qa/bluegreen/BlueGreenPlugin.java | 35 +++++ .../qa/bluegreen/BuiltInProfilesV1.java | 33 +++++ .../qa/bluegreen/PageDefinitionV1.java | 32 +++++ .../sonarqube/qa/bluegreen/RuleSensorV1.java | 55 +++++++ .../qa/bluegreen/RulesDefinitionV1.java | 35 +++++ .../sonarqube/qa/bluegreen/package-info.java | 23 +++ .../src/main/resources/static/global_page.js | 23 +++ .../plugins/blue-green-plugin-v2/build.gradle | 26 ++++ .../qa/bluegreen/BlueGreenPlugin.java | 35 +++++ .../qa/bluegreen/BuiltInProfilesV2.java | 33 +++++ .../qa/bluegreen/PageDefinitionV2.java | 32 +++++ .../sonarqube/qa/bluegreen/RuleSensorV2.java | 55 +++++++ .../qa/bluegreen/RulesDefinitionV2.java | 35 +++++ .../sonarqube/qa/bluegreen/package-info.java | 23 +++ .../src/main/resources/static/global_page.js | 23 +++ tests/plugins/blue-green-plugin/build.gradle | 29 ++++ .../qa/bluegreen/BlueGreenPlugin.java | 41 ++++++ .../qa/bluegreen/BuiltInProfilesV1.java | 4 + .../qa/bluegreen/BuiltInProfilesV2.java | 15 ++ .../sonarqube/qa/bluegreen/RuleSensorV1.java | 64 +++++++++ .../sonarqube/qa/bluegreen/RuleSensorV2.java | 55 +++++++ .../qa/bluegreen/RulesDefinitionV1.java | 4 + .../qa/bluegreen/RulesDefinitionV2.java | 14 ++ .../sonarqube/qa/bluegreen/package-info.java | 23 +++ .../org/sonarqube/tests/Category5Suite.java | 2 + .../tests/serverSystem/BlueGreenTest.java | 134 ++++++++++++++++++ .../src/test/java/util/XooProjectBuilder.java | 4 + 36 files changed, 1074 insertions(+), 55 deletions(-) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualityprofile/AlwaysActiveRulesHolderImpl.java create mode 100644 tests/plugins/blue-green-plugin-v1/build.gradle create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV1.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/package-info.java create mode 100644 tests/plugins/blue-green-plugin-v1/src/main/resources/static/global_page.js create mode 100644 tests/plugins/blue-green-plugin-v2/build.gradle create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV2.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/package-info.java create mode 100644 tests/plugins/blue-green-plugin-v2/src/main/resources/static/global_page.js create mode 100644 tests/plugins/blue-green-plugin/build.gradle create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java create mode 100644 tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/package-info.java create mode 100644 tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculator.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculator.java index a43250189d3..43fab81a51e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculator.java @@ -90,8 +90,8 @@ public class IssueCreationDateCalculator extends IssueVisitor { if (rule.isExternal()) { getScmChangeDate(component, issue).ifPresent(changeDate -> updateDate(issue, changeDate)); } else { - ActiveRule activeRule = toJavaUtilOptional(activeRulesHolder.get(issue.getRuleKey())) - .orElseThrow(illegalStateException("The rule %s raised an issue, but is not one of the active rules.", issue.getRuleKey())); + // Rule can't be inactive (see contract of IssueVisitor) + ActiveRule activeRule = activeRulesHolder.get(issue.getRuleKey()).get(); if (firstAnalysis || activeRuleIsNew(activeRule, lastAnalysisOptional.get()) || ruleImplementationChanged(activeRule.getRuleKey(), activeRule.getPluginKey(), lastAnalysisOptional.get())) { getScmChangeDate(component, issue).ifPresent(changeDate -> updateDate(issue, changeDate)); @@ -182,10 +182,6 @@ public class IssueCreationDateCalculator extends IssueVisitor { issueUpdater.setCreationDate(issue, scmDate, changeContext); } - private static Optional toJavaUtilOptional(com.google.common.base.Optional scmInfo) { - return scmInfo.transform(Optional::of).or(Optional::empty); - } - private static Supplier illegalStateException(String str, Object... args) { return () -> new IllegalStateException(String.format(str, args)); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueVisitor.java index f403d50e50a..d974dc76eea 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueVisitor.java @@ -36,6 +36,9 @@ public abstract class IssueVisitor { * This method is called for each issue of a component when tracking is done and issue is initialized. * That means that the following fields are set: resolution, status, line, creation date, uuid * and all the fields merged from base issues. + *
+ * The related rule is active in the Quality profile. Issues on inactive rules + * are ignored. */ public void onIssue(Component component, DefaultIssue issue) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java index 878651b2c00..84a1cab92de 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java @@ -42,6 +42,7 @@ import org.sonar.server.computation.task.projectanalysis.component.Component; import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder; import org.sonar.server.computation.task.projectanalysis.issue.commonrule.CommonRuleEngine; import org.sonar.server.computation.task.projectanalysis.issue.filter.IssueFilter; +import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRulesHolder; import org.sonar.server.computation.task.projectanalysis.source.SourceLinesHashRepository; import org.sonar.server.rule.CommonRuleKeys; @@ -55,15 +56,18 @@ public class TrackerRawInputFactory { private final IssueFilter issueFilter; private final SourceLinesHashRepository sourceLinesHash; private final RuleRepository ruleRepository; + private final ActiveRulesHolder activeRulesHolder; public TrackerRawInputFactory(TreeRootHolder treeRootHolder, BatchReportReader reportReader, - SourceLinesHashRepository sourceLinesHash, CommonRuleEngine commonRuleEngine, IssueFilter issueFilter, RuleRepository ruleRepository) { + SourceLinesHashRepository sourceLinesHash, CommonRuleEngine commonRuleEngine, IssueFilter issueFilter, RuleRepository ruleRepository, + ActiveRulesHolder activeRulesHolder) { this.treeRootHolder = treeRootHolder; this.reportReader = reportReader; this.sourceLinesHash = sourceLinesHash; this.commonRuleEngine = commonRuleEngine; this.issueFilter = issueFilter; this.ruleRepository = ruleRepository; + this.activeRulesHolder = activeRulesHolder; } public Input create(Component component) { @@ -100,6 +104,9 @@ public class TrackerRawInputFactory { // as late as possible while (reportIssues.hasNext()) { ScannerReport.Issue reportIssue = reportIssues.next(); + if (isOnInactiveRule(reportIssue)) { + continue; + } if (!isIssueOnUnsupportedCommonRule(reportIssue)) { Loggers.get(getClass()).debug("Ignored issue from analysis report on rule {}:{}", reportIssue.getRuleRepository(), reportIssue.getRuleKey()); continue; @@ -123,6 +130,11 @@ public class TrackerRawInputFactory { return result; } + private boolean isOnInactiveRule(ScannerReport.Issue reportIssue) { + RuleKey ruleKey = RuleKey.of(reportIssue.getRuleRepository(), reportIssue.getRuleKey()); + return !activeRulesHolder.get(ruleKey).isPresent(); + } + private boolean isIssueOnUnsupportedCommonRule(ScannerReport.Issue issue) { // issues on batch common rules are ignored. This feature // is natively supported by compute engine since 5.2. diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java index 085820dae94..a19a9a940f2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java @@ -53,8 +53,10 @@ import org.sonar.server.computation.task.projectanalysis.component.TypeAwareVisi import org.sonar.server.computation.task.projectanalysis.filemove.MovedFilesRepository; import org.sonar.server.computation.task.projectanalysis.issue.commonrule.CommonRuleEngineImpl; import org.sonar.server.computation.task.projectanalysis.issue.filter.IssueFilter; +import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRulesHolder; import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRulesHolderRule; import org.sonar.server.computation.task.projectanalysis.source.SourceLinesHashRepository; +import org.sonar.server.computation.task.projectanalysis.qualityprofile.AlwaysActiveRulesHolderImpl; import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepositoryRule; import static com.google.common.collect.Lists.newArrayList; @@ -69,21 +71,21 @@ import static org.sonar.server.computation.task.projectanalysis.component.Report public class IntegrateIssuesVisitorTest { - static final String FILE_UUID = "FILE_UUID"; - static final String FILE_UUID_ON_BRANCH = "FILE_UUID_BRANCH"; - static final String FILE_KEY = "FILE_KEY"; - static final int FILE_REF = 2; + private static final String FILE_UUID = "FILE_UUID"; + private static final String FILE_UUID_ON_BRANCH = "FILE_UUID_BRANCH"; + private static final String FILE_KEY = "FILE_KEY"; + private static final int FILE_REF = 2; - static final Component FILE = builder(Component.Type.FILE, FILE_REF) + private static final Component FILE = builder(Component.Type.FILE, FILE_REF) .setKey(FILE_KEY) .setUuid(FILE_UUID) .build(); - static final String PROJECT_KEY = "PROJECT_KEY"; - static final String PROJECT_UUID = "PROJECT_UUID"; - static final String PROJECT_UUID_ON_BRANCH = "PROJECT_UUID_BRANCH"; - static final int PROJECT_REF = 1; - static final Component PROJECT = builder(Component.Type.PROJECT, PROJECT_REF) + private static final String PROJECT_KEY = "PROJECT_KEY"; + private static final String PROJECT_UUID = "PROJECT_UUID"; + private static final String PROJECT_UUID_ON_BRANCH = "PROJECT_UUID_BRANCH"; + private static final int PROJECT_REF = 1; + private static final Component PROJECT = builder(Component.Type.PROJECT, PROJECT_REF) .setKey(PROJECT_KEY) .setUuid(PROJECT_UUID) .addChildren(FILE) @@ -116,16 +118,17 @@ public class IntegrateIssuesVisitorTest { private MergeBranchComponentUuids mergeBranchComponentUuids = mock(MergeBranchComponentUuids.class); private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class); - ArgumentCaptor defaultIssueCaptor; + private ArgumentCaptor defaultIssueCaptor; - ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule); - IssueTrackingDelegator trackingDelegator; - TrackerExecution tracker; - ShortBranchTrackerExecution shortBranchTracker; - MergeBranchTrackerExecution mergeBranchTracker; - IssueCache issueCache; + private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule); + private IssueTrackingDelegator trackingDelegator; + private TrackerExecution tracker; + private ShortBranchTrackerExecution shortBranchTracker; + private MergeBranchTrackerExecution mergeBranchTracker; + private ActiveRulesHolder activeRulesHolder = new AlwaysActiveRulesHolderImpl(); + private IssueCache issueCache; - TypeAwareVisitor underTest; + private TypeAwareVisitor underTest; @Before public void setUp() throws Exception { @@ -134,7 +137,7 @@ public class IntegrateIssuesVisitorTest { defaultIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class); when(movedFilesRepository.getOriginalFile(any(Component.class))).thenReturn(Optional.absent()); - TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(), issueFilter, ruleRepository); + TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(), issueFilter, ruleRepository, activeRulesHolder); TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbTester.getDbClient(), movedFilesRepository); TrackerMergeBranchInputFactory mergeInputFactory = new TrackerMergeBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbTester.getDbClient()); tracker = new TrackerExecution(baseInputFactory, rawInputFactory, new Tracker<>()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactoryTest.java index e04d2981788..3da31e3a7c2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactoryTest.java @@ -39,10 +39,14 @@ import org.sonar.server.computation.task.projectanalysis.component.ReportCompone import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.server.computation.task.projectanalysis.issue.commonrule.CommonRuleEngine; import org.sonar.server.computation.task.projectanalysis.issue.filter.IssueFilter; +import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRule; +import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRulesHolderRule; import org.sonar.server.computation.task.projectanalysis.source.SourceLinesHashRepository; import org.sonar.server.rule.CommonRuleKeys; import static java.util.Arrays.asList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -58,17 +62,18 @@ public class TrackerRawInputFactoryTest { @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT); - @Rule public BatchReportReaderRule reportReader = new BatchReportReaderRule(); - + @Rule + public ActiveRulesHolderRule activeRulesHolder = new ActiveRulesHolderRule(); @Rule public RuleRepositoryRule ruleRepository = new RuleRepositoryRule(); - SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class); - CommonRuleEngine commonRuleEngine = mock(CommonRuleEngine.class); - IssueFilter issueFilter = mock(IssueFilter.class); - TrackerRawInputFactory underTest = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, commonRuleEngine, issueFilter, ruleRepository); + private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class); + private CommonRuleEngine commonRuleEngine = mock(CommonRuleEngine.class); + private IssueFilter issueFilter = mock(IssueFilter.class); + private TrackerRawInputFactory underTest = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, + commonRuleEngine, issueFilter, ruleRepository, activeRulesHolder); @Test public void load_source_hash_sequences() { @@ -93,17 +98,20 @@ public class TrackerRawInputFactoryTest { @Test public void load_issues_from_report() { - when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true); + RuleKey ruleKey = RuleKey.of("java", "S001"); + markRuleAsActive(ruleKey); + when(issueFilter.accept(any(), eq(FILE))).thenReturn(true); + when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder() .setTextRange(TextRange.newBuilder().setStartLine(2).build()) .setMsg("the message") - .setRuleRepository("java") - .setRuleKey("S001") + .setRuleRepository(ruleKey.repository()) + .setRuleKey(ruleKey.rule()) .setSeverity(Constants.Severity.BLOCKER) .setGap(3.14) .build(); - reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); + reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue)); Input input = underTest.create(FILE); Collection issues = input.getIssues(); @@ -111,7 +119,7 @@ public class TrackerRawInputFactoryTest { DefaultIssue issue = Iterators.getOnlyElement(issues.iterator()); // fields set by analysis report - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("java", "S001")); + assertThat(issue.ruleKey()).isEqualTo(ruleKey); assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.line()).isEqualTo(2); assertThat(issue.effortToFix()).isEqualTo(3.14); @@ -153,7 +161,7 @@ public class TrackerRawInputFactoryTest { // fields set by compute engine assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); assertThat(issue.tags()).isEmpty(); - assertInitializedIssue(issue); + assertInitializedExternalIssue(issue); } @Test @@ -183,22 +191,24 @@ public class TrackerRawInputFactoryTest { // fields set by compute engine assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); assertThat(issue.tags()).isEmpty(); - assertInitializedIssue(issue); + assertInitializedExternalIssue(issue); } @Test - public void ignore_issue_from_report() { - when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(false); + public void excludes_issues_on_inactive_rules() { + RuleKey ruleKey = RuleKey.of("java", "S001"); + when(issueFilter.accept(any(), eq(FILE))).thenReturn(true); + when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder() .setTextRange(TextRange.newBuilder().setStartLine(2).build()) .setMsg("the message") - .setRuleRepository("java") - .setRuleKey("S001") + .setRuleRepository(ruleKey.repository()) + .setRuleKey(ruleKey.rule()) .setSeverity(Constants.Severity.BLOCKER) .setGap(3.14) .build(); - reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); + reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue)); Input input = underTest.create(FILE); Collection issues = input.getIssues(); @@ -206,15 +216,38 @@ public class TrackerRawInputFactoryTest { } @Test - public void ignore_report_issues_on_common_rules() { + public void filter_excludes_issues_from_report() { + RuleKey ruleKey = RuleKey.of("java", "S001"); + markRuleAsActive(ruleKey); + when(issueFilter.accept(any(), eq(FILE))).thenReturn(false); when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder() + .setTextRange(TextRange.newBuilder().setStartLine(2).build()) .setMsg("the message") - .setRuleRepository(CommonRuleKeys.commonRepositoryForLang("java")) - .setRuleKey("S001") + .setRuleRepository(ruleKey.repository()) + .setRuleKey(ruleKey.rule()) + .setSeverity(Constants.Severity.BLOCKER) + .setGap(3.14) + .build(); + reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue)); + Input input = underTest.create(FILE); + + Collection issues = input.getIssues(); + assertThat(issues).isEmpty(); + } + + @Test + public void exclude_issues_on_common_rules() { + RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "S001"); + markRuleAsActive(ruleKey); + when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); + ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder() + .setMsg("the message") + .setRuleRepository(ruleKey.repository()) + .setRuleKey(ruleKey.rule()) .setSeverity(Constants.Severity.BLOCKER) .build(); - reportReader.putIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); + reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue)); Input input = underTest.create(FILE); @@ -223,13 +256,15 @@ public class TrackerRawInputFactoryTest { @Test public void load_issues_of_compute_engine_common_rules() { - when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true); + RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage"); + markRuleAsActive(ruleKey); + when(issueFilter.accept(any(), eq(FILE))).thenReturn(true); when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); DefaultIssue ceIssue = new DefaultIssue() - .setRuleKey(RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage")) + .setRuleKey(ruleKey) .setMessage("not enough coverage") .setGap(10.0); - when(commonRuleEngine.process(FILE)).thenReturn(asList(ceIssue)); + when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue)); Input input = underTest.create(FILE); @@ -238,14 +273,16 @@ public class TrackerRawInputFactoryTest { } @Test - public void ignore_issue_from_common_rule() { - when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(false); + public void filter_exclude_issues_on_common_rule() { + RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage"); + markRuleAsActive(ruleKey); + when(issueFilter.accept(any(), eq(FILE))).thenReturn(false); when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); DefaultIssue ceIssue = new DefaultIssue() - .setRuleKey(RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage")) + .setRuleKey(ruleKey) .setMessage("not enough coverage") .setGap(10.0); - when(commonRuleEngine.process(FILE)).thenReturn(asList(ceIssue)); + when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue)); Input input = underTest.create(FILE); @@ -260,5 +297,22 @@ public class TrackerRawInputFactoryTest { assertThat(issue.status()).isEqualTo(Issue.STATUS_OPEN); assertThat(issue.key()).isNull(); assertThat(issue.authorLogin()).isNull(); + assertThat(issue.effort()).isNull(); + assertThat(issue.effortInMinutes()).isNull(); + assertThat(issue.debt()).isNull(); + } + + private void assertInitializedExternalIssue(DefaultIssue issue) { + assertThat(issue.projectKey()).isEqualTo(PROJECT.getPublicKey()); + assertThat(issue.componentKey()).isEqualTo(FILE.getPublicKey()); + assertThat(issue.componentUuid()).isEqualTo(FILE.getUuid()); + assertThat(issue.resolution()).isNull(); + assertThat(issue.status()).isEqualTo(Issue.STATUS_OPEN); + assertThat(issue.key()).isNull(); + assertThat(issue.authorLogin()).isNull(); + } + + private void markRuleAsActive(RuleKey ruleKey) { + activeRulesHolder.put(new ActiveRule(ruleKey, Severity.CRITICAL, emptyMap(), 1_000L, null)); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualityprofile/AlwaysActiveRulesHolderImpl.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualityprofile/AlwaysActiveRulesHolderImpl.java new file mode 100644 index 00000000000..088138a8c53 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualityprofile/AlwaysActiveRulesHolderImpl.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.sonar.server.computation.task.projectanalysis.qualityprofile; + +import com.google.common.base.Optional; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.Severity; + +import static java.util.Collections.emptyMap; + +public class AlwaysActiveRulesHolderImpl implements ActiveRulesHolder { + @Override + public Optional get(RuleKey ruleKey) { + return Optional.of(new ActiveRule(ruleKey, Severity.MAJOR, emptyMap(), 1_000L, null)); + } + +} diff --git a/settings.gradle b/settings.gradle index a3f0c94d685..bc05b4e8080 100644 --- a/settings.gradle +++ b/settings.gradle @@ -36,6 +36,8 @@ include 'tests:plugins:backdating-plugin-v1' include 'tests:plugins:backdating-plugin-v2' include 'tests:plugins:base-auth-plugin' include 'tests:plugins:batch-plugin' +include 'tests:plugins:blue-green-plugin-v1' +include 'tests:plugins:blue-green-plugin-v2' include 'tests:plugins:extension-lifecycle-plugin' include 'tests:plugins:fake-billing-plugin' include 'tests:plugins:fake-governance-plugin' diff --git a/tests/build.gradle b/tests/build.gradle index 8164dfebb19..1d9605e8593 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -16,6 +16,8 @@ def pluginsForITs = [ ':tests:plugins:backdating-customplugin', ':tests:plugins:base-auth-plugin', ':tests:plugins:batch-plugin', + ':tests:plugins:blue-green-plugin-v1', + ':tests:plugins:blue-green-plugin-v2', ':tests:plugins:extension-lifecycle-plugin', ':tests:plugins:fake-billing-plugin', ':tests:plugins:fake-governance-plugin', diff --git a/tests/plugins/blue-green-plugin-v1/build.gradle b/tests/plugins/blue-green-plugin-v1/build.gradle new file mode 100644 index 00000000000..e2fef432b88 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/build.gradle @@ -0,0 +1,26 @@ +sonarqube { + skipProject = true +} + +dependencies { + compileOnly 'com.google.code.findbugs:jsr305' + compileOnly project(path: ':sonar-plugin-api', configuration: 'shadow') +} + +jar { + manifest { + attributes( + 'Plugin-Key': 'bluegreen', + 'Plugin-Version': '1.0', + 'Plugin-Class': 'org.sonarqube.qa.bluegreen.BlueGreenPlugin', + 'Plugin-ChildFirstClassLoader': 'false', + 'Sonar-Version': version, + 'SonarLint-Supported': 'false', + 'Plugin-Name': 'BlueGreen', + 'Plugin-License': 'GNU LGPL 3' + ) + } + into('META-INF/lib') { + from configurations.compile + } +} 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 new file mode 100644 index 00000000000..ea0eea80322 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.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 org.sonar.api.Plugin; + +public class BlueGreenPlugin implements Plugin { + + @Override + public void define(Context context) { + context.addExtensions( + BuiltInProfilesV1.class, + PageDefinitionV1.class, + RulesDefinitionV1.class, + RuleSensorV1.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 new file mode 100644 index 00000000000..1d19f4e5ad9 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java @@ -0,0 +1,33 @@ +/* + * 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 org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; + +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.done(); + } +} + diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV1.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV1.java new file mode 100644 index 00000000000..d7cb207aa41 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV1.java @@ -0,0 +1,32 @@ +/* + * 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 org.sonar.api.web.page.Context; +import org.sonar.api.web.page.Page; +import org.sonar.api.web.page.PageDefinition; + +public class PageDefinitionV1 implements PageDefinition { + @Override + public void define(Context context) { + context + .addPage(Page.builder("bluegreen/global_page").setName("Blue Green Page").build()); + } +} 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/RuleSensorV1.java new file mode 100644 index 00000000000..1d377825a3f --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.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.sonarqube.qa.bluegreen; + +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 static org.sonarqube.qa.bluegreen.RulesDefinitionV1.REPOSITORY_KEY; + +public class RuleSensorV1 implements Sensor { + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(REPOSITORY_KEY) + .onlyOnLanguage("xoo") + .name("BlueGreen V1"); + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage("xoo"))) { + saveIssue(context, inputFile, "a"); + saveIssue(context, inputFile, "b"); + } + } + + private void saveIssue(SensorContext context, InputFile inputFile, String ruleKey) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile).at(inputFile.selectLine(1))) + .forRule(RuleKey.of(REPOSITORY_KEY, ruleKey)) + .save(); + } + +} 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 new file mode 100644 index 00000000000..e6fbc56bbe4 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.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 org.sonar.api.server.rule.RulesDefinition; + +public class RulesDefinitionV1 implements RulesDefinition { + + public static final String REPOSITORY_KEY = "bluegreen"; + + @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.done(); + } +} diff --git a/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/package-info.java b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/package-info.java new file mode 100644 index 00000000000..86d3578aa72 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/java/org/sonarqube/qa/bluegreen/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonarqube.qa.bluegreen; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tests/plugins/blue-green-plugin-v1/src/main/resources/static/global_page.js b/tests/plugins/blue-green-plugin-v1/src/main/resources/static/global_page.js new file mode 100644 index 00000000000..257440f340b --- /dev/null +++ b/tests/plugins/blue-green-plugin-v1/src/main/resources/static/global_page.js @@ -0,0 +1,23 @@ +/* + * 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. + */ +window.registerExtension('bluegreen/global_page', function (options) { + options.el.textContent = 'BLUE'; + return function () {}; +}); diff --git a/tests/plugins/blue-green-plugin-v2/build.gradle b/tests/plugins/blue-green-plugin-v2/build.gradle new file mode 100644 index 00000000000..0730c13d390 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/build.gradle @@ -0,0 +1,26 @@ +sonarqube { + skipProject = true +} + +dependencies { + compileOnly 'com.google.code.findbugs:jsr305' + compileOnly project(path: ':sonar-plugin-api', configuration: 'shadow') +} + +jar { + manifest { + attributes( + 'Plugin-Key': 'bluegreen', + 'Plugin-Version': '2.0', + 'Plugin-Class': 'org.sonarqube.qa.bluegreen.BlueGreenPlugin', + 'Plugin-ChildFirstClassLoader': 'false', + 'Sonar-Version': version, + 'SonarLint-Supported': 'false', + 'Plugin-Name': 'BlueGreen', + 'Plugin-License': 'GNU LGPL 3' + ) + } + into('META-INF/lib') { + from configurations.compile + } +} 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 new file mode 100644 index 00000000000..156bf7a612f --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.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 org.sonar.api.Plugin; + +public class BlueGreenPlugin implements Plugin { + + @Override + public void define(Context context) { + context.addExtensions( + BuiltInProfilesV2.class, + PageDefinitionV2.class, + RulesDefinitionV2.class, + RuleSensorV2.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 new file mode 100644 index 00000000000..ccb8e096010 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java @@ -0,0 +1,33 @@ +/* + * 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 org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; + +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"); + 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/PageDefinitionV2.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV2.java new file mode 100644 index 00000000000..d9d64100abb --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/PageDefinitionV2.java @@ -0,0 +1,32 @@ +/* + * 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 org.sonar.api.web.page.Context; +import org.sonar.api.web.page.Page; +import org.sonar.api.web.page.PageDefinition; + +public class PageDefinitionV2 implements PageDefinition { + @Override + public void define(Context context) { + context + .addPage(Page.builder("bluegreen/global_page").setName("Blue Green Page").build()); + } +} 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/RuleSensorV2.java new file mode 100644 index 00000000000..5dde5ddd1b2 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.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.sonarqube.qa.bluegreen; + +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 static org.sonarqube.qa.bluegreen.RulesDefinitionV2.REPOSITORY_KEY; + +public class RuleSensorV2 implements Sensor { + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(REPOSITORY_KEY) + .onlyOnLanguage("xoo") + .name("BlueGreen V2"); + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage("xoo"))) { + saveIssue(context, inputFile, "b"); + saveIssue(context, inputFile, "c"); + } + } + + private void saveIssue(SensorContext context, InputFile inputFile, String ruleKey) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile).at(inputFile.selectLine(1))) + .forRule(RuleKey.of(REPOSITORY_KEY, ruleKey)) + .save(); + } + +} 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 new file mode 100644 index 00000000000..3e04908a570 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.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 org.sonar.api.server.rule.RulesDefinition; + +public class RulesDefinitionV2 implements RulesDefinition { + + public static final String REPOSITORY_KEY = "bluegreen"; + + @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"); + repo.done(); + } +} diff --git a/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/package-info.java b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/package-info.java new file mode 100644 index 00000000000..86d3578aa72 --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/java/org/sonarqube/qa/bluegreen/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonarqube.qa.bluegreen; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tests/plugins/blue-green-plugin-v2/src/main/resources/static/global_page.js b/tests/plugins/blue-green-plugin-v2/src/main/resources/static/global_page.js new file mode 100644 index 00000000000..2bf90efe4ed --- /dev/null +++ b/tests/plugins/blue-green-plugin-v2/src/main/resources/static/global_page.js @@ -0,0 +1,23 @@ +/* + * 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. + */ +window.registerExtension('bluegreen/global_page', function (options) { + options.el.textContent = 'GREEN'; + return function () {}; +}); diff --git a/tests/plugins/blue-green-plugin/build.gradle b/tests/plugins/blue-green-plugin/build.gradle new file mode 100644 index 00000000000..833f88f3230 --- /dev/null +++ b/tests/plugins/blue-green-plugin/build.gradle @@ -0,0 +1,29 @@ +sonarqube { + skipProject = true +} + +dependencies { + compile 'com.google.guava:guava' + compile 'commons-io:commons-io' + compile 'commons-lang:commons-lang' + compileOnly 'com.google.code.findbugs:jsr305' + compileOnly project(path: ':sonar-plugin-api', configuration: 'shadow') +} + +jar { + manifest { + attributes( + 'Plugin-Key': 'bluegreen', + 'Plugin-Version': version, + 'Plugin-Class': 'org.sonarqube.qa.bluegreen', + 'Plugin-ChildFirstClassLoader': 'false', + 'Sonar-Version': version, + 'SonarLint-Supported': 'false', + 'Plugin-Name': 'Foo', + 'Plugin-License': 'GNU LGPL 3' + ) + } + into('META-INF/lib') { + from configurations.compile + } +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java new file mode 100644 index 00000000000..f4ec4e56925 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BlueGreenPlugin.java @@ -0,0 +1,41 @@ +/* + * 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.Optional; +import org.sonar.api.Plugin; + +public class BlueGreenPlugin implements Plugin { + + @Override + public void define(Context context) { + Optional version = context.getBootConfiguration().get("bluegreenplugin.version"); + if (version.isPresent()) { + if (version.get().equals("1")) { + context.addExtension(RulesDefinitionV1.class); + + } else if (version.get().equals("2")) { + context.addExtension(RulesDefinitionV2.class); + + } + } + } + +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java new file mode 100644 index 00000000000..79e14e0f947 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV1.java @@ -0,0 +1,4 @@ +package org.sonarqube.qa.bluegreen; + +public class BuiltInProfileV1 { +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java new file mode 100644 index 00000000000..131f1711d47 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/BuiltInProfilesV2.java @@ -0,0 +1,15 @@ +package org.sonarqube.qa.bluegreen; + +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; + +public class BuiltInProfilesV2 implements BuiltInQualityProfilesDefinition { + @Override + public void define(Context context) { + NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("Profile One", "xoo"); + profile.setDefault(true); + profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "a").overrideSeverity("BLOCKER"); + profile.activateRule(RulesDefinitionV1.REPOSITORY_KEY, "b").overrideSeverity("CRITICAL"); + profile.done(); + } +} + diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java new file mode 100644 index 00000000000..9ecea9bf5c2 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV1.java @@ -0,0 +1,64 @@ +/* + * 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.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +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.plugins.backdating.rule.BackRulesDefinition; + +public class RuleSensorV1 implements Sensor { + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(BackRulesDefinition.BACK_REPOSITORY) + .onlyOnLanguage("xoo") + .name("Back V1"); + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage("xoo"))) { + int lineNb = 0; + try { + BufferedReader reader = new BufferedReader(new StringReader(inputFile.contents())); + String line; + while ((line = reader.readLine()) != null) { + lineNb++; + if (line.contains("BACKV1")) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile).at(inputFile.selectLine(lineNb))) + .forRule(RuleKey.of(BackRulesDefinition.BACK_REPOSITORY, BackRulesDefinition.RULE_KEY)) + .save(); + } + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.java new file mode 100644 index 00000000000..d3c18d64cb2 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RuleSensorV2.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.sonarqube.qa.bluegreen; + +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 static org.sonarqube.qa.bluegreen.RulesDefinitionV1.REPOSITORY_KEY; + +public class RuleSensorV2 implements Sensor { + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.createIssuesForRuleRepositories(REPOSITORY_KEY) + .onlyOnLanguage("xoo") + .name("BlueGreen V1"); + } + + @Override + public void execute(SensorContext context) { + for (InputFile inputFile : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguage("xoo"))) { + saveIssue(context, inputFile, "a"); + saveIssue(context, inputFile, "b"); + } + } + + private void saveIssue(SensorContext context, InputFile inputFile, String ruleKey) { + NewIssue newIssue = context.newIssue(); + newIssue.at(newIssue.newLocation().on(inputFile).at(inputFile.selectLine(1))) + .forRule(RuleKey.of(REPOSITORY_KEY, ruleKey)) + .save(); + } + +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java new file mode 100644 index 00000000000..af58aeb2f0d --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV1.java @@ -0,0 +1,4 @@ +package org.sonarqube.qa.bluegreen; + +public class RulesDefinitionV1 { +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java new file mode 100644 index 00000000000..8b39095b356 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/RulesDefinitionV2.java @@ -0,0 +1,14 @@ +package org.sonarqube.qa.bluegreen; + +import org.sonar.api.server.rule.RulesDefinition; + +public class RulesDefinitionV2 implements RulesDefinition { + + @Override + public void define(Context context) { + NewRepository repo = context.createRepository("bluegreen", "xoo").setName("BlueGreen"); + repo.createRule("a").setName("Rule A").setHtmlDescription("Rule A"); + repo.createRule("b").setName("Rule B").setHtmlDescription("Rule B"); + repo.done(); + } +} diff --git a/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/package-info.java b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/package-info.java new file mode 100644 index 00000000000..86d3578aa72 --- /dev/null +++ b/tests/plugins/blue-green-plugin/src/main/java/org/sonarqube/qa/bluegreen/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonarqube.qa.bluegreen; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java index 0f1cc1381ab..d45b79800cc 100644 --- a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java +++ b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java @@ -29,6 +29,7 @@ import org.sonarqube.tests.marketplace.UpdateCenterTest; import org.sonarqube.tests.qualityProfile.ActiveRuleEsResilienceTest; import org.sonarqube.tests.qualityProfile.BuiltInQualityProfilesNotificationTest; import org.sonarqube.tests.rule.RuleEsResilienceTest; +import org.sonarqube.tests.serverSystem.BlueGreenTest; import org.sonarqube.tests.serverSystem.RestartTest; import org.sonarqube.tests.serverSystem.ServerSystemRestartingOrchestrator; import org.sonarqube.tests.serverSystem.SystemStateTest; @@ -52,6 +53,7 @@ import org.sonarqube.tests.user.UserEsResilienceTest; @Deprecated @RunWith(Suite.class) @Suite.SuiteClasses({ + BlueGreenTest.class, ServerSystemRestartingOrchestrator.class, RestartTest.class, SettingsTestRestartingOrchestrator.class, diff --git a/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java b/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java new file mode 100644 index 00000000000..106a47a1e82 --- /dev/null +++ b/tests/src/test/java/org/sonarqube/tests/serverSystem/BlueGreenTest.java @@ -0,0 +1,134 @@ +/* + * 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.tests.serverSystem; + +import com.google.common.util.concurrent.Uninterruptibles; +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; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TemporaryFolder; +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.qualityprofiles.AddProjectRequest; +import util.XooProjectBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.newOrchestratorBuilder; +import static util.ItUtils.pluginArtifact; +import static util.ItUtils.xooPlugin; + +public class BlueGreenTest { + + @Rule + public TestRule safeguard = new DisableOnDebug(Timeout.seconds(600)); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private Orchestrator orchestrator; + private Tester tester; + + @After + public void tearDown() { + if (tester != null) { + tester.after(); + } + if (orchestrator != null) { + orchestrator.stop(); + } + } + + @Test + public void test_change_of_version_at_runtime() throws Exception { + orchestrator = newOrchestratorBuilder() + .addPlugin(pluginArtifact("blue-green-plugin-v1")) + .addPlugin(xooPlugin()) + .build(); + tester = new Tester(orchestrator).disableOrganizations(); + 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); + + // open browser + Navigation browser = tester.openBrowser(); + + + // upgrade plugin + 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); + + resumeAndWaitForCeQueueEmpty(); + + // 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); + } + + private void associateProjectToProfile(Projects.CreateWsResponse.Project project, String xooProfileName) { + tester.wsClient().qualityprofiles().addProject(new AddProjectRequest() + .setProject(project.getKey()) + .setLanguage("xoo") + .setQualityProfile(xooProfileName)); + } + + private void resumeAndWaitForCeQueueEmpty() { + tester.wsClient().ce().resume(); + while (true) { + Ce.ActivityStatusWsResponse activity = loadCeActivity(); + if (activity.getPending() + activity.getInProgress() == 0) { + return; + } + Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); + } + } + + private Ce.ActivityStatusWsResponse loadCeActivity() { + return tester.wsClient().ce().activityStatus(new ActivityStatusRequest()); + } +} diff --git a/tests/src/test/java/util/XooProjectBuilder.java b/tests/src/test/java/util/XooProjectBuilder.java index 0eaf934572b..c9e8c8265b8 100644 --- a/tests/src/test/java/util/XooProjectBuilder.java +++ b/tests/src/test/java/util/XooProjectBuilder.java @@ -67,6 +67,10 @@ public class XooProjectBuilder { for (int i = 0; i < filesPerModule; i++) { File sourceFile = new File(sourceDir, "File" + i + ".xoo"); FileUtils.write(sourceFile, "content of " + sourceFile.getName()); + + File measuresFile = new File(sourceFile + ".measures"); + FileUtils.write(measuresFile, "ncloc:10\n" + + "comment_lines:3\n"); } Properties props = new Properties(); props.setProperty("sonar.projectKey", key); -- 2.39.5