]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4996 Measure on added debt are now in seconds
authorJulien Lancelot <julien.lancelot@gmail.com>
Fri, 21 Feb 2014 16:55:39 +0000 (17:55 +0100)
committerJulien Lancelot <julien.lancelot@gmail.com>
Tue, 25 Feb 2014 18:01:33 +0000 (19:01 +0100)
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/NewTechnicalDebtDecorator.java
plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/issues/issues.html.erb
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/technicaldebt/NewTechnicalDebtDecoratorTest.java
sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java
sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java

index 9433d65c48d740ac0360b4c1c17f51fe2ff31d30..baa0c203cd4cea6b5eb83f26986470dab36ecd3b 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.api.measures.MeasureUtils;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.WorkDuration;
 import org.sonar.batch.components.Period;
 import org.sonar.batch.components.TimeMachineConfiguration;
 import org.sonar.batch.debt.IssueChangelogDebtCalculator;
@@ -91,15 +90,15 @@ public final class NewTechnicalDebtDecorator implements Decorator {
     context.saveMeasure(measure);
   }
 
-  private Double calculateNewTechnicalDebtValue(Collection<Issue> issues, @Nullable Date periodDate) {
-    WorkDuration duration = null;
+  private long calculateNewTechnicalDebtValue(Collection<Issue> issues, @Nullable Date periodDate) {
+    long result = 0;
     for (Issue issue : issues) {
-      WorkDuration debt = issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, periodDate);
+      Long debt = issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, periodDate);
       if (debt != null) {
-        duration = duration != null ? duration.add(debt) : debt;
+        result += debt;
       }
     }
-    return duration != null ? duration.toWorkingDays() : 0d;
+    return result;
   }
 
   private boolean shouldSaveNewMetrics(DecoratorContext context) {
index 82c5a402303ed97de194ecfb02c2aa096cd4a73a..e02b1564ac29eeeba6d51171ea12d0d9d5cb72e1 100644 (file)
@@ -56,7 +56,7 @@
                if @dashboard_configuration.selected_period?
                  technical_debt_variation = variation_value(technical_debt)
                  new_technical_debt_variation = variation_value(new_technical_debt)
-                 estimated_cleared_technical_debt = (new_technical_debt_variation - technical_debt_variation).to_f if technical_debt_variation && new_technical_debt_variation
+                 estimated_cleared_technical_debt = (new_technical_debt_variation - technical_debt_variation).to_i if technical_debt_variation && new_technical_debt_variation
             %>
               <% if new_technical_debt_variation && new_technical_debt_variation > 0 %>
                 <br/>
@@ -70,7 +70,7 @@
                 <br/>
                 <span style="font-weight: bold">
                   <%= message('widget.rules.removed') -%>&nbsp;
-                  <span class="varb"><%= number_with_precision(estimated_cleared_technical_debt, :precision => 1) -%></span>
+                  <span class="varb"><%= Internal.work_duration_formatter.abbreviation(estimated_cleared_technical_debt) -%></span>
                 </span>
               <% end %>
             <% end %>
index c3d8625b24d6d2cf242d53c0a88da67c0e9d000d..7f75ac85a349cefceb9711ec493a822d51171b35 100644 (file)
@@ -79,9 +79,9 @@ public class NewTechnicalDebtDecoratorTest {
 
   private static final int HOURS_IN_DAY = 8;
 
-  long oneDay = 1 * HOURS_IN_DAY * 60 * 60L;
-  long twoDays = 2 * HOURS_IN_DAY * 60 * 60L;
-  long fiveDays = 5 * HOURS_IN_DAY * 60 * 60L;
+  Long oneDay = 1 * HOURS_IN_DAY * 60 * 60L;
+  Long twoDays = 2 * HOURS_IN_DAY * 60 * 60L;
+  Long fiveDays = 5 * HOURS_IN_DAY * 60 * 60L;
 
   @Before
   public void setup() {
@@ -101,7 +101,7 @@ public class NewTechnicalDebtDecoratorTest {
     when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, fiveDaysAgo), new Period(2, tenDaysAgo)));
 
     WorkDurationFactory workDurationFactory = new WorkDurationFactory(settings);
-    decorator = new NewTechnicalDebtDecorator(perspectives, timeMachineConfiguration, new IssueChangelogDebtCalculator(workDurationFactory));
+    decorator = new NewTechnicalDebtDecorator(perspectives, timeMachineConfiguration, new IssueChangelogDebtCalculator());
   }
 
   @Test
@@ -127,7 +127,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 1.0, 1.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 1.0 * oneDay, 1.0 * oneDay)));
   }
 
   @Test
