]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5189 Reintroduce check for duplicate measures
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 24 Apr 2014 14:30:26 +0000 (16:30 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 24 Apr 2014 14:30:26 +0000 (16:30 +0200)
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TendencyDecoratorTest.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateVerifier.java
sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java
sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateVerifierTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java

index c824537cecea47a21d5c8128ca73ef77794774f4..1e20c12f99431be39311d9418c6480a2f5b7707c 100644 (file)
@@ -24,7 +24,13 @@ import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.batch.*;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.TimeMachine;
+import org.sonar.api.batch.TimeMachineQuery;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.MetricFinder;
@@ -32,6 +38,7 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.Scopes;
 import org.sonar.batch.components.PeriodsDefinition;
+import org.sonar.batch.index.DefaultIndex;
 import org.sonar.core.DryRunIncompatible;
 
 import java.util.List;
@@ -46,9 +53,11 @@ public class TendencyDecorator implements Decorator {
   private TimeMachineQuery query;
   private TendencyAnalyser analyser;
   private List<Metric> metrics;
+  private final DefaultIndex index;
 
-  public TendencyDecorator(TimeMachine timeMachine, MetricFinder metricFinder) {
+  public TendencyDecorator(TimeMachine timeMachine, MetricFinder metricFinder, DefaultIndex index) {
     this.timeMachine = timeMachine;
+    this.index = index;
     this.analyser = new TendencyAnalyser();
     this.metrics = Lists.newLinkedList();
     for (Metric metric : metricFinder.findAll()) {
@@ -58,10 +67,11 @@ public class TendencyDecorator implements Decorator {
     }
   }
 
-  TendencyDecorator(TimeMachine timeMachine, TimeMachineQuery query, TendencyAnalyser analyser) {
+  TendencyDecorator(TimeMachine timeMachine, TimeMachineQuery query, TendencyAnalyser analyser, DefaultIndex index) {
     this.timeMachine = timeMachine;
     this.query = query;
     this.analyser = analyser;
+    this.index = index;
   }
 
   @DependsUpon
@@ -108,7 +118,7 @@ public class TendencyDecorator implements Decorator {
           values.add(measure.getValue());
 
           measure.setTendency(analyser.analyseLevel(valuesPerMetric.get(metric)));
-          context.saveMeasure(measure);
+          index.updateMeasure(resource, measure);
         }
       }
     }
index 8713c66537b226a8555c62cd984100d5cf60f61e..a60dfbb5e9e2f76621ddc3cd3e69b0ddd5acdb26 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.resources.Directory;
 import org.sonar.api.resources.Project;
+import org.sonar.batch.index.DefaultIndex;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -53,7 +54,7 @@ public class TendencyDecoratorTest {
     MetricFinder metricFinder = mock(MetricFinder.class);
     when(metricFinder.findAll()).thenReturn(Arrays.asList(CoreMetrics.LINES, CoreMetrics.COVERAGE, CoreMetrics.COVERAGE_LINE_HITS_DATA, CoreMetrics.PROFILE));
 
-    TendencyDecorator decorator = new TendencyDecorator(null, metricFinder);
+    TendencyDecorator decorator = new TendencyDecorator(null, metricFinder, mock(DefaultIndex.class));
 
     TimeMachineQuery query = decorator.initQuery(project);
     assertThat(query.getMetrics().size(), is(2));
@@ -80,7 +81,7 @@ public class TendencyDecoratorTest {
     when(context.getMeasure(CoreMetrics.LINES)).thenReturn(new Measure(CoreMetrics.LINES, 1400.0));
     when(context.getMeasure(CoreMetrics.COVERAGE)).thenReturn(new Measure(CoreMetrics.LINES, 90.0));
 
-    TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser);
+    TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser, mock(DefaultIndex.class));
     decorator.decorate(new Directory("org/foo"), context);
 
     verify(analyser).analyseLevel(Arrays.asList(1200.0, 1300.0, 1150.0, 1400.0));
@@ -99,7 +100,7 @@ public class TendencyDecoratorTest {
       ));
 
     DecoratorContext context = mock(DecoratorContext.class);
-    TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser);
+    TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser, mock(DefaultIndex.class));
     decorator.decorate(new Directory("org/foo"), context);
 
     verify(analyser, never()).analyseLevel(anyList());
