private RepositoryImpl(NewRepositoryImpl newRepository, @Nullable Repository mergeInto) { this.key = newRepository.key; this.language = newRepository.language; this.isExternal = newRepository.isExternal; Map<String, Rule> ruleBuilder = new HashMap<>(); if (mergeInto != null) { if (!StringUtils.equals(newRepository.language, mergeInto.language()) || !StringUtils.equals(newRepository.key, mergeInto.key())) { throw new IllegalArgumentException(format("Bug - language and key of the repositories to be merged should be the sames: %s and %s", newRepository, mergeInto)); } this.name = StringUtils.defaultIfBlank(mergeInto.name(), newRepository.name); for (Rule rule : mergeInto.rules()) { if (!newRepository.key().startsWith("common-") && ruleBuilder.containsKey(rule.key())) { Loggers.get(getClass()).warn("The rule '{}' of repository '{}' is declared several times", rule.key(), mergeInto.key()); } ruleBuilder.put(rule.key(), rule); } } else { this.name = newRepository.name; } for (NewRule newRule : newRepository.newRules.values()) { newRule.validate(); ruleBuilder.put(newRule.key, new Rule(this, newRule)); } this.rulesByKey = unmodifiableMap(ruleBuilder); }
@Test public void define_xoo2_rules() { RulesDefinition.Repository repo = context.repository("xoo2"); assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo2"); assertThat(repo.language()).isEqualTo("xoo2"); assertThat(repo.rules()).hasSize(2); } }
@Test public void support_deprecated_format() { // the deprecated format uses some attributes instead of nodes InputStream input = getClass().getResourceAsStream("RulesDefinitionXmlLoaderTest/deprecated.xml"); RulesDefinition.Repository repository = load(input, StandardCharsets.UTF_8.name()); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); assertThat(rule.key()).isEqualTo("org.sonar.it.checkstyle.MethodsCountCheck"); assertThat(rule.internalKey()).isEqualTo("Checker/TreeWalker/org.sonar.it.checkstyle.MethodsCountCheck"); assertThat(rule.severity()).isEqualTo(Severity.CRITICAL); assertThat(rule.htmlDescription()).isEqualTo("Count methods"); assertThat(rule.param("minMethodsCount")).isNotNull(); }
/** * This is temporarily accepted only for the support of the common-rules that are still declared * by plugins. It could be removed in 7.0 * @since 5.2 */ @Test public void allow_to_replace_an_existing_common_rule() { RulesDefinition.NewRepository newCommonJava1 = context.createRepository("common-java", "java").setName("Common Java"); newCommonJava1.createRule("coverage").setName("Lack of coverage").setHtmlDescription("Coverage must be high"); newCommonJava1.done(); RulesDefinition.NewRepository newCommonJava2 = context.createRepository("common-java", "java"); newCommonJava2.createRule("coverage").setName("Lack of coverage (V2)").setMarkdownDescription("Coverage must be high (V2)"); newCommonJava2.done(); RulesDefinition.Repository commonJava = context.repository("common-java"); assertThat(commonJava.rules()).hasSize(1); RulesDefinition.Rule rule = commonJava.rule("coverage"); assertThat(rule.name()).isEqualTo("Lack of coverage (V2)"); // replacement but not merge -> keep only the v2 (which has markdown but not html description) assertThat(rule.markdownDescription()).isEqualTo("Coverage must be high (V2)"); assertThat(rule.htmlDescription()).isNull(); // do not log warning assertThat(logTester.logs()).isEmpty(); }
@Test public void define_repositories() { assertThat(context.repositories()).isEmpty(); context.createRepository("findbugs", "java").setName("Findbugs").done(); context.createRepository("checkstyle", "java").done(); assertThat(context.repositories()).hasSize(2); RulesDefinition.Repository findbugs = context.repository("findbugs"); assertThat(findbugs).isNotNull(); assertThat(findbugs.key()).isEqualTo("findbugs"); assertThat(findbugs.language()).isEqualTo("java"); assertThat(findbugs.name()).isEqualTo("Findbugs"); assertThat(findbugs.rules()).isEmpty(); RulesDefinition.Repository checkstyle = context.repository("checkstyle"); assertThat(checkstyle).isNotNull(); assertThat(checkstyle.key()).isEqualTo("checkstyle"); assertThat(checkstyle.language()).isEqualTo("java"); // default name is key assertThat(checkstyle.name()).isEqualTo("checkstyle"); assertThat(checkstyle.rules()).isEmpty(); assertThat(context.repository("unknown")).isNull(); // test equals() and hashCode() assertThat(findbugs).isEqualTo(findbugs).isNotEqualTo(checkstyle).isNotEqualTo("findbugs").isNotEqualTo(null); assertThat(findbugs.hashCode()).isEqualTo(findbugs.hashCode()); }
@Test public void define_rules_with_remediation_function() { RulesDefinition.NewRepository newRepo = context.createRepository("common-java", "java"); RulesDefinition.NewRule newRule = newRepo.createRule("InsufficientBranchCoverage") .setName("Insufficient condition coverage") .setHtmlDescription("Insufficient condition coverage by unit tests") .setSeverity(Severity.MAJOR) .setGapDescription("Effort to test one uncovered branch"); newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().linearWithOffset("1h", "10min")); newRepo.done(); RulesDefinition.Repository repo = context.repository("common-java"); assertThat(repo.rules()).hasSize(1); RulesDefinition.Rule rule = repo.rule("InsufficientBranchCoverage"); assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET); assertThat(rule.debtRemediationFunction().gapMultiplier()).isEqualTo("1h"); assertThat(rule.debtRemediationFunction().baseEffort()).isEqualTo("10min"); assertThat(rule.gapDescription()).isEqualTo("Effort to test one uncovered branch"); }
@Test public void rule_with_property() { RulesDefinition.Repository repository = load(RuleWithProperty.class); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); assertThat(rule.key()).isEqualTo("foo"); assertThat(rule.status()).isEqualTo(RuleStatus.BETA); assertThat(rule.name()).isEqualTo("bar"); assertThat(rule.htmlDescription()).isEqualTo("Foo Bar"); assertThat(rule.severity()).isEqualTo(Severity.BLOCKER); assertThat(rule.params()).hasSize(1); assertThat(rule.tags()).isEmpty(); RulesDefinition.Param prop = rule.param("property"); assertThat(prop.key()).isEqualTo("property"); assertThat(prop.description()).isEqualTo("Ignore ?"); assertThat(prop.defaultValue()).isEqualTo("false"); assertThat(prop.type()).isEqualTo(RuleParamType.STRING); }
@Test public void add_rules_to_existing_repository() { RulesDefinition.NewRepository newFindbugs = context.createRepository("findbugs", "java").setName("Findbugs"); newFindbugs.createRule("NPE").setName("NPE").setHtmlDescription("NPE"); newFindbugs.done(); RulesDefinition.NewRepository newFbContrib = context.createRepository("findbugs", "java"); newFbContrib.createRule("VULNERABILITY").setName("Vulnerability").setMarkdownDescription("Detect vulnerability"); newFbContrib.done(); assertThat(context.repositories()).hasSize(1); RulesDefinition.Repository findbugs = context.repository("findbugs"); assertThat(findbugs.key()).isEqualTo("findbugs"); assertThat(findbugs.language()).isEqualTo("java"); assertThat(findbugs.name()).isEqualTo("Findbugs"); assertThat(findbugs.rules()).extracting("key").containsOnly("NPE", "VULNERABILITY"); }
/** * "common-rules" are merged into core 5.2. Previously they were embedded by some plugins. Only the core definition * is taken into account. Others are ignored. */ @Test public void plugin_common_rules_are_overridden() { CommonRuleDefinitions commonRulesDefinitions = new FakeCommonRuleDefinitions(); RulesDefinition.Context context = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), commonRulesDefinitions, mock(ServerPluginRepository.class), new RulesDefinition[] { new PluginCommonRuleDefinitions() }).load(); assertThat(context.repositories()).extracting("key").containsOnly("common-java"); assertThat(context.repository("common-java").rules()).extracting("key").containsOnly("InsufficientBranchCoverage"); assertThat(context.repository("common-java").rule("InsufficientBranchCoverage").name()).isEqualTo("The name as defined by core"); }
@Test public void define_xoo_rules() { RulesDefinition.Repository repo = context.repository("xoo"); assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo"); assertThat(repo.language()).isEqualTo("xoo"); assertThat(repo.rules()).hasSize(19); RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY); assertThat(rule.name()).isNotEmpty(); assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR); assertThat(rule.debtRemediationFunction().gapMultiplier()).isEqualTo("1min"); assertThat(rule.debtRemediationFunction().baseEffort()).isNull(); assertThat(rule.gapDescription()).isNotEmpty(); }
@Test public void define_xooExternal_rules() { RulesDefinition.Repository repo = context.repository("external_XooEngine"); assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("XooEngine"); assertThat(repo.language()).isEqualTo("xoo"); assertThat(repo.rules()).hasSize(1); }
@Test public void test_utf8_encoding() throws UnsupportedEncodingException { InputStream input = getClass().getResourceAsStream("RulesDefinitionXmlLoaderTest/utf8.xml"); RulesDefinition.Repository repository = load(input, StandardCharsets.UTF_8.name()); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); assertThat(rule.key()).isEqualTo("com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck"); assertThat(rule.name()).isEqualTo("M & M"); assertThat(rule.htmlDescription().charAt(0)).isEqualTo('\u00E9'); assertThat(rule.htmlDescription().charAt(1)).isEqualTo('\u00E0'); assertThat(rule.htmlDescription().charAt(2)).isEqualTo('\u0026'); }
public ScannerMediumTester addRules(RulesDefinition rulesDefinition) { RulesDefinition.Context context = new RulesDefinition.Context(); rulesDefinition.define(context); List<Repository> repositories = context.repositories(); for (Repository repo : repositories) { for (RulesDefinition.Rule rule : repo.rules()) { this.addRule(rule.key(), rule.repository().key(), rule.internalKey(), rule.name()); } } return this; }
@Test public void define_common_rules() { CommonRuleDefinitions commonRulesDefinitions = new FakeCommonRuleDefinitions(); RulesDefinition.Context context = new RuleDefinitionsLoader(mock(DeprecatedRulesDefinitionLoader.class), commonRulesDefinitions, mock(ServerPluginRepository.class), new RulesDefinition[] { new SquidDefinitions() }).load(); assertThat(context.repositories()).extracting("key").containsOnly("squid", "common-java"); assertThat(context.repository("common-java").rules()).extracting("key").containsOnly("InsufficientBranchCoverage"); }
@Test public void define_xoo_hotspot_rule() { RulesDefinition.Repository repo = context.repository("xoo"); assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo"); assertThat(repo.language()).isEqualTo("xoo"); assertThat(repo.rules()).hasSize(19); RulesDefinition.Rule rule = repo.rule(HotspotSensor.RULE_KEY); assertThat(rule.name()).isNotEmpty(); assertThat(rule.securityStandards()) .isNotEmpty() .containsExactlyInAnyOrder("cwe:1", "cwe:123", "cwe:863", "owaspTop10:a1", "owaspTop10:a3"); }
@Test public void overridden_class() { RulesDefinition.Repository repository = load(OverridingRule.class); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); assertThat(rule.key()).isEqualTo("overriding_foo"); assertThat(rule.name()).isEqualTo("Overriding Foo"); assertThat(rule.severity()).isEqualTo(Severity.MAJOR); assertThat(rule.htmlDescription()).isEqualTo("Desc of Overriding Foo"); assertThat(rule.params()).hasSize(2); }
@Test public void rule_with_text_property() { RulesDefinition.Repository repository = load(RuleWithTextProperty.class); RulesDefinition.Param prop = repository.rules().get(0).param("property"); assertThat(prop.description()).isEqualTo("text"); assertThat(prop.defaultValue()).isEqualTo("Long text"); assertThat(prop.type()).isEqualTo(RuleParamType.TEXT); }
@Test public void use_classname_when_missing_key() { RulesDefinition.Repository repository = load(RuleWithoutKey.class); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); assertThat(rule.key()).isEqualTo(RuleWithoutKey.class.getCanonicalName()); assertThat(rule.name()).isEqualTo("foo"); }
@Test public void rule_with_integer_property() { RulesDefinition.Repository repository = load(RuleWithIntegerProperty.class); RulesDefinition.Param prop = repository.rules().get(0).param("property"); assertThat(prop.description()).isEqualTo("Max"); assertThat(prop.defaultValue()).isEqualTo("12"); assertThat(prop.type()).isEqualTo(RuleParamType.INTEGER); }