@@ -25,6 +25,7 @@ import java.util.Optional; | |||
import java.util.Set; | |||
import java.util.function.Consumer; | |||
import javax.annotation.Nullable; | |||
import org.apache.ibatis.session.ResultHandler; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rules.RuleQuery; | |||
@@ -49,6 +50,11 @@ public class RuleDao implements Dao { | |||
return ofNullable(res); | |||
} | |||
public RuleDto selectOrFailByKey(DbSession session, RuleKey key) { | |||
RuleDefinitionDto ruleDefinitionDto = selectOrFailDefinitionByKey(session, key); | |||
return new RuleDto(ruleDefinitionDto, new RuleMetadataDto()); | |||
} | |||
public Optional<RuleDefinitionDto> selectDefinitionByKey(DbSession session, RuleKey key) { | |||
return ofNullable(mapper(session).selectDefinitionByKey(key)); | |||
} |
@@ -122,11 +122,12 @@ public class RuleDefinitionDto { | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getDescriptionURL() { | |||
return descriptionURL; | |||
} | |||
public RuleDefinitionDto setDescriptionURL(String descriptionURL) { | |||
public RuleDefinitionDto setDescriptionURL(@Nullable String descriptionURL) { | |||
this.descriptionURL = descriptionURL; | |||
return this; | |||
} |
@@ -42,7 +42,11 @@ public class AddRuleExternalTest { | |||
@Test | |||
public void column_are_added_to_table() throws SQLException { | |||
dbTester.assertColumnDoesNotExist("rules", "is_external"); | |||
dbTester.assertColumnDoesNotExist("rules", "description_url"); | |||
underTest.execute(); | |||
dbTester.assertColumnDefinition("rules", "is_external", BOOLEAN, null, true); | |||
dbTester.assertColumnDefinition("rules", "description_url", VARCHAR, 256, true); | |||
} |
@@ -36,6 +36,7 @@ public class NewExternalRule implements Rule { | |||
private final String descriptionUrl; | |||
private final String severity; | |||
private final RuleType type; | |||
private final String pluginKey; | |||
private NewExternalRule(Builder builder) { | |||
this.key = checkNotNull(builder.key, "key"); | |||
@@ -43,6 +44,7 @@ public class NewExternalRule implements Rule { | |||
this.descriptionUrl = builder.descriptionUrl; | |||
this.severity = checkNotEmpty(builder.severity, "severity"); | |||
this.type = checkNotNull(builder.type, "type"); | |||
this.pluginKey = builder.pluginKey; | |||
} | |||
private static String checkNotEmpty(String str, String name) { | |||
@@ -110,7 +112,7 @@ public class NewExternalRule implements Rule { | |||
@Override | |||
public String getPluginKey() { | |||
return null; | |||
return pluginKey; | |||
} | |||
public static class Builder { | |||
@@ -119,6 +121,7 @@ public class NewExternalRule implements Rule { | |||
private String descriptionUrl; | |||
private String severity; | |||
private RuleType type; | |||
private String pluginKey; | |||
public Builder setKey(RuleKey key) { | |||
this.key = key; | |||
@@ -164,5 +167,10 @@ public class NewExternalRule implements Rule { | |||
public NewExternalRule build() { | |||
return new NewExternalRule(this); | |||
} | |||
public Builder setPluginKey(String pluginKey) { | |||
this.pluginKey = pluginKey; | |||
return this; | |||
} | |||
} | |||
} |
@@ -22,6 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.issue; | |||
import java.util.Optional; | |||
import java.util.function.Supplier; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.db.DbSession; | |||
/** | |||
* Repository of every rule in DB (including manual rules) whichever their status. | |||
@@ -45,6 +46,9 @@ public interface RuleRepository { | |||
Optional<Rule> findByKey(RuleKey key); | |||
Optional<Rule> findById(int id); | |||
void insertNewExternalRuleIfAbsent(RuleKey ruleKey, Supplier<NewExternalRule> ruleSupplier); | |||
void persistNewExternalRules(DbSession dbSession); | |||
} |
@@ -19,13 +19,7 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.issue; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.Multimap; | |||
import java.util.LinkedHashMap; | |||
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; | |||
@@ -33,6 +27,13 @@ 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 static com.google.common.base.Preconditions.checkArgument; | |||
import static java.util.Objects.requireNonNull; | |||
@@ -43,23 +44,39 @@ public class RuleRepositoryImpl implements RuleRepository { | |||
private Map<RuleKey, Rule> rulesByKey; | |||
@CheckForNull | |||
private Map<Integer, Rule> rulesById; | |||
@CheckForNull | |||
private Map<RuleKey, NewExternalRule> newExternalRulesByKey; | |||
private final RuleCreator creator; | |||
private final DbClient dbClient; | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
public RuleRepositoryImpl(DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder) { | |||
public RuleRepositoryImpl(RuleCreator creator, DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder) { | |||
this.creator = creator; | |||
this.dbClient = dbClient; | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
} | |||
public void insertNewExternalRuleIfAbsent(RuleKey ruleKey, Supplier<NewExternalRule> ruleSupplier) { | |||
ensureInitialized(); | |||
if (!rulesByKey.containsKey(ruleKey)) { | |||
newExternalRulesByKey.computeIfAbsent(ruleKey, s -> ruleSupplier.get()); | |||
rulesByKey.computeIfAbsent(ruleKey, s -> ruleSupplier.get()); | |||
} | |||
} | |||
@Override public void persistNewExternalRules(DbSession dbSession) { | |||
ensureInitialized(); | |||
rulesByKey.values().stream() | |||
.filter(NewExternalRule.class::isInstance) | |||
.forEach(extRule -> persistAndIndex(dbSession, (NewExternalRule) extRule)); | |||
} | |||
private void persistAndIndex(DbSession dbSession, NewExternalRule external) { | |||
Rule rule = creator.create(dbSession, external); | |||
rulesById.put(rule.getId(), rule); | |||
rulesByKey.put(external.getKey(), rule); | |||
} | |||
@Override | |||
public Rule getByKey(RuleKey key) { | |||
verifyKeyArgument(key); | |||
@@ -109,20 +126,17 @@ public class RuleRepositoryImpl implements RuleRepository { | |||
} | |||
private void loadRulesFromDb(DbSession dbSession) { | |||
ImmutableMap.Builder<RuleKey, Rule> rulesByKeyBuilder = ImmutableMap.builder(); | |||
ImmutableMap.Builder<Integer, Rule> rulesByIdBuilder = ImmutableMap.builder(); | |||
this.rulesByKey = new HashMap<>(); | |||
this.rulesById = new HashMap<>(); | |||
String organizationUuid = analysisMetadataHolder.getOrganization().getUuid(); | |||
Multimap<Integer, DeprecatedRuleKeyDto> deprecatedRuleKeysByRuleId = dbClient.ruleDao().selectAllDeprecatedRuleKeys(dbSession).stream() | |||
.collect(MoreCollectors.index(DeprecatedRuleKeyDto::getRuleId)); | |||
for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession, organizationUuid)) { | |||
Rule rule = new RuleImpl(ruleDto); | |||
rulesByKeyBuilder.put(ruleDto.getKey(), rule); | |||
rulesByIdBuilder.put(ruleDto.getId(), rule); | |||
deprecatedRuleKeysByRuleId.get(ruleDto.getId()).forEach(t -> rulesByKeyBuilder.put(RuleKey.of(t.getOldRepositoryKey(), t.getOldRuleKey()), rule)); | |||
rulesByKey.put(ruleDto.getKey(), rule); | |||
rulesById.put(ruleDto.getId(), rule); | |||
deprecatedRuleKeysByRuleId.get(ruleDto.getId()).forEach(t -> rulesByKey.put(RuleKey.of(t.getOldRepositoryKey(), t.getOldRuleKey()), rule)); | |||
} | |||
this.rulesByKey = rulesByKeyBuilder.build(); | |||
this.rulesById = rulesByIdBuilder.build(); | |||
this.newExternalRulesByKey = new LinkedHashMap<>(); | |||
} | |||
} |
@@ -0,0 +1,53 @@ | |||
/* | |||
* 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.step; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.server.computation.task.projectanalysis.issue.RuleRepository; | |||
import org.sonar.server.computation.task.step.ComputationStep; | |||
public class PersistExternalRulesStep implements ComputationStep { | |||
private final DbClient dbClient; | |||
private final RuleRepository ruleRepository; | |||
public PersistExternalRulesStep(DbClient dbClient, RuleRepository ruleRepository) { | |||
this.dbClient = dbClient; | |||
this.ruleRepository = ruleRepository; | |||
} | |||
@Override | |||
public void execute() { | |||
try (DbSession dbSession = dbClient.openSession(true)) { | |||
ruleRepository.persistNewExternalRules(dbSession); | |||
dbSession.flushStatements(); | |||
dbSession.commit(); | |||
} | |||
} | |||
@Override | |||
public String getDescription() { | |||
return "Persist new externally defined Rules"; | |||
} | |||
} |
@@ -89,6 +89,7 @@ public class ReportComputationSteps extends AbstractComputationSteps { | |||
PersistAnalysisPropertiesStep.class, | |||
PersistMeasuresStep.class, | |||
PersistLiveMeasuresStep.class, | |||
PersistExternalRulesStep.class, | |||
PersistIssuesStep.class, | |||
PersistProjectLinksStep.class, | |||
PersistEventsStep.class, |
@@ -36,11 +36,14 @@ 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; | |||
@@ -49,6 +52,7 @@ 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 | |||
@@ -89,6 +93,20 @@ 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<String> errors = new ArrayList<>(); | |||
@@ -35,6 +35,7 @@ public class NewExternalRuleTest { | |||
NewExternalRule.Builder builder = new NewExternalRule.Builder() | |||
.setDescriptionUrl("url") | |||
.setKey(RuleKey.of("repo", "rule")) | |||
.setPluginKey("repo") | |||
.setName("name") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.BUG); | |||
@@ -49,7 +50,7 @@ public class NewExternalRuleTest { | |||
assertThat(rule.getDescriptionUrl()).isEqualTo("url"); | |||
assertThat(rule.getName()).isEqualTo("name"); | |||
assertThat(rule.getPluginKey()).isNull(); | |||
assertThat(rule.getPluginKey()).isEqualTo("repo"); | |||
assertThat(rule.getSeverity()).isEqualTo("MAJOR"); | |||
assertThat(rule.getType()).isEqualTo(RuleType.BUG); | |||
assertThat(rule.getDescriptionUrl()).isEqualTo("url"); |
@@ -21,21 +21,35 @@ 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; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.rule.DeprecatedRuleKeyDto; | |||
import org.sonar.db.rule.RuleDao; | |||
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.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; | |||
@@ -45,6 +59,10 @@ import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||
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 { | |||
@@ -64,11 +82,19 @@ public class RuleRepositoryImplTest { | |||
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule() | |||
.setOrganizationUuid(ORGANIZATION_UUID, QUALITY_GATE_UUID); | |||
@org.junit.Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@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(dbClient, analysisMetadataHolder); | |||
private RuleRepositoryImpl underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); | |||
@Before | |||
public void setUp() throws Exception { | |||
@@ -255,6 +281,64 @@ public class RuleRepositoryImplTest { | |||
assertIsABRule(rule.get()); | |||
} | |||
@Test | |||
public void accept_new_externally_defined_Rules() { | |||
DbClient dbClient = db.getDbClient(); | |||
underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); | |||
RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); | |||
underTest.insertNewExternalRuleIfAbsent(ruleKey, () -> 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()); | |||
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)"); | |||
assertThat(underTest.getByKey(ruleKey).getType()).isEqualTo(BUG); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
Optional<RuleDefinitionDto> ruleDefinitionDto = ruleDao.selectDefinitionByKey(dbClient.openSession(false), ruleKey); | |||
assertThat(ruleDefinitionDto).isNotPresent(); | |||
} | |||
@Test | |||
public void persist_new_externally_defined_Rules() { | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = dbClient.openSession(false); | |||
underTest = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); | |||
RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); | |||
underTest.insertNewExternalRuleIfAbsent(ruleKey, () -> 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()); | |||
underTest.persistNewExternalRules(dbSession); | |||
dbSession.commit(); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
Optional<RuleDefinitionDto> ruleDefinitionDto = ruleDao.selectDefinitionByKey(dbClient.openSession(false), ruleKey); | |||
assertThat(ruleDefinitionDto).isPresent(); | |||
Rule rule = underTest.getByKey(ruleKey); | |||
assertThat(rule).isNotNull(); | |||
assertThat(underTest.getById(ruleDefinitionDto.get().getId())).isNotNull(); | |||
} | |||
private void expectNullRuleKeyNPE() { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("RuleKey can not be null"); |
@@ -23,8 +23,10 @@ import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import java.util.function.Supplier; | |||
import org.junit.rules.ExternalResource; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.db.DbSession; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static java.util.Objects.requireNonNull; | |||
@@ -65,6 +67,10 @@ public class RuleRepositoryRule extends ExternalResource implements RuleReposito | |||
return Optional.ofNullable(rulesById.get(id)); | |||
} | |||
@Override public void persistNewExternalRules(DbSession dbSession) { | |||
throw new UnsupportedOperationException(); | |||
} | |||
public DumbRule add(RuleKey key) { | |||
DumbRule rule = new DumbRule(key); | |||
rule.setId(key.hashCode()); |
@@ -0,0 +1,114 @@ | |||
/* | |||
* 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.step; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.config.internal.MapSettings; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.rule.RuleDao; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; | |||
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.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 { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule() | |||
.setOrganizationUuid("org-1", "qg-uuid-1"); | |||
private DbClient dbClient = db.getDbClient(); | |||
private System2 system2 = System2.INSTANCE; | |||
private ComputationStep underTest; | |||
private RuleRepositoryImpl ruleRepository; | |||
@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)); | |||
@Override | |||
protected ComputationStep step() { | |||
return underTest; | |||
} | |||
@Before | |||
public void setup() { | |||
ruleRepository = new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder); | |||
underTest = new PersistExternalRulesStep(dbClient, ruleRepository); | |||
} | |||
@Test | |||
public void persist_new_external_rules() { | |||
RuleKey ruleKey = RuleKey.of("eslint", "no-cond-assign"); | |||
ruleRepository.insertNewExternalRuleIfAbsent(ruleKey, () -> 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()); | |||
underTest.execute(); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
Optional<RuleDefinitionDto> ruleDefinitionDtoOptional = ruleDao.selectDefinitionByKey(dbClient.openSession(false), ruleKey); | |||
assertThat(ruleDefinitionDtoOptional).isPresent(); | |||
RuleDefinitionDto reloaded = ruleDefinitionDtoOptional.get(); | |||
assertThat(reloaded.getRuleKey()).isEqualTo("no-cond-assign"); | |||
assertThat(reloaded.getRepositoryKey()).isEqualTo("eslint"); | |||
assertThat(reloaded.isExternal()).isTrue(); | |||
assertThat(reloaded.getType()).isEqualTo(2); | |||
assertThat(reloaded.getSeverity()).isEqualTo(4); | |||
assertThat(reloaded.getDescriptionURL()).isEqualTo("https://eslint.org/docs/rules/no-cond-assign"); | |||
assertThat(reloaded.getName()).isEqualTo("disallow assignment operators in conditional statements (no-cond-assign)"); | |||
assertThat(reloaded.getPluginKey()).isEqualTo("eslint"); | |||
} | |||
} |
@@ -27,6 +27,7 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.config.internal.MapSettings; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rules.RuleType; | |||
import org.sonar.api.utils.System2; | |||
@@ -50,6 +51,10 @@ import org.sonar.server.computation.task.projectanalysis.issue.IssueCache; | |||
import org.sonar.server.computation.task.projectanalysis.issue.RuleRepositoryImpl; | |||
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.index.RuleIndexDefinition; | |||
import org.sonar.server.rule.index.RuleIndexer; | |||
import org.sonar.server.util.cache.DiskCache; | |||
import static java.util.Collections.singletonList; | |||
@@ -61,6 +66,8 @@ 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 { | |||
@@ -82,6 +89,12 @@ public class PersistIssuesStepTest extends BaseStepTest { | |||
private IssueCache issueCache; | |||
private ComputationStep step; | |||
@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)); | |||
@Override | |||
protected ComputationStep step() { | |||
return step; | |||
@@ -94,7 +107,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(dbClient, analysisMetadataHolder), issueCache); | |||
step = new PersistIssuesStep(dbClient, system2, new UpdateConflictResolver(), new RuleRepositoryImpl(creator, dbClient, analysisMetadataHolder), issueCache); | |||
} | |||
@After |