3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.computation.task.projectanalysis.issue;
22 import java.util.Arrays;
23 import java.util.Date;
24 import java.util.List;
25 import javax.annotation.Nullable;
26 import org.junit.Test;
27 import org.sonar.api.utils.Duration;
28 import org.sonar.core.issue.DefaultIssue;
29 import org.sonar.core.issue.FieldDiffs;
30 import org.sonar.db.issue.IssueChangeDto;
31 import org.sonar.server.computation.task.projectanalysis.period.Period;
33 import static java.util.Collections.emptyList;
34 import static org.assertj.core.api.Assertions.assertThat;
35 import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_VERSION;
37 public class NewEffortCalculatorTest {
39 private static final int HOURS_IN_DAY = 8;
40 private static final Duration ONE_DAY = Duration.create(HOURS_IN_DAY * 60 * 60L);
41 private static final Duration TWO_DAYS = Duration.create(2 * HOURS_IN_DAY * 60 * 60L);
42 private static final Duration FOUR_DAYS = Duration.create(4 * HOURS_IN_DAY * 60 * 60L);
43 private static final Duration FIVE_DAYS = Duration.create(5 * HOURS_IN_DAY * 60 * 60L);
44 private static final Duration TEN_DAYS = Duration.create(10 * HOURS_IN_DAY * 60 * 60L);
45 private static final long PERIOD_DATE = 150000000L;
46 private static final String ANALYSIS_UUID = "u1";
47 private static final Period PERIOD = new Period(1, TIMEMACHINE_MODE_PREVIOUS_VERSION, null, PERIOD_DATE, ANALYSIS_UUID);
49 DefaultIssue issue = new DefaultIssue();
50 NewEffortCalculator underTest = new NewEffortCalculator();
53 * New debt is the value of the debt when issue is created during the period
56 public void total_debt_if_issue_created_during_period() {
57 issue.setEffort(TWO_DAYS).setCreationDate(new Date(PERIOD_DATE + 10000));
59 long newDebt = underTest.calculate(issue, emptyList(), PERIOD);
61 assertThat(newDebt).isEqualTo(TWO_DAYS.toMinutes());
65 public void new_debt_if_issue_created_before_period() {
67 // before period: increased to 2d
68 // after period: increased to 5d, decreased to 4d then increased to 10d
69 // -> new debt is 10d - 2d = 8d
70 issue.setEffort(TEN_DAYS).setCreationDate(new Date(PERIOD_DATE - 10000));
71 List<IssueChangeDto> changelog = Arrays.asList(
72 newDebtChangelog(ONE_DAY.toMinutes(), TWO_DAYS.toMinutes(), PERIOD_DATE - 9000),
73 newDebtChangelog(TWO_DAYS.toMinutes(), FIVE_DAYS.toMinutes(), PERIOD_DATE + 10000),
74 newDebtChangelog(FIVE_DAYS.toMinutes(), FOUR_DAYS.toMinutes(), PERIOD_DATE + 20000),
75 newDebtChangelog(FOUR_DAYS.toMinutes(), TEN_DAYS.toMinutes(), PERIOD_DATE + 30000)
78 long newDebt = underTest.calculate(issue, changelog, PERIOD);
80 assertThat(newDebt).isEqualTo(TEN_DAYS.toMinutes() - TWO_DAYS.toMinutes());
84 public void new_debt_is_positive() {
86 // before period: increased to 10d
87 // after period: decreased to 2d
88 // -> new debt is 2d - 10d = -8d -> 0d
89 issue.setEffort(TWO_DAYS).setCreationDate(new Date(PERIOD_DATE - 10000));
90 List<IssueChangeDto> changelog = Arrays.asList(
91 newDebtChangelog(ONE_DAY.toMinutes(), TEN_DAYS.toMinutes(), PERIOD_DATE - 9000),
92 newDebtChangelog(TEN_DAYS.toMinutes(), TWO_DAYS.toMinutes(), PERIOD_DATE + 30000)
95 long newDebt = underTest.calculate(issue, changelog, PERIOD);
97 assertThat(newDebt).isEqualTo(0L);
101 public void guess_initial_debt_when_first_change_is_after_period() {
103 // after period: increased to 2d, then to 5d
104 // -> new debt is 5d - 1d = 4d
105 issue.setEffort(FIVE_DAYS).setCreationDate(new Date(PERIOD_DATE - 10000));
106 List<IssueChangeDto> changelog = Arrays.asList(
107 newDebtChangelog(ONE_DAY.toMinutes(), TWO_DAYS.toMinutes(), PERIOD_DATE + 20000),
108 newDebtChangelog(TWO_DAYS.toMinutes(), FIVE_DAYS.toMinutes(), PERIOD_DATE + 30000)
111 long newDebt = underTest.calculate(issue, changelog, PERIOD);
113 assertThat(newDebt).isEqualTo(FIVE_DAYS.toMinutes() - ONE_DAY.toMinutes());
117 private static IssueChangeDto newDebtChangelog(long previousValue, long value, @Nullable Long date) {
118 FieldDiffs diffs = new FieldDiffs().setDiff("technicalDebt", previousValue, value);
120 diffs.setCreationDate(new Date(date));
122 return new IssueChangeDto().setIssueChangeCreationDate(date).setChangeData(diffs.toString());