From b92c2b10a48954be8b8af7e02c01f6f39001074f Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Tue, 10 Apr 2018 16:08:50 +0200 Subject: [PATCH] SONAR-10544 Fix handling of external rules in CE --- .../main/java/org/sonar/db/rule/RuleDto.java | 14 ++-- ...ProjectAnalysisTaskContainerPopulator.java | 2 + .../issue/ComponentIssuesLoader.java | 3 +- .../issue/IssueCreationDateCalculator.java | 30 ++++++--- .../task/projectanalysis/issue/RuleImpl.java | 3 +- .../issue/RuleRepositoryImpl.java | 20 +++--- .../step/PersistExternalRulesStep.java | 2 +- .../server/rule/ExternalRuleCreator.java | 61 +++++++++++++++++ .../org/sonar/server/rule/RuleCreator.java | 18 ----- .../IssueCreationDateCalculatorTest.java | 30 +++------ .../issue/RuleRepositoryImplTest.java | 25 ++----- .../step/PersistExternalRulesStepTest.java | 12 +--- .../step/PersistIssuesStepTest.java | 10 +-- .../server/rule/ExternalRuleCreatorTest.java | 67 +++++++++++++++++++ 14 files changed, 196 insertions(+), 101 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index 86afcb2bed1..38075e93fc5 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -33,9 +33,9 @@ public class RuleDto { public enum Format { HTML, MARKDOWN } - + public enum Scope { - MAIN, TEST, ALL; + MAIN, TEST, ALL } private final RuleDefinitionDto definition; @@ -142,16 +142,16 @@ public class RuleDto { public String getConfigKey() { return definition.getConfigKey(); } - + public RuleDto setConfigKey(@Nullable String configKey) { definition.setConfigKey(configKey); return this; } - + public Scope getScope() { return definition.getScope(); } - + public RuleDto setScope(Scope scope) { definition.setScope(scope); return this; @@ -177,6 +177,10 @@ public class RuleDto { return this; } + public boolean isExternal() { + return definition.isExternal(); + } + public boolean isTemplate() { return definition.isTemplate(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java index f40d4dece13..b7692f5cb56 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java @@ -122,6 +122,7 @@ import org.sonar.server.computation.task.projectanalysis.webhook.WebhookPostTask import org.sonar.server.computation.task.step.ComputationStepExecutor; import org.sonar.server.computation.task.step.ComputationSteps; import org.sonar.server.computation.taskprocessor.MutableTaskResultHolderImpl; +import org.sonar.server.rule.ExternalRuleCreator; import org.sonar.server.view.index.ViewIndex; public final class ProjectAnalysisTaskContainerPopulator implements ContainerPopulator { @@ -196,6 +197,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop DuplicationRepositoryImpl.class, // issues + ExternalRuleCreator.class, RuleRepositoryImpl.class, ScmAccountToUserLoader.class, ScmAccountToUser.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ComponentIssuesLoader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ComponentIssuesLoader.java index fad32145784..3dd91d851a0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ComponentIssuesLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ComponentIssuesLoader.java @@ -72,9 +72,10 @@ public class ComponentIssuesLoader { List result = new ArrayList<>(); dbSession.getMapper(IssueMapper.class).scrollNonClosedByComponentUuid(componentUuid, resultContext -> { DefaultIssue issue = (resultContext.getResultObject()).toDefaultIssue(); + Rule rule = ruleRepository.getByKey(issue.ruleKey()); // TODO this field should be set outside this class - if (!isActive(issue.ruleKey()) || ruleRepository.getByKey(issue.ruleKey()).getStatus() == RuleStatus.REMOVED) { + if ((!rule.isExternal() && !isActive(issue.ruleKey())) || rule.getStatus() == RuleStatus.REMOVED) { issue.setOnDisabledRule(true); // TODO to be improved, why setOnDisabledRule(true) is not enough ? issue.setBeingClosed(true); 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 473fe7054f9..70a8a66633a 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 @@ -28,6 +28,8 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.stream.IntStream; +import javax.annotation.Nullable; +import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -63,12 +65,14 @@ public class IssueCreationDateCalculator extends IssueVisitor { private final AnalysisMetadataHolder analysisMetadataHolder; private final IssueChangeContext changeContext; private final ActiveRulesHolder activeRulesHolder; + private final RuleRepository ruleRepository; public IssueCreationDateCalculator(AnalysisMetadataHolder analysisMetadataHolder, ScmInfoRepository scmInfoRepository, - IssueFieldsSetter issueUpdater, ActiveRulesHolder activeRulesHolder) { + IssueFieldsSetter issueUpdater, ActiveRulesHolder activeRulesHolder, RuleRepository ruleRepository) { this.scmInfoRepository = scmInfoRepository; this.issueUpdater = issueUpdater; this.analysisMetadataHolder = analysisMetadataHolder; + this.ruleRepository = ruleRepository; this.changeContext = createScan(new Date(analysisMetadataHolder.getAnalysisDate())); this.activeRulesHolder = activeRulesHolder; } @@ -80,24 +84,28 @@ public class IssueCreationDateCalculator extends IssueVisitor { } Optional lastAnalysisOptional = lastAnalysis(); boolean firstAnalysis = !lastAnalysisOptional.isPresent(); - 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())); - if (firstAnalysis - || activeRuleIsNew(activeRule, lastAnalysisOptional.get()) - || ruleImplementationChanged(activeRule, lastAnalysisOptional.get())) { - getScmChangeDate(component, issue) - .ifPresent(changeDate -> updateDate(issue, changeDate)); + Rule rule = ruleRepository.findByKey(issue.getRuleKey()) + .orElseThrow(illegalStateException("The rule with key '%s' raised an issue, but no rule with that key was found", issue.getRuleKey())); + + 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())); + if (firstAnalysis || activeRuleIsNew(activeRule, lastAnalysisOptional.get()) + || ruleImplementationChanged(activeRule.getRuleKey(), activeRule.getPluginKey(), lastAnalysisOptional.get())) { + getScmChangeDate(component, issue).ifPresent(changeDate -> updateDate(issue, changeDate)); + } } } - private boolean ruleImplementationChanged(ActiveRule activeRule, long lastAnalysisDate) { - String pluginKey = activeRule.getPluginKey(); + private boolean ruleImplementationChanged(RuleKey ruleKey, @Nullable String pluginKey, long lastAnalysisDate) { if (pluginKey == null) { return false; } ScannerPlugin scannerPlugin = Optional.ofNullable(analysisMetadataHolder.getScannerPluginsByKey().get(pluginKey)) - .orElseThrow(illegalStateException("The rule %s is declared to come from plugin %s, but this plugin was not used by scanner.", activeRule.getRuleKey(), pluginKey)); + .orElseThrow(illegalStateException("The rule %s is declared to come from plugin %s, but this plugin was not used by scanner.", ruleKey, pluginKey)); return pluginIsNew(scannerPlugin, lastAnalysisDate) || basePluginIsNew(scannerPlugin, lastAnalysisDate); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleImpl.java index 4762cef0629..0119b4d640c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleImpl.java @@ -55,8 +55,7 @@ public class RuleImpl implements Rule { this.remediationFunction = effectiveRemediationFunction(dto); this.type = RuleType.valueOf(dto.getType()); this.pluginKey = dto.getPluginKey(); - // TODO - this.external = false; + this.external = dto.isExternal(); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java index 32fbac077f6..10eb88f7e09 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java @@ -20,6 +20,11 @@ package org.sonar.server.computation.task.projectanalysis.issue; import com.google.common.collect.Multimap; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; +import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; @@ -27,13 +32,7 @@ import org.sonar.db.DbSession; import org.sonar.db.rule.DeprecatedRuleKeyDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; -import org.sonar.server.rule.RuleCreator; - -import javax.annotation.CheckForNull; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; +import org.sonar.server.rule.ExternalRuleCreator; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; @@ -45,11 +44,11 @@ public class RuleRepositoryImpl implements RuleRepository { @CheckForNull private Map rulesById; - private final RuleCreator creator; + private final ExternalRuleCreator creator; private final DbClient dbClient; private final AnalysisMetadataHolder analysisMetadataHolder; - public RuleRepositoryImpl(RuleCreator creator, DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder) { + public RuleRepositoryImpl(ExternalRuleCreator creator, DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder) { this.creator = creator; this.dbClient = dbClient; this.analysisMetadataHolder = analysisMetadataHolder; @@ -63,7 +62,8 @@ public class RuleRepositoryImpl implements RuleRepository { } } - @Override public void persistNewExternalRules(DbSession dbSession) { + @Override + public void persistNewExternalRules(DbSession dbSession) { ensureInitialized(); rulesByKey.values().stream() diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStep.java index aac5e714eeb..e51c1c895de 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStep.java @@ -37,7 +37,7 @@ public class PersistExternalRulesStep implements ComputationStep { @Override public void execute() { - try (DbSession dbSession = dbClient.openSession(true)) { + try (DbSession dbSession = dbClient.openSession(false)) { ruleRepository.persistNewExternalRules(dbSession); dbSession.flushStatements(); dbSession.commit(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java new file mode 100644 index 00000000000..2cbef97cbd5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java @@ -0,0 +1,61 @@ +/* + * 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.rule; + +import org.sonar.api.server.ServerSide; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.rule.RuleDao; +import org.sonar.db.rule.RuleDefinitionDto; +import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; +import org.sonar.server.computation.task.projectanalysis.issue.Rule; +import org.sonar.server.computation.task.projectanalysis.issue.RuleImpl; + +import static org.sonar.db.rule.RuleDto.Scope.ALL; + +@ServerSide +public class ExternalRuleCreator { + + private final DbClient dbClient; + private final System2 system2; + + public ExternalRuleCreator(DbClient dbClient, System2 system2) { + this.dbClient = dbClient; + this.system2 = system2; + } + + public Rule create(DbSession dbSession, NewExternalRule external) { + RuleDao dao = dbClient.ruleDao(); + dao.insert(dbSession, new RuleDefinitionDto() + .setRuleKey(external.getKey()) + .setPluginKey(external.getPluginKey()) + .setIsExternal(true) + .setName(external.getName()) + .setDescriptionURL(external.getDescriptionUrl()) + .setType(external.getType()) + .setScope(ALL) + .setSeverity(external.getSeverity()) + .setCreatedAt(system2.now()) + .setUpdatedAt(system2.now())); + return new RuleImpl(dao.selectOrFailByKey(dbSession, external.getKey())); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java index 73ab988cade..b6823f0e3ef 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java @@ -36,14 +36,11 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.rule.RuleDao; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleDto.Format; import org.sonar.db.rule.RuleMetadataDto; import org.sonar.db.rule.RuleParamDto; -import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; -import org.sonar.server.computation.task.projectanalysis.issue.RuleImpl; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.rule.index.RuleIndexer; @@ -52,7 +49,6 @@ import org.sonar.server.util.TypeValidations; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Lists.newArrayList; import static java.lang.String.format; -import static org.sonar.db.rule.RuleDto.Scope.ALL; import static org.sonar.server.ws.WsUtils.checkRequest; @ServerSide @@ -93,20 +89,6 @@ public class RuleCreator { return customRuleKey; } - public org.sonar.server.computation.task.projectanalysis.issue.Rule create(DbSession dbSession, NewExternalRule external) { - RuleDao dao = dbClient.ruleDao(); - dao.insert(dbSession, new RuleDefinitionDto() - .setRuleKey(external.getKey()) - .setPluginKey(external.getPluginKey()) - .setIsExternal(true) - .setName(external.getName()) - .setDescriptionURL(external.getDescriptionUrl()) - .setType(external.getType()) - .setScope(ALL) - .setSeverity(external.getSeverity())); - return new RuleImpl(dao.selectOrFailByKey(dbSession, external.getKey())); - } - private void validateCustomRule(NewCustomRule newRule, DbSession dbSession, RuleKey templateKey) { List errors = new ArrayList<>(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculatorTest.java index b8ebe63fdb5..8024f1b121f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculatorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueCreationDateCalculatorTest.java @@ -59,33 +59,25 @@ public class IssueCreationDateCalculatorTest { @Rule public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); - private ScmInfoRepository scmInfoRepository; - private IssueFieldsSetter issueUpdater; - private ActiveRulesHolder activeRulesHolder; - private Component component; - private RuleKey ruleKey; - private DefaultIssue issue; - private ActiveRule activeRule; + private ScmInfoRepository scmInfoRepository = mock(ScmInfoRepository.class); + private IssueFieldsSetter issueUpdater = mock(IssueFieldsSetter.class); + private ActiveRulesHolder activeRulesHolder = mock(ActiveRulesHolder.class); + private Component component = mock(Component.class); + private RuleKey ruleKey = RuleKey.of("reop", "rule"); + private DefaultIssue issue = mock(DefaultIssue.class); + private ActiveRule activeRule = mock(ActiveRule.class); private IssueCreationDateCalculator calculator; - private Analysis baseAnalysis; - private Map scannerPlugins; + private Analysis baseAnalysis = mock(Analysis.class); + private Map scannerPlugins = new HashMap<>(); + private RuleRepository ruleRepository = mock(RuleRepository.class); private ScmInfo scmInfo; @Before public void before() { - scannerPlugins = new HashMap<>(); analysisMetadataHolder.setScannerPluginsByKey(scannerPlugins); analysisMetadataHolder.setAnalysisDate(new Date()); - scmInfoRepository = mock(ScmInfoRepository.class); - issueUpdater = mock(IssueFieldsSetter.class); - activeRulesHolder = mock(ActiveRulesHolder.class); - component = mock(Component.class); when(component.getUuid()).thenReturn(COMPONENT_UUID); - ruleKey = RuleKey.of("reop", "rule"); - issue = mock(DefaultIssue.class); - activeRule = mock(ActiveRule.class); - baseAnalysis = mock(Analysis.class); - calculator = new IssueCreationDateCalculator(analysisMetadataHolder, scmInfoRepository, issueUpdater, activeRulesHolder); + calculator = new IssueCreationDateCalculator(analysisMetadataHolder, scmInfoRepository, issueUpdater, activeRulesHolder, ruleRepository); when(activeRulesHolder.get(any(RuleKey.class))) .thenReturn(Optional.absent()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java index 24400902b3d..318f4e4ca7b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java @@ -21,16 +21,13 @@ package org.sonar.server.computation.task.projectanalysis.issue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; - import java.util.Optional; - import org.junit.Before; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; @@ -42,14 +39,10 @@ import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.server.es.EsTester; -import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.rule.RuleCreator; +import org.sonar.server.rule.ExternalRuleCreator; import org.sonar.server.rule.index.RuleIndexDefinition; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.util.TypeValidationsTesting; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; @@ -61,8 +54,6 @@ import static org.mockito.Mockito.when; import static org.mockito.internal.verification.VerificationModeFactory.times; import static org.sonar.api.rule.Severity.BLOCKER; import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.server.organization.TestDefaultOrganizationProvider.from; -import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations; public class RuleRepositoryImplTest { @@ -87,14 +78,12 @@ public class RuleRepositoryImplTest { @org.junit.Rule public EsTester es = new EsTester(new RuleIndexDefinition(new MapSettings().asConfig())); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); - private RuleCreator creator = new RuleCreator(System2.INSTANCE, ruleIndexer, db.getDbClient(), newFullTypeValidations(), from(db)); - private DbClient dbClient = mock(DbClient.class); private DbSession dbSession = mock(DbSession.class); private RuleDao ruleDao = mock(RuleDao.class); - private RuleRepositoryImpl underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); + private ExternalRuleCreator externalRuleCreator = new ExternalRuleCreator(dbClient, System2.INSTANCE); + private RuleRepositoryImpl underTest = new RuleRepositoryImpl(externalRuleCreator, dbClient, analysisMetadataHolder); @Before public void setUp() throws Exception { @@ -284,7 +273,8 @@ public class RuleRepositoryImplTest { @Test public void accept_new_externally_defined_Rules() { DbClient dbClient = db.getDbClient(); - underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); + externalRuleCreator = new ExternalRuleCreator(dbClient, System2.INSTANCE); + underTest = new RuleRepositoryImpl(externalRuleCreator, dbClient, analysisMetadataHolder); RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); @@ -297,7 +287,6 @@ public class RuleRepositoryImplTest { .setType(BUG) .build()); - assertThat(underTest.getByKey(ruleKey)).isNotNull(); assertThat(underTest.getByKey(ruleKey).getPluginKey()).isEqualTo("eslint"); assertThat(underTest.getByKey(ruleKey).getName()).isEqualTo("disallow assignment operators in conditional statements (no-cond-assign)"); @@ -312,7 +301,8 @@ public class RuleRepositoryImplTest { public void persist_new_externally_defined_Rules() { DbClient dbClient = db.getDbClient(); DbSession dbSession = dbClient.openSession(false); - underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); + externalRuleCreator = new ExternalRuleCreator(dbClient, System2.INSTANCE); + underTest = new RuleRepositoryImpl(externalRuleCreator, dbClient, analysisMetadataHolder); RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); underTest.insertNewExternalRuleIfAbsent(ruleKey, () -> new NewExternalRule.Builder() @@ -324,7 +314,6 @@ public class RuleRepositoryImplTest { .setType(BUG) .build()); - underTest.persistNewExternalRules(dbSession); dbSession.commit(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java index a9f0fdaf553..d3f2a9d33db 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java @@ -34,17 +34,14 @@ import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; import org.sonar.server.computation.task.projectanalysis.issue.RuleRepositoryImpl; import org.sonar.server.computation.task.step.ComputationStep; import org.sonar.server.es.EsTester; -import org.sonar.server.rule.RuleCreator; +import org.sonar.server.rule.ExternalRuleCreator; import org.sonar.server.rule.index.RuleIndexDefinition; -import org.sonar.server.rule.index.RuleIndexer; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.rule.Severity.BLOCKER; import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.server.organization.TestDefaultOrganizationProvider.from; -import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations; public class PersistExternalRulesStepTest extends BaseStepTest { @@ -56,7 +53,6 @@ public class PersistExternalRulesStepTest extends BaseStepTest { .setOrganizationUuid("org-1", "qg-uuid-1"); private DbClient dbClient = db.getDbClient(); - private System2 system2 = System2.INSTANCE; private ComputationStep underTest; private RuleRepositoryImpl ruleRepository; @@ -64,9 +60,7 @@ public class PersistExternalRulesStepTest extends BaseStepTest { @org.junit.Rule public EsTester es = new EsTester(new RuleIndexDefinition(new MapSettings().asConfig())); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); - private RuleCreator creator = new RuleCreator(System2.INSTANCE, ruleIndexer, db.getDbClient(), newFullTypeValidations(), from(db)); - + private ExternalRuleCreator externalRuleCreator = new ExternalRuleCreator(dbClient, System2.INSTANCE); @Override protected ComputationStep step() { @@ -75,7 +69,7 @@ public class PersistExternalRulesStepTest extends BaseStepTest { @Before public void setup() { - ruleRepository = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); + ruleRepository = new RuleRepositoryImpl(externalRuleCreator, dbClient, analysisMetadataHolder); underTest = new PersistExternalRulesStep(dbClient, ruleRepository); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistIssuesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistIssuesStepTest.java index 2d3590b42fb..e57c3dd6729 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistIssuesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistIssuesStepTest.java @@ -52,9 +52,8 @@ import org.sonar.server.computation.task.projectanalysis.issue.RuleRepositoryImp import org.sonar.server.computation.task.projectanalysis.issue.UpdateConflictResolver; import org.sonar.server.computation.task.step.ComputationStep; import org.sonar.server.es.EsTester; -import org.sonar.server.rule.RuleCreator; +import org.sonar.server.rule.ExternalRuleCreator; import org.sonar.server.rule.index.RuleIndexDefinition; -import org.sonar.server.rule.index.RuleIndexer; import org.sonar.server.util.cache.DiskCache; import static java.util.Collections.singletonList; @@ -66,8 +65,6 @@ import static org.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_OPEN; import static org.sonar.api.rule.Severity.BLOCKER; import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.server.organization.TestDefaultOrganizationProvider.from; -import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations; public class PersistIssuesStepTest extends BaseStepTest { @@ -92,8 +89,7 @@ public class PersistIssuesStepTest extends BaseStepTest { @org.junit.Rule public EsTester es = new EsTester(new RuleIndexDefinition(new MapSettings().asConfig())); - private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient()); - private RuleCreator creator = new RuleCreator(System2.INSTANCE, ruleIndexer, db.getDbClient(), newFullTypeValidations(), from(db)); + private ExternalRuleCreator externalRuleCreator = new ExternalRuleCreator(dbClient, System2.INSTANCE); @Override protected ComputationStep step() { @@ -107,7 +103,7 @@ public class PersistIssuesStepTest extends BaseStepTest { when(system2.now()).thenReturn(NOW); reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance()); - step = new PersistIssuesStep(dbClient, system2, new UpdateConflictResolver(), new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder), issueCache); + step = new PersistIssuesStep(dbClient, system2, new UpdateConflictResolver(), new RuleRepositoryImpl(externalRuleCreator, dbClient, analysisMetadataHolder), issueCache); } @After diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java new file mode 100644 index 00000000000..2beeddfc76c --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java @@ -0,0 +1,67 @@ +/* + * 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.rule; + +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.System2; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; +import org.sonar.server.computation.task.projectanalysis.issue.Rule; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.rule.Severity.BLOCKER; +import static org.sonar.api.rules.RuleType.BUG; + +public class ExternalRuleCreatorTest { + + @org.junit.Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + + private ExternalRuleCreator underTest = new ExternalRuleCreator(dbTester.getDbClient(), System2.INSTANCE); + private DbSession dbSession = dbTester.getSession(); + + @Test + public void create_external_rule() { + + RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); + NewExternalRule externalRule = new NewExternalRule.Builder() + .setKey(ruleKey) + .setPluginKey("eslint") + .setName("disallow assignment operators in conditional statements (no-cond-assign)") + .setDescriptionUrl("https://eslint.org/docs/rules/no-cond-assign") + .setSeverity(BLOCKER) + .setType(BUG) + .build(); + + Rule rule1 = underTest.create(dbSession, externalRule); + + assertThat(rule1).isNotNull(); + assertThat(rule1.isExternal()).isTrue(); + assertThat(rule1.getId()).isGreaterThan(0); + assertThat(rule1.getKey()).isEqualTo(ruleKey); + assertThat(rule1.getPluginKey()).isEqualTo("eslint"); + assertThat(rule1.getName()).isEqualTo("disallow assignment operators in conditional statements (no-cond-assign)"); + assertThat(rule1.getType()).isEqualTo(BUG); + + } + +} -- 2.39.5