@@ -143,7 +143,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0, 4.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * oneDay, 4.0 * oneDay)));
   }
 
   @Test
@@ -176,7 +176,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0, 5.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * oneDay, 5.0 * oneDay)));
   }
 
   @Test
@@ -195,7 +195,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0, 5.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * oneDay, 5.0 * oneDay)));
   }
 
   @Test
@@ -212,7 +212,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0, 4.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * oneDay, 4.0 * oneDay)));
   }
 
   @Test
@@ -235,7 +235,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0, 7.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * oneDay, 7.0 * oneDay)));
   }
 
   @Test
@@ -247,7 +247,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 5.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 5.0 * oneDay)));
   }
 
   @Test
@@ -273,7 +273,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is null, period2 is null
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0, 5.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * oneDay, 5.0 * oneDay)));
   }
 
   @Test
@@ -286,7 +286,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 7.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 7.0 * oneDay)));
   }
 
   @Test
@@ -314,7 +314,7 @@ public class NewTechnicalDebtDecoratorTest {
     decorator.decorate(resource, context);
 
     // remember : period1 is 5daysAgo, period2 is 10daysAgo
-    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0, 14.0)));
+    verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * oneDay, 14.0 * oneDay)));
   }
 
   @Test
index cba4b32807d9c27d77d46ed724be27a0c0b18009..276671185f0831f69c04383955240d45ee52ddc9 100644 (file)
@@ -27,8 +27,6 @@ import org.sonar.api.BatchComponent;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.FieldDiffs;
-import org.sonar.api.utils.WorkDuration;
-import org.sonar.api.utils.WorkDurationFactory;
 import org.sonar.core.issue.IssueUpdater;
 
 import javax.annotation.CheckForNull;
