@Test public void load_external_issues_from_report() { when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder() .setTextRange(TextRange.newBuilder().setStartLine(2).build()) .setMsg("the message") .setEngineId("eslint") .setRuleId("S001") .setSeverity(Constants.Severity.BLOCKER) .setEffort(20l) .setType(ScannerReport.IssueType.SECURITY_HOTSPOT) .build(); reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); Input<DefaultIssue> input = underTest.create(FILE); Collection<DefaultIssue> issues = input.getIssues(); assertThat(issues).hasSize(1); DefaultIssue issue = Iterators.getOnlyElement(issues.iterator()); // fields set by analysis report assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001")); assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.line()).isEqualTo(2); assertThat(issue.effort()).isEqualTo(Duration.create(20l)); assertThat(issue.message()).isEqualTo("the message"); assertThat(issue.type()).isEqualTo(RuleType.SECURITY_HOTSPOT); // fields set by compute engine assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); assertThat(issue.tags()).isEmpty(); assertInitializedExternalIssue(issue); }
assertThat(issue.getFlowCount()).isZero(); assertThat(issue.getMsg()).isEqualTo("fix the issue here"); assertThat(issue.getEngineId()).isEqualTo("externalXoo"); assertThat(issue.getRuleId()).isEqualTo("rule1"); assertThat(issue.getSeverity()).isEqualTo(Severity.MAJOR); assertThat(issue.getEffort()).isEqualTo(50l); assertThat(issue.getType()).isEqualTo(IssueType.CODE_SMELL); assertThat(issue.getTextRange().getStartLine()).isEqualTo(5); assertThat(issue.getTextRange().getEndLine()).isEqualTo(5); assertThat(issue.getTextRange().getStartOffset()).isEqualTo(3); assertThat(issue.getTextRange().getEndOffset()).isEqualTo(41); assertThat(issue.getFlowCount()).isZero(); assertThat(issue.getMsg()).isEqualTo("fix the bug here"); assertThat(issue.getEngineId()).isEqualTo("externalXoo"); assertThat(issue.getRuleId()).isEqualTo("rule2"); assertThat(issue.getSeverity()).isEqualTo(Severity.CRITICAL); assertThat(issue.getType()).isEqualTo(IssueType.BUG); assertThat(issue.getEffort()).isZero(); assertThat(issue.getTextRange().getStartLine()).isEqualTo(3); assertThat(issue.getTextRange().getEndLine()).isEqualTo(3); assertThat(issue.getTextRange().getStartOffset()).isEqualTo(0); assertThat(issue.getTextRange().getEndOffset()).isEqualTo(24); assertThat(issue.getFlowCount()).isEqualTo(2); assertThat(issue.getMsg()).isEqualTo("fix the bug here"); assertThat(issue.getEngineId()).isEqualTo("externalXoo"); assertThat(issue.getRuleId()).isEqualTo("rule3"); assertThat(issue.getSeverity()).isEqualTo(Severity.MAJOR);
@Test public void write_external_issues() { // no data yet assertThat(underTest.hasComponentData(FileStructure.Domain.EXTERNAL_ISSUES, 1)).isFalse(); // write data ScannerReport.ExternalIssue issue = ScannerReport.ExternalIssue.newBuilder() .setMsg("the message") .build(); underTest.appendComponentExternalIssue(1, issue); assertThat(underTest.hasComponentData(FileStructure.Domain.EXTERNAL_ISSUES, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.EXTERNAL_ISSUES, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.ExternalIssue> read = Protobuf.readStream(file, ScannerReport.ExternalIssue.parser())) { assertThat(Iterators.size(read)).isEqualTo(1); } }
init(issue); issue.setRuleKey(RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + reportIssue.getRuleRepository(), reportIssue.getRuleKey())); if (reportIssue.hasTextRange()) { int startLine = reportIssue.getTextRange().getStartLine(); issue.setLine(startLine); issue.setChecksum(lineHashSeq.getHashForLine(startLine)); issue.setChecksum(""); if (isNotEmpty(reportIssue.getMsg())) { issue.setMessage(reportIssue.getMsg()); if (reportIssue.getSeverity() != Severity.UNSET_SEVERITY) { issue.setSeverity(reportIssue.getSeverity().name()); issue.setEffort(Duration.create(reportIssue.getEffort() != 0 ? reportIssue.getEffort() : DEFAULT_EXTERNAL_ISSUE_EFFORT)); DbIssues.Locations.Builder dbLocationsBuilder = DbIssues.Locations.newBuilder(); if (reportIssue.hasTextRange()) { dbLocationsBuilder.setTextRange(convertTextRange(reportIssue.getTextRange())); for (ScannerReport.Flow flow : reportIssue.getFlowList()) { if (flow.getLocationCount() > 0) { DbIssues.Flow.Builder dbFlowBuilder = DbIssues.Flow.newBuilder(); issue.setType(toRuleType(reportIssue.getType()));
private static ScannerReport.ExternalIssue createReportExternalIssue(ExternalIssue issue, int componentRef) { // primary location of an external issue must have a message String primaryMessage = issue.primaryLocation().message(); Severity severity = Severity.valueOf(issue.severity().name()); IssueType issueType = IssueType.valueOf(issue.type().name()); ScannerReport.ExternalIssue.Builder builder = ScannerReport.ExternalIssue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setType(issueType); builder.setEngineId(issue.engineId()); builder.setRuleId(issue.ruleId()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Long effort = issue.remediationEffort(); if (effort != null) { builder.setEffort(effort); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }
public CloseableIterator<ScannerReport.ExternalIssue> readComponentExternalIssues(int componentRef) { File file = fileStructure.fileFor(FileStructure.Domain.EXTERNAL_ISSUES, componentRef); if (fileExists(file)) { return Protobuf.readStream(file, ScannerReport.ExternalIssue.parser()); } return emptyCloseableIterator(); }
init(issue); RuleKey ruleKey = RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + reportExternalIssue.getEngineId(), reportExternalIssue.getRuleId()); issue.setRuleKey(ruleKey); if (reportExternalIssue.hasTextRange()) { int startLine = reportExternalIssue.getTextRange().getStartLine(); issue.setLine(startLine); issue.setChecksum(lineHashSeq.getHashForLine(startLine)); issue.setChecksum(""); if (isNotEmpty(reportExternalIssue.getMsg())) { issue.setMessage(reportExternalIssue.getMsg()); if (reportExternalIssue.getSeverity() != Severity.UNSET_SEVERITY) { issue.setSeverity(reportExternalIssue.getSeverity().name()); issue.setEffort(Duration.create(reportExternalIssue.getEffort() != 0 ? reportExternalIssue.getEffort() : DEFAULT_EXTERNAL_ISSUE_EFFORT)); DbIssues.Locations.Builder dbLocationsBuilder = DbIssues.Locations.newBuilder(); if (reportExternalIssue.hasTextRange()) { dbLocationsBuilder.setTextRange(convertTextRange(reportExternalIssue.getTextRange())); for (ScannerReport.Flow flow : reportExternalIssue.getFlowList()) { if (flow.getLocationCount() > 0) { DbIssues.Flow.Builder dbFlowBuilder = DbIssues.Flow.newBuilder(); issue.setType(toRuleType(reportExternalIssue.getType()));
private static ScannerReport.ExternalIssue createReportExternalIssue(ExternalIssue issue, int componentRef) { // primary location of an external issue must have a message String primaryMessage = issue.primaryLocation().message(); Severity severity = Severity.valueOf(issue.severity().name()); IssueType issueType = IssueType.valueOf(issue.type().name()); ScannerReport.ExternalIssue.Builder builder = ScannerReport.ExternalIssue.newBuilder(); ScannerReport.IssueLocation.Builder locationBuilder = IssueLocation.newBuilder(); ScannerReport.TextRange.Builder textRangeBuilder = ScannerReport.TextRange.newBuilder(); // non-null fields builder.setSeverity(severity); builder.setType(issueType); builder.setEngineId(issue.engineId()); builder.setRuleId(issue.ruleId()); builder.setMsg(primaryMessage); locationBuilder.setMsg(primaryMessage); locationBuilder.setComponentRef(componentRef); TextRange primaryTextRange = issue.primaryLocation().textRange(); if (primaryTextRange != null) { builder.setTextRange(toProtobufTextRange(textRangeBuilder, primaryTextRange)); } Long effort = issue.remediationEffort(); if (effort != null) { builder.setEffort(effort); } applyFlows(builder::addFlow, locationBuilder, textRangeBuilder, issue.flows()); return builder.build(); }
@Test public void load_external_issues_from_report_with_default_effort() { when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line")); ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder() .setTextRange(TextRange.newBuilder().setStartLine(2).build()) .setMsg("the message") .setEngineId("eslint") .setRuleId("S001") .setSeverity(Constants.Severity.BLOCKER) .setType(ScannerReport.IssueType.BUG) .build(); reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); Input<DefaultIssue> input = underTest.create(FILE); Collection<DefaultIssue> issues = input.getIssues(); assertThat(issues).hasSize(1); DefaultIssue issue = Iterators.getOnlyElement(issues.iterator()); // fields set by analysis report assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001")); assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.line()).isEqualTo(2); assertThat(issue.effort()).isEqualTo(Duration.create(0l)); assertThat(issue.message()).isEqualTo("the message"); // fields set by compute engine assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); assertThat(issue.tags()).isEmpty(); assertInitializedExternalIssue(issue); }
@Test public void create_ad_hoc_rule_from_issue() { OrganizationDto organization = db.organizations().insert(); NewAdHocRule addHocRule = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()); RuleDto rule = underTest.persistAndIndex(dbSession, addHocRule, organization); assertThat(rule).isNotNull(); assertThat(rule.isExternal()).isTrue(); assertThat(rule.isAdHoc()).isTrue(); assertThat(rule.getId()).isGreaterThan(0); assertThat(rule.getKey()).isEqualTo(RuleKey.of("external_eslint", "no-cond-assign")); assertThat(rule.getName()).isEqualTo("eslint:no-cond-assign"); assertThat(rule.getDescription()).isNull(); assertThat(rule.getSeverity()).isNull(); assertThat(rule.getType()).isEqualTo(0); assertThat(rule.getMetadata().getAdHocName()).isNull(); assertThat(rule.getMetadata().getAdHocDescription()).isNull(); assertThat(rule.getMetadata().getAdHocSeverity()).isNull(); assertThat(rule.getMetadata().getAdHocType()).isNull(); }
@Test public void persist_and_index_new_ad_hoc_rules() { RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign"); ruleRepository.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build())); underTest.execute(new TestComputationStepContext()); 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("external_eslint"); assertThat(reloaded.isExternal()).isTrue(); assertThat(reloaded.isAdHoc()).isTrue(); assertThat(reloaded.getType()).isEqualTo(0); assertThat(reloaded.getSeverity()).isNull(); assertThat(reloaded.getName()).isEqualTo("eslint:no-cond-assign"); assertThat(es.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1l); assertThat(es.getDocuments(RuleIndexDefinition.INDEX_TYPE_RULE).iterator().next().getId()).isEqualTo(Integer.toString(reloaded.getId())); }
@Test public void testOneIssuePerLine() throws Exception { File projectDir = new File("test-resources/mediumtest/xoo/sample"); File tmpDir = temp.newFolder(); FileUtils.copyDirectory(projectDir, tmpDir); AnalysisResult result = tester .newAnalysis(new File(tmpDir, "sonar-project.properties")) .property(OneExternalIssuePerLineSensor.ACTIVATE, "true") .execute(); List<Issue> issues = result.issuesFor(result.inputFile("xources/hello/HelloJava.xoo")); assertThat(issues).isEmpty(); List<ExternalIssue> externalIssues = result.externalIssuesFor(result.inputFile("xources/hello/HelloJava.xoo")); assertThat(externalIssues).hasSize(8 /* lines */); ExternalIssue issue = externalIssues.get(0); assertThat(issue.getTextRange().getStartLine()).isEqualTo(issue.getTextRange().getStartLine()); assertThat(result.adHocRules()).isEmpty(); }
@Test public void test_equals_and_hashcode() { NewAdHocRule adHocRule1 = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()); NewAdHocRule adHocRule2 = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()); NewAdHocRule anotherAdHocRule = new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("another").build()); assertThat(adHocRule1).isEqualTo(adHocRule1); assertThat(adHocRule1).isEqualTo(adHocRule2); assertThat(adHocRule1).isNotEqualTo(null); assertThat(adHocRule1).isNotEqualTo(anotherAdHocRule); assertThat(adHocRule1.hashCode()).isEqualTo(adHocRule1.hashCode()); assertThat(adHocRule1.hashCode()).isEqualTo(adHocRule2.hashCode()); assertThat(adHocRule1.hashCode()).isNotEqualTo(anotherAdHocRule.hashCode()); } }
@Test public void persist_new_externally_defined_Rules() { underTest = new RuleRepositoryImpl(adHocRuleCreator, db.getDbClient(), analysisMetadataHolder); RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign"); underTest.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build())); underTest.saveOrUpdateAddHocRules(db.getSession()); db.commit(); Optional<RuleDefinitionDto> ruleDefinitionDto = db.getDbClient().ruleDao().selectDefinitionByKey(db.getSession(), ruleKey); assertThat(ruleDefinitionDto).isPresent(); Rule rule = underTest.getByKey(ruleKey); assertThat(rule).isNotNull(); assertThat(underTest.getById(ruleDefinitionDto.get().getId())).isNotNull(); verify(ruleIndexer).commitAndIndex(db.getSession(), ruleDefinitionDto.get().getId()); }
@Test public void add_external_issue_to_cache() { ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME); initModuleIssues(); DefaultExternalIssue issue = new DefaultExternalIssue(project) .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo")) .type(RuleType.BUG) .forRule(SQUID_RULE_KEY) .severity(org.sonar.api.batch.rule.Severity.CRITICAL); moduleIssues.initAndAddExternalIssue(issue); ArgumentCaptor<ScannerReport.ExternalIssue> argument = ArgumentCaptor.forClass(ScannerReport.ExternalIssue.class); verify(reportPublisher.getWriter()).appendComponentExternalIssue(eq(file.scannerId()), argument.capture()); assertThat(argument.getValue().getSeverity()).isEqualTo(org.sonar.scanner.protocol.Constants.Severity.CRITICAL); }
@Test public void accept_new_externally_defined_Rules() { RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign"); underTest.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build())); assertThat(underTest.getByKey(ruleKey)).isNotNull(); assertThat(underTest.getByKey(ruleKey).getType()).isNull(); RuleDao ruleDao = dbClient.ruleDao(); Optional<RuleDefinitionDto> ruleDefinitionDto = ruleDao.selectDefinitionByKey(dbClient.openSession(false), ruleKey); assertThat(ruleDefinitionDto).isNotPresent(); }
@Test public void read_external_issues() { ScannerReportWriter writer = new ScannerReportWriter(dir); ScannerReport.ExternalIssue issue = ScannerReport.ExternalIssue.newBuilder() .build(); writer.appendComponentExternalIssue(1, issue); assertThat(underTest.readComponentExternalIssues(1)).hasSize(1); assertThat(underTest.readComponentExternalIssues(200)).isEmpty(); }
public NewAdHocRule(ScannerReport.ExternalIssue fromIssue) { Preconditions.checkArgument(isNotBlank(fromIssue.getEngineId()), "'engine id' not expected to be null for an ad hoc rule"); Preconditions.checkArgument(isNotBlank(fromIssue.getRuleId()), "'rule id' not expected to be null for an ad hoc rule"); this.key = RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + fromIssue.getEngineId(), fromIssue.getRuleId()); this.engineId = fromIssue.getEngineId(); this.ruleId = fromIssue.getRuleId(); this.name = null; this.description = null; this.severity = null; this.ruleType = null; this.hasDetails = false; }
public CloseableIterator<ScannerReport.ExternalIssue> readComponentExternalIssues(int componentRef) { File file = fileStructure.fileFor(FileStructure.Domain.EXTERNAL_ISSUES, componentRef); if (fileExists(file)) { return Protobuf.readStream(file, ScannerReport.ExternalIssue.parser()); } return emptyCloseableIterator(); }
@Test public void fail_if_engine_id_is_not_set() { exception.expect(IllegalArgumentException.class); exception.expectMessage("'engine id' not expected to be null for an ad hoc rule"); new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().build()); }