index 5a9c3148b238aaed7f2442f4a5886ff307a82862..6fc4c72eeb6741773652f319fb884b0c9cdd95b3 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.batch.SonarIndex;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.design.Dependency;
+import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MeasuresFilter;
 import org.sonar.api.measures.MeasuresFilters;
@@ -188,9 +189,6 @@ public class DefaultIndex extends SonarIndex {
     return filter.filter(unfiltered);
   }
 
-  /**
-   * the measure is updated if it's already registered.
-   */
   @Override
   public Measure addMeasure(Resource resource, Measure measure) {
     Bucket bucket = getBucket(resource);
@@ -200,11 +198,26 @@ public class DefaultIndex extends SonarIndex {
         throw new SonarException("Unknown metric: " + measure.getMetricKey());
       }
       measure.setMetric(metric);
+      if (measureCache.contains(resource, measure)
+        // Hack for SONAR-5212
+        && !measure.getMetric().equals(CoreMetrics.TESTS)) {
+        throw new SonarException("Can not add twice the same measure on " + resource + ": " + measure);
+      }
       measureCache.put(resource, measure);
     }
     return measure;
   }
 
+  /**
+   * Used by some core features like TendencyDecorator, QualityGateVerifier that need to update some existing measures
+   */
+  public void updateMeasure(Resource resource, Measure measure) {
+    if (!measureCache.contains(resource, measure)) {
+      throw new SonarException("Can't update measure on " + resource + ": " + measure);
+    }
+    measureCache.put(resource, measure);
+  }
+
   //
   //
   //
index 28dacfe99237ee072642f9ebb794c44e01285c2c..a0cc9b3e1507ba42e686cd0bae7a91760cd57d49 100644 (file)
@@ -23,7 +23,11 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.*;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DecoratorBarriers;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.measures.CoreMetrics;
@@ -34,10 +38,15 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.ResourceUtils;
 import org.sonar.api.utils.Duration;
 import org.sonar.api.utils.Durations;