@@ -39,39 +37,30 @@ import static com.google.common.collect.Lists.newArrayList;
 
 public class IssueChangelogDebtCalculator implements BatchComponent {
 
-  private final WorkDurationFactory workDurationFactory;
-
-  public IssueChangelogDebtCalculator(WorkDurationFactory workDurationFactory) {
-    this.workDurationFactory = workDurationFactory;
-  }
-
   @CheckForNull
-  public WorkDuration calculateNewTechnicalDebt(Issue issue, @Nullable Date periodDate) {
+  public Long calculateNewTechnicalDebt(Issue issue, @Nullable Date periodDate) {
     Long debt = ((DefaultIssue) issue).debt();
-    WorkDuration currentTechnicalDebt = debt != null ? workDurationFactory.createFromSeconds(debt) : null;
     Date periodDatePlusOneSecond = periodDate != null ? DateUtils.addSeconds(periodDate, 1) : null;
     if (isAfter(issue.creationDate(), periodDatePlusOneSecond)) {
-      return currentTechnicalDebt;
+      return debt;
     } else {
-      return calculateNewTechnicalDebtValueFromChangelog(currentTechnicalDebt, issue, periodDate);
+      return calculateNewTechnicalDebtValueFromChangelog(debt, issue, periodDate);
     }
   }
 
   @CheckForNull
-  private WorkDuration calculateNewTechnicalDebtValueFromChangelog(@Nullable WorkDuration currentTechnicalDebtValue, Issue issue, Date periodDate) {
+  private Long calculateNewTechnicalDebtValueFromChangelog(@Nullable Long currentTechnicalDebtValue, Issue issue, Date periodDate) {
     List<FieldDiffs> changelog = technicalDebtHistory(issue);
     for (Iterator<FieldDiffs> iterator = changelog.iterator(); iterator.hasNext(); ) {
       FieldDiffs diff = iterator.next();
       Date date = diff.creationDate();
-      WorkDuration newValue = newValue(diff);
-      WorkDuration oldValue = oldValue(diff);
       if (isLesserOrEqual(date, periodDate)) {
         // return new value from the change that is just before the period date
-        return subtractNeverNegative(currentTechnicalDebtValue, newValue);
+        return subtractNeverNegative(currentTechnicalDebtValue, newValue(diff));
       }
       if (!iterator.hasNext()) {
         // return old value from the change that is just after the period date when there's no more element in changelog
-        return subtractNeverNegative(currentTechnicalDebtValue, oldValue);
+        return subtractNeverNegative(currentTechnicalDebtValue, oldValue(diff));
       }
     }
     // Return null when no changelog
@@ -82,14 +71,9 @@ public class IssueChangelogDebtCalculator implements BatchComponent {
    * SONAR-5059
    */
   @CheckForNull
-  private WorkDuration subtractNeverNegative(@Nullable WorkDuration workDuration, WorkDuration toSubtractWith) {
-    if (workDuration != null) {
-      WorkDuration result = workDuration.subtract(toSubtractWith);
-      if (result.toSeconds() > 0) {
-        return result;
-      }
-    }
-    return null;
+  private Long subtractNeverNegative(@Nullable Long value, Long with) {
+    Long result = (value != null ? value : 0) - (with != null ? with : 0);
+    return result > 0 ? result : null;
   }
 
   private List<FieldDiffs> technicalDebtHistory(Issue issue) {
@@ -118,26 +102,20 @@ public class IssueChangelogDebtCalculator implements BatchComponent {
   }
 
   @CheckForNull
-  private WorkDuration newValue(FieldDiffs fieldDiffs) {
+  private Long newValue(FieldDiffs fieldDiffs) {
     for (Map.Entry<String, FieldDiffs.Diff> entry : fieldDiffs.diffs().entrySet()) {
       if (entry.getKey().equals(IssueUpdater.TECHNICAL_DEBT)) {
-        Long newValue = entry.getValue().newValueLong();
-        if (newValue != null) {
-          return workDurationFactory.createFromSeconds(newValue);
-        }
+        return entry.getValue().newValueLong();
       }
     }
     return null;
   }
 
   @CheckForNull
-  private WorkDuration oldValue(FieldDiffs fieldDiffs) {
+  private Long oldValue(FieldDiffs fieldDiffs) {
     for (Map.Entry<String, FieldDiffs.Diff> entry : fieldDiffs.diffs().entrySet()) {
       if (entry.getKey().equals(IssueUpdater.TECHNICAL_DEBT)) {
-        Long value = entry.getValue().oldValueLong();
-        if (value != null) {
-          return workDurationFactory.createFromSeconds(value);
-        }
+        return entry.getValue().oldValueLong();
       }
     }
     return null;
index 5096952aa850ae1f1315f06293e1f9d13b72abba..479b8e2f888b1737c75d8fc6a11c86fd3aab19d8 100644 (file)
@@ -28,8 +28,6 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.FieldDiffs;
-import org.sonar.api.utils.WorkDuration;
-import org.sonar.api.utils.WorkDurationFactory;
 
 import java.util.Date;
 
@@ -58,7 +56,7 @@ public class IssueChangelogDebtCalculatorTest {
     Settings settings = new Settings();
     settings.setProperty(CoreProperties.HOURS_IN_DAY, Integer.toString(HOURS_IN_DAY));
 
-    issueChangelogDebtCalculator = new IssueChangelogDebtCalculator(new WorkDurationFactory(settings));
+    issueChangelogDebtCalculator = new IssueChangelogDebtCalculator();
   }
 
   @Test
@@ -70,13 +68,10 @@ public class IssueChangelogDebtCalculatorTest {
       )
     );
 
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(1, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(1, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(oneDay);
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(oneDay);
 
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(2, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(twoDays);
   }
 
   @Test
@@ -88,12 +83,9 @@ public class IssueChangelogDebtCalculatorTest {
       )
     );
 
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(3, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(4, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(5, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(3 * oneDay);
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(4 * oneDay);
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(5 * oneDay);
   }
 
   @Test
@@ -109,10 +101,8 @@ public class IssueChangelogDebtCalculatorTest {
       )
     );
 
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(4, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(5, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(4 * oneDay);
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(5 * oneDay);
   }
 
   @Test
@@ -123,8 +113,7 @@ public class IssueChangelogDebtCalculatorTest {
       )
     );
 
-    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, null)).isEqualTo(
-      WorkDuration.createFromValueAndUnit(2, WorkDuration.UNIT.DAYS, HOURS_IN_DAY));
+    assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, null)).isEqualTo(2 * oneDay);
   }
 
   @Test
index 4693a229fb21693c5b1be4bbbde85445969f36ec..6c2d95c5413c0efe704fa2c34193015e1fe042f8 100644 (file)
@@ -2146,7 +2146,7 @@ public final class CoreMetrics {
   /**
    * @since 4.1
    */
-  public static final Metric NEW_TECHNICAL_DEBT = new Metric.Builder(NEW_TECHNICAL_DEBT_KEY, "Technical Debt on new code", Metric.ValueType.FLOAT)
+  public static final Metric NEW_TECHNICAL_DEBT = new Metric.Builder(NEW_TECHNICAL_DEBT_KEY, "Technical Debt on new code", Metric.ValueType.WORK_DUR)
     .setDescription("Technical Debt of new code")
     .setDomain(DOMAIN_TECHNICAL_DEBT)
     .setDirection(Metric.DIRECTION_WORST)