public boolean setPastEffort(DefaultIssue issue, @Nullable Duration previousEffort, IssueChangeContext context) { Duration currentEffort = issue.effort(); issue.setEffort(previousEffort); return setEffort(issue, currentEffort, context); }
private void assertInitializedIssue(DefaultIssue issue) { assertThat(issue.projectKey()).isEqualTo(PROJECT.getKey()); assertThat(issue.componentKey()).isEqualTo(FILE.getKey()); 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(); assertThat(issue.effort()).isNull(); assertThat(issue.effortInMinutes()).isNull(); }
public boolean setEffort(DefaultIssue issue, @Nullable Duration value, IssueChangeContext context) { Duration oldValue = issue.effort(); if (!Objects.equals(value, oldValue)) { issue.setEffort(value); issue.setFieldChange(context, TECHNICAL_DEBT, oldValue != null ? oldValue.toMinutes() : null, value != null ? value.toMinutes() : null); issue.setUpdateDate(context.date()); issue.setChanged(true); return true; } return false; }
public void add(DefaultIssue issue) { boolean isOnLeak = onLeakPredicate.test(issue); distributions.get(RULE_TYPE).increment(issue.type().name(), isOnLeak); String componentUuid = issue.componentUuid(); if (componentUuid != null) { distributions.get(COMPONENT).increment(componentUuid, isOnLeak); } RuleKey ruleKey = issue.ruleKey(); if (ruleKey != null) { distributions.get(RULE).increment(ruleKey.toString(), isOnLeak); } String assigneeUuid = issue.assignee(); if (assigneeUuid != null) { distributions.get(ASSIGNEE).increment(assigneeUuid, isOnLeak); } for (String tag : issue.tags()) { distributions.get(TAG).increment(tag, isOnLeak); } Duration effort = issue.effort(); if (effort != null) { effortStats.add(effort.toMinutes(), isOnLeak); } }
@Test public void set_past_technical_debt_without_previous_value() { Duration newDebt = Duration.create(15 * 8 * 60); issue.setEffort(newDebt); boolean updated = underTest.setPastEffort(issue, null, context); assertThat(updated).isTrue(); assertThat(issue.effort()).isEqualTo(newDebt); assertThat(issue.mustSendNotifications()).isFalse(); FieldDiffs.Diff diff = issue.currentChange().get(TECHNICAL_DEBT); assertThat(diff.oldValue()).isNull(); assertThat(diff.newValue()).isEqualTo(15L * 8 * 60); }
@Test public void set_past_technical_debt() { Duration newDebt = Duration.create(15 * 8 * 60); Duration previousDebt = Duration.create(10 * 8 * 60); issue.setEffort(newDebt); boolean updated = underTest.setPastEffort(issue, previousDebt, context); assertThat(updated).isTrue(); assertThat(issue.effort()).isEqualTo(newDebt); assertThat(issue.mustSendNotifications()).isFalse(); FieldDiffs.Diff diff = issue.currentChange().get(TECHNICAL_DEBT); assertThat(diff.oldValue()).isEqualTo(10L * 8 * 60); assertThat(diff.newValue()).isEqualTo(15L * 8 * 60); }
@Test public void set_past_technical_debt_with_null_new_value() { issue.setEffort(null); Duration previousDebt = Duration.create(10 * 8 * 60); boolean updated = underTest.setPastEffort(issue, previousDebt, context); assertThat(updated).isTrue(); assertThat(issue.effort()).isNull(); assertThat(issue.mustSendNotifications()).isFalse(); FieldDiffs.Diff diff = issue.currentChange().get(TECHNICAL_DEBT); assertThat(diff.oldValue()).isEqualTo(10L * 8 * 60); assertThat(diff.newValue()).isNull(); }
@Test public void initNewOpenIssue() { DefaultIssue issue = new DefaultIssue() .setRuleKey(XOO_X1); when(debtCalculator.calculate(issue)).thenReturn(DEFAULT_DURATION); underTest.initNewOpenIssue(issue); assertThat(issue.key()).isNotNull(); assertThat(issue.creationDate()).isNotNull(); assertThat(issue.updateDate()).isNotNull(); assertThat(issue.status()).isEqualTo(STATUS_OPEN); assertThat(issue.effort()).isEqualTo(DEFAULT_DURATION); assertThat(issue.isNew()).isTrue(); assertThat(issue.isCopied()).isFalse(); assertThat(issue.isFromHotspot()).isFalse(); }
@Test public void initNewOpenHotspot() { rule.setType(RuleType.SECURITY_HOTSPOT); DefaultIssue issue = new DefaultIssue() .setRuleKey(XOO_X1); when(debtCalculator.calculate(issue)).thenReturn(DEFAULT_DURATION); underTest.initNewOpenIssue(issue); assertThat(issue.key()).isNotNull(); assertThat(issue.creationDate()).isNotNull(); assertThat(issue.updateDate()).isNotNull(); assertThat(issue.status()).isEqualTo(STATUS_OPEN); assertThat(issue.effort()).isEqualTo(DEFAULT_DURATION); assertThat(issue.isNew()).isTrue(); assertThat(issue.isCopied()).isFalse(); assertThat(issue.isFromHotspot()).isTrue(); }
@CheckForNull public Duration calculate(DefaultIssue issue) { if (issue.isFromExternalRuleEngine()) { return issue.effort(); } Rule rule = ruleRepository.getByKey(issue.ruleKey()); DebtRemediationFunction fn = rule.getRemediationFunction(); if (fn != null) { verifyEffortToFix(issue, fn); Duration debt = Duration.create(0); String gapMultiplier = fn.gapMultiplier(); if (fn.type().usesGapMultiplier() && !Strings.isNullOrEmpty(gapMultiplier)) { int effortToFixValue = MoreObjects.firstNonNull(issue.gap(), 1).intValue(); // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling debt = durations.decode(gapMultiplier).multiply(effortToFixValue); } String baseEffort = fn.baseEffort(); if (fn.type().usesBaseEffort() && !Strings.isNullOrEmpty(baseEffort)) { // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling debt = debt.add(durations.decode(baseEffort)); } return debt; } return null; }
assertThat(issue.line()).isEqualTo(7); assertThat(issue.gap()).isEqualTo(1.2d); assertThat(issue.effort()).isEqualTo(Duration.create(28800L)); assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED); assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
@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 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.tags()).isEmpty(); assertInitializedIssue(issue); assertThat(issue.effort()).isNull();
assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE); assertThat(issue.gap()).isEqualTo(15.0); assertThat(issue.effort()).isEqualTo(Duration.create(10L)); assertThat(issue.line()).isEqualTo(6); assertThat(issue.severity()).isEqualTo("BLOCKER");
assertThat(raw.authorLogin()).isEqualTo("base author"); assertThat(raw.tags()).containsOnly("base tag"); assertThat(raw.effort()).isEqualTo(DEFAULT_DURATION); assertThat(raw.isOnDisabledRule()).isTrue(); assertThat(raw.selectedAt()).isEqualTo(1000L);
assertThat(raw.authorLogin()).isEqualTo("base author"); assertThat(raw.tags()).containsOnly("base tag"); assertThat(raw.effort()).isEqualTo(DEFAULT_DURATION); assertThat(raw.selectedAt()).isEqualTo(1000L); assertThat(raw.isFromHotspot()).isTrue();
assertThat(raw.authorLogin()).isEqualTo("base author"); assertThat(raw.tags()).containsOnly("base tag"); assertThat(raw.effort()).isEqualTo(DEFAULT_DURATION); assertThat(raw.isOnDisabledRule()).isTrue(); assertThat(raw.selectedAt()).isEqualTo(1000L);
updater.setPastMessage(raw, base.getMessage(), changeContext); updater.setPastGap(raw, base.gap(), changeContext); updater.setPastEffort(raw, base.effort(), changeContext);
public boolean setPastEffort(DefaultIssue issue, @Nullable Duration previousEffort, IssueChangeContext context) { Duration currentEffort = issue.effort(); issue.setEffort(previousEffort); return setEffort(issue, currentEffort, context); }