+import org.sonar.batch.index.DefaultIndex;
 import org.sonar.core.qualitygate.db.QualityGateConditionDto;
 import org.sonar.core.timemachine.Periods;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 
 public class QualityGateVerifier implements Decorator {
 
@@ -55,13 +64,15 @@ public class QualityGateVerifier implements Decorator {
   private Periods periods;
   private I18n i18n;
   private Durations durations;
+  private final DefaultIndex index;
 
-  public QualityGateVerifier(QualityGate qualityGate, Snapshot snapshot, Periods periods, I18n i18n, Durations durations) {
+  public QualityGateVerifier(QualityGate qualityGate, Snapshot snapshot, Periods periods, I18n i18n, Durations durations, DefaultIndex index) {
     this.qualityGate = qualityGate;
     this.snapshot = snapshot;
     this.periods = periods;
     this.i18n = i18n;
     this.durations = durations;
+    this.index = index;
   }
 
   @DependedUpon
@@ -77,7 +88,7 @@ public class QualityGateVerifier implements Decorator {
   @DependsUpon
   public Collection<Metric> dependsUponMetrics() {
     Set<Metric> metrics = Sets.newHashSet();
-    for (ResolvedCondition condition: qualityGate.conditions()) {
+    for (ResolvedCondition condition : qualityGate.conditions()) {
       metrics.add(condition.metric());
     }
     return metrics;
@@ -91,15 +102,15 @@ public class QualityGateVerifier implements Decorator {
   @Override
   public void decorate(Resource resource, DecoratorContext context) {
     if (ResourceUtils.isRootProject(resource)) {
-      checkProjectConditions(context);
+      checkProjectConditions(resource, context);
     }
   }
 
-  private void checkProjectConditions(DecoratorContext context) {
+  private void checkProjectConditions(Resource resource, DecoratorContext context) {
     Metric.Level globalLevel = Metric.Level.OK;
     List<String> labels = Lists.newArrayList();
 
-    for (ResolvedCondition condition: qualityGate.conditions()) {
+    for (ResolvedCondition condition : qualityGate.conditions()) {
       Measure measure = context.getMeasure(condition.metric());
       if (measure != null) {
         Metric.Level level = ConditionUtils.getLevel(condition, measure);
@@ -114,7 +125,7 @@ public class QualityGateVerifier implements Decorator {
           labels.add(text);
         }
 
-        context.saveMeasure(measure);
+        index.updateMeasure(resource, measure);
 
         if (Metric.Level.WARN == level && globalLevel != Metric.Level.ERROR) {
           globalLevel = Metric.Level.WARN;
index 5068a4734be5a870e24664c632831a4130a84eb5..b29b6c83ee0ce4e27af01e4e53a65242b79fa0ab 100644 (file)
@@ -54,6 +54,12 @@ public class MeasureCache implements BatchComponent {
     return this;
   }
 
+  public boolean contains(Resource resource, Measure measure) {
+    Preconditions.checkNotNull(resource.getEffectiveKey());
+    Preconditions.checkNotNull(measure.getMetricKey());
+    return cache.containsKey(resource.getEffectiveKey(), computeMeasureKey(measure));
+  }
+
   private static String computeMeasureKey(Measure m) {
     StringBuilder sb = new StringBuilder();
     if (m.getMetricKey() != null) {
index 1a4be071193c55ef41860972d54b3e89f9bfe559..f1671fe5ecede5daf9580c01972ec2f52eac8c90 100644 (file)
@@ -38,6 +38,7 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.test.IsMeasure;
 import org.sonar.api.utils.Duration;
 import org.sonar.api.utils.Durations;
+import org.sonar.batch.index.DefaultIndex;
 import org.sonar.core.qualitygate.db.QualityGateConditionDto;
 import org.sonar.core.timemachine.Periods;
 
@@ -68,6 +69,7 @@ public class QualityGateVerifierTest {
   Periods periods;
   I18n i18n;
   Durations durations;
+  private DefaultIndex index;
 
   @Before
   public void before() {
@@ -88,7 +90,8 @@ public class QualityGateVerifierTest {
     snapshot = mock(Snapshot.class);
     qualityGate = mock(QualityGate.class);
     when(qualityGate.isEnabled()).thenReturn(true);
-    verifier = new QualityGateVerifier(qualityGate, snapshot, periods, i18n, durations);
+    index = mock(DefaultIndex.class);
+    verifier = new QualityGateVerifier(qualityGate, snapshot, periods, i18n, durations, index);
     project = new Project("foo");
   }
 
@@ -130,8 +133,8 @@ public class QualityGateVerifierTest {
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.ALERT_STATUS, Metric.Level.OK.toString())));
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK)));
-    verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureCoverage, Metric.Level.OK)));
   }
 
   @Test
@@ -150,31 +153,34 @@ public class QualityGateVerifierTest {
   public void generate_warnings() {
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "100"),
-      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "95.0")); // generates warning because coverage 35% < 95%
+      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "95.0")); // generates warning because coverage
+                                                                                                      // 35% < 95%
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.WARN, null)));
 
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK)));
-    verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureCoverage, Metric.Level.WARN)));
 
   }
 
   @Test
   public void globalStatusShouldBeErrorIfWarningsAndErrors() {
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
-      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "100"), // generates warning because classes 20 < 100
-      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, "50.0", "80.0")); // generates error because coverage 35% < 50%
+      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "100"), // generates warning because classes 20 <
+                                                                                                   // 100
+      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, "50.0", "80.0")); // generates error because coverage
+                                                                                                        // 35% < 50%
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.ERROR, null)));
 
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.WARN)));
-    verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.ERROR)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureCoverage, Metric.Level.ERROR)));
   }
 
   @Test
@@ -182,8 +188,10 @@ public class QualityGateVerifierTest {
     when(i18n.message(any(Locale.class), eq("metric.classes.name"), anyString())).thenReturn("Classes");
     when(i18n.message(any(Locale.class), eq("metric.coverage.name"), anyString())).thenReturn("Coverages");
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
-      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "10000"), // there are 20 classes, error threshold is higher => alert
-      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, "50.0", "80.0"));// coverage is 35%, warning threshold is higher => alert
+      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "10000"), // there are 20 classes, error
+                                                                                                     // threshold is higher => alert
+      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, "50.0", "80.0"));// coverage is 35%, warning threshold
+                                                                                                       // is higher => alert
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
@@ -213,7 +221,7 @@ public class QualityGateVerifierTest {
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       // there are 20 classes, error threshold is higher => alert
       mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_LESS_THAN, "10000", null)
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
@@ -229,20 +237,22 @@ public class QualityGateVerifierTest {
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "10", 1), // ok because no variation
-      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "40.0", 2), // ok because coverage increases of 50%, which is more
+      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "40.0", 2), // ok because coverage increases of
+                                                                                                        // 50%, which is more
       // than 40%
-      mockCondition(CoreMetrics.COMPLEXITY, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "5", 3) // ok because complexity increases of 2, which is less
+      mockCondition(CoreMetrics.COMPLEXITY, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "5", 3) // ok because complexity increases
+                                                                                                         // of 2, which is less
       // than 5
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.OK, null)));
 
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK)));
-    verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.OK)));
-    verify(context).saveMeasure(argThat(hasLevel(measureComplexity, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureCoverage, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureComplexity, Metric.Level.OK)));
   }
 
   @Test
@@ -252,22 +262,25 @@ public class QualityGateVerifierTest {
     measureComplexity.setVariation3(70d);
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
-      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1), // generates warning because classes increases of 40,
+      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1), // generates warning because classes
+                                                                                                        // increases of 40,
       // which is greater than 30
-      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "10.0", 2), // generates warning because coverage increases of 5%,
+      mockCondition(CoreMetrics.COVERAGE, QualityGateConditionDto.OPERATOR_LESS_THAN, null, "10.0", 2), // generates warning because
+                                                                                                        // coverage increases of 5%,
       // which is smaller than 10%
-      mockCondition(CoreMetrics.COMPLEXITY, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "60", 3) // generates warning because complexity increases of
+      mockCondition(CoreMetrics.COMPLEXITY, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "60", 3) // generates warning because
+                                                                                                          // complexity increases of
       // 70, which is smaller than 60
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.WARN, null)));
 
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.WARN)));
-    verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.WARN)));
-    verify(context).saveMeasure(argThat(hasLevel(measureComplexity, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureCoverage, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureComplexity, Metric.Level.WARN)));
   }
 
   @Test
@@ -281,7 +294,7 @@ public class QualityGateVerifierTest {
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.OK, null)));
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.OK)));
   }
 
   @Test
@@ -293,13 +306,13 @@ public class QualityGateVerifierTest {
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       mockCondition(ratingMetric, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "100", 1)
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.OK, null)));
-    verify(context).saveMeasure(argThat(hasLevel(measureRatingMetric, Metric.Level.OK)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureRatingMetric, Metric.Level.OK)));
   }
 
   @Test
@@ -308,13 +321,13 @@ public class QualityGateVerifierTest {
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 4)
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
 
     verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.WARN, null)));
-    verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.WARN)));
+    verify(index).updateMeasure(eq(project), argThat(hasLevel(measureClasses, Metric.Level.WARN)));
   }
 
   @Test(expected = NotImplementedException.class)
@@ -325,7 +338,7 @@ public class QualityGateVerifierTest {
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
       mockCondition(CoreMetrics.SCM_AUTHORS_BY_LINE, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1)
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
@@ -339,9 +352,10 @@ public class QualityGateVerifierTest {
     when(periods.label(snapshot, 1)).thenReturn("since someday");
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
-      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1) // generates warning because classes increases of 40,
+      mockCondition(CoreMetrics.CLASSES, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1) // generates warning because classes
+                                                                                                       // increases of 40,
       // which is greater than 30
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
@@ -361,9 +375,10 @@ public class QualityGateVerifierTest {
     when(periods.label(snapshot, 1)).thenReturn("since someday");
 
     ArrayList<ResolvedCondition> conditions = Lists.newArrayList(
-      mockCondition(newMetric, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1) // generates warning because classes increases of 40, which is
+      mockCondition(newMetric, QualityGateConditionDto.OPERATOR_GREATER_THAN, null, "30", 1) // generates warning because classes increases
+                                                                                             // of 40, which is
       // greater than 30
-    );
+      );
     when(qualityGate.conditions()).thenReturn(conditions);
 
     verifier.decorate(project, context);
index 0b1db5e1d75c24d0d0c9fe40c4aedf21edc287fd..a4da3d1d7c2e136b1b171c00fb5570656550a94d 100644 (file)
@@ -72,6 +72,7 @@ public class MeasureCacheTest {
     Measure m = new Measure(CoreMetrics.NCLOC, 1.0);
     cache.put(p, m);
 
+    assertThat(cache.contains(p, m)).isTrue();
     assertThat(cache.entries()).hasSize(1);
     Iterator<Entry<Measure>> iterator = cache.entries().iterator();
     iterator.hasNext();