]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6589 move MeasureRepository out of Component
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 27 May 2015 16:24:50 +0000 (18:24 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 1 Jun 2015 15:08:28 +0000 (17:08 +0200)
server/sonar-server/src/main/java/org/sonar/server/computation/component/Component.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentTreeBuilders.java
server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureRepository.java
server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureRepositoryImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityProfileEventsStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/component/DumbComponent.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityProfileEventsStepTest.java

index ab4170d128f411cf0a75a14063cc6c9890d7bf4d..c379e1f72eb93e31fba68ff4b3e87d275b2b8215 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.server.computation.component;
 import java.util.List;
 import org.sonar.server.computation.context.ComputationContext;
 import org.sonar.server.computation.event.EventRepository;
-import org.sonar.server.computation.measure.MeasureRepository;
 import org.sonar.server.computation.step.PopulateComponentsUuidAndKeyStep;
 
 public interface Component {
@@ -68,9 +67,4 @@ public interface Component {
    */
   EventRepository getEventRepository();
 
-  /**
-   * the measure repository for the current component
-   */
-  MeasureRepository getMeasureRepository();
-
 }
index c0690e03cbd73001bfe653ac85da98112b4df56c..f0ae5fd951214878183d9a1e17bb1b71fd1449ed 100644 (file)
  */
 package org.sonar.server.computation.component;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.sonar.api.measures.Metric;
 import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.measure.db.MeasureDto;
-import org.sonar.core.persistence.DbSession;
 import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.event.Event;
 import org.sonar.server.computation.event.EventRepository;
-import org.sonar.server.computation.measure.MeasureRepository;
-import org.sonar.server.db.DbClient;
 
 import static com.google.common.base.Predicates.notNull;
 import static com.google.common.collect.ImmutableList.copyOf;
@@ -50,18 +40,15 @@ public class ComponentImpl implements Component {
   private final Type type;
   private final BatchReport.Component component;
   private final List<Component> children;
-  private final BatchReportReader reportReader;
   private final EventRepository eventRepository = new SetEventRepository();
 
   // Mutable values
   private String key;
   private String uuid;
 
-  public ComponentImpl(ComputationContext context, BatchReport.Component component,
-    BatchReportReader reportReader, @Nullable Iterable<Component> children) {
+  public ComponentImpl(ComputationContext context, BatchReport.Component component, @Nullable Iterable<Component> children) {
     this.context = context;
     this.component = component;
-    this.reportReader = reportReader;
     this.type = convertType(component.getType());
     this.children = children == null ? Collections.<Component>emptyList() : copyOf(filter(children, notNull()));
   }
@@ -130,36 +117,6 @@ public class ComponentImpl implements Component {
     return eventRepository;
   }
 
-  @Override
-  public MeasureRepository getMeasureRepository() {
-    return new MeasureRepository() {
-      @Override
-      public Optional<MeasureDto> findPrevious(Metric<?> metric) {
-        DbClient dbClient = context.getDbClient();
-        try (DbSession dbSession = dbClient.openSession(false)) {
-          return Optional.fromNullable(
-            // TODO replace component.getKey() by ${link #getKey} as component.getKey() is only for project/module and does not take into
-            // account usage of the branch
-            dbClient.measureDao().findByComponentKeyAndMetricKey(dbSession, component.getKey(), metric.getKey())
-            );
-        }
-      }
-
-      @Override
-      public Optional<BatchReport.Measure> findCurrent(final Metric<?> metric) {
-        return Optional.fromNullable(Iterables.find(
-          reportReader.readComponentMeasures(component.getRef()),
-          new Predicate<BatchReport.Measure>() {
-            @Override
-            public boolean apply(@Nonnull BatchReport.Measure input) {
-              return input.getMetricKey().equals(metric.getKey());
-            }
-          }
-          ));
-      }
-    };
-  }
-
   private static class SetEventRepository implements EventRepository {
     private final Set<Event> events = new HashSet<>();
 
@@ -173,4 +130,5 @@ public class ComponentImpl implements Component {
       return events;
     }
   }
+
 }
index 7496e287df0e837c2c99e7ad314f5f39a0e4edbb..55b106b5425f6d18b209b4afba5ddf2196f3c097 100644 (file)
@@ -66,7 +66,7 @@ public final class ComponentTreeBuilders {
     private Component buildComponentRoot(ComputationContext computationContext, BatchReportReader reportReader) {
       int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
       BatchReport.Component component = reportReader.readComponent(rootComponentRef);
-      return new ComponentImpl(computationContext, component, reportReader, buildComponent(computationContext, rootComponentRef));
+      return new ComponentImpl(computationContext, component, buildComponent(computationContext, rootComponentRef));
     }
 
     private Iterable<Component> buildComponent(final ComputationContext computationContext, int componentRef) {
@@ -77,7 +77,7 @@ public final class ComponentTreeBuilders {
             @Override
             public Component apply(@Nonnull Integer componentRef) {
               BatchReport.Component component = reportReader.readComponent(componentRef);
-              return new ComponentImpl(computationContext, component, reportReader, buildComponent(computationContext, componentRef));
+              return new ComponentImpl(computationContext, component, buildComponent(computationContext, componentRef));
             }
           }
       );
index 3d35d9e7b191edceaa754f2ebd1619cbd7ddecd5..f1040901595ee011eb90f78621c9a90dd372033e 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.server.computation.issue.ScmAccountCache;
 import org.sonar.server.computation.issue.ScmAccountCacheLoader;
 import org.sonar.server.computation.issue.SourceLinesCache;
 import org.sonar.server.computation.language.PlatformLanguageRepository;
+import org.sonar.server.computation.measure.MeasureRepositoryImpl;
 import org.sonar.server.computation.measure.MetricCache;
 import org.sonar.server.computation.step.ComputationStep;
 import org.sonar.server.computation.step.ComputationSteps;
@@ -113,6 +114,7 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co
 
       // repositories
       PlatformLanguageRepository.class,
+      MeasureRepositoryImpl.class,
       ProjectSettingsRepository.class,
 
       // component caches
index 38c4e77dfd908f92dd0eca3cabc72828cc834f1d..390e3ff62e61b7303b4ef2010db00df6abe87888 100644 (file)
@@ -24,11 +24,12 @@ import org.sonar.batch.protocol.output.BatchReport;
 
 import com.google.common.base.Optional;
 import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.server.computation.component.Component;
 
 public interface MeasureRepository {
   // FIXME should not expose MeasureDto from DAO layer
-  Optional<MeasureDto> findPrevious(Metric<?> metric);
+  Optional<MeasureDto> findPrevious(Component component, Metric<?> metric);
 
   // FIXME should not expose Measure from BatchReport
-  Optional<BatchReport.Measure> findCurrent(Metric<?> metric);
+  Optional<BatchReport.Measure> findCurrent(Component component, Metric<?> metric);
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureRepositoryImpl.java
new file mode 100644 (file)
index 0000000..61718b6
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.measure;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import javax.annotation.Nonnull;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.computation.batch.BatchReportReader;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.db.DbClient;
+
+public class MeasureRepositoryImpl implements MeasureRepository {
+  private final DbClient dbClient;
+  private final BatchReportReader reportReader;
+
+  public MeasureRepositoryImpl(DbClient dbClient, BatchReportReader reportReader) {
+    this.dbClient = dbClient;
+    this.reportReader = reportReader;
+  }
+
+  @Override
+  public Optional<MeasureDto> findPrevious(Component component, Metric<?> metric) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      return Optional.fromNullable(
+        // TODO replace component.getKey() by ${link #getKey} as component.getKey() is only for project/module and does not take into
+        // account usage of the branch
+        dbClient.measureDao().findByComponentKeyAndMetricKey(dbSession, component.getKey(), metric.getKey())
+        );
+    }
+  }
+
+  @Override
+  public Optional<BatchReport.Measure> findCurrent(Component component, final Metric<?> metric) {
+    return Optional.fromNullable(Iterables.find(
+        reportReader.readComponentMeasures(component.getRef()),
+        new Predicate<BatchReport.Measure>() {
+          @Override
+          public boolean apply(@Nonnull BatchReport.Measure input) {
+            return input.getMetricKey().equals(metric.getKey());
+          }
+        }
+    ));
+  }
+}
index 3846599a0f27643380a28111eae5010d7b1645ab..2e26992c1d23b6ef8bf268f3d625c7c8d80790ed 100644 (file)
@@ -32,6 +32,7 @@ import org.sonar.server.computation.ComputationContext;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
 import org.sonar.server.computation.event.Event;
+import org.sonar.server.computation.measure.MeasureRepository;
 import org.sonar.server.computation.qualityprofile.QPMeasureData;
 import org.sonar.server.computation.qualityprofile.QualityProfile;
 
@@ -43,6 +44,11 @@ import java.util.Map;
 import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.POST_ORDER;
 
 public class QualityProfileEventsStep implements ComputationStep {
+  private final MeasureRepository measureRepository;
+
+  public QualityProfileEventsStep(MeasureRepository measureRepository) {
+    this.measureRepository = measureRepository;
+  }
 
   @Override
   public void execute(ComputationContext context) {
@@ -55,7 +61,7 @@ public class QualityProfileEventsStep implements ComputationStep {
   }
 
   private void executeForProject(Component projectComponent) {
-    Optional<MeasureDto> previousMeasure = projectComponent.getMeasureRepository().findPrevious(CoreMetrics.QUALITY_PROFILES);
+    Optional<MeasureDto> previousMeasure = measureRepository.findPrevious(projectComponent, CoreMetrics.QUALITY_PROFILES);
     if (!previousMeasure.isPresent()) {
       // first analysis -> do not generate events
       return;
@@ -63,7 +69,7 @@ public class QualityProfileEventsStep implements ComputationStep {
 
     // Load current profiles
     Map<String, QualityProfile> previousProfiles = QPMeasureData.fromJson(previousMeasure.get().getData()).getProfilesByKey();
-    Optional<BatchReport.Measure> currentMeasure = projectComponent.getMeasureRepository().findCurrent(CoreMetrics.QUALITY_PROFILES);
+    Optional<BatchReport.Measure> currentMeasure = measureRepository.findCurrent(projectComponent, CoreMetrics.QUALITY_PROFILES);
     if (!currentMeasure.isPresent()) {
       throw new IllegalStateException("Missing measure " + CoreMetrics.QUALITY_PROFILES + " for component " + projectComponent.getRef());
     }
index f9edbb04bf869b5d3380d3687b015872eb12aa24..8830ff340df56c423615c1dfd6a55170556b1508 100644 (file)
 package org.sonar.server.computation.component;
 
 import com.google.common.collect.ImmutableList;
-import org.sonar.server.computation.context.ComputationContext;
-import org.sonar.server.computation.event.EventRepository;
-import org.sonar.server.computation.measure.MeasureRepository;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.server.computation.context.ComputationContext;
+import org.sonar.server.computation.event.EventRepository;
 
 public class DumbComponent implements Component {
   public static final Component DUMB_PROJECT = new DumbComponent(Type.PROJECT, 1, "PROJECT_KEY", "PROJECT_UUID");
@@ -95,8 +92,4 @@ public class DumbComponent implements Component {
     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_ERROR);
   }
 
-  @Override
-  public MeasureRepository getMeasureRepository() {
-    throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_ERROR);
-  }
 }
index e2dd85639f8ef8996094ef0dbae2f2ef71cf29ce..2759dec7c19c14ff03a0f1d5ed87a1d8d2b91e69 100644 (file)
@@ -21,6 +21,13 @@ package org.sonar.server.computation.step;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
@@ -42,15 +49,6 @@ import org.sonar.server.computation.qualityprofile.QPMeasureData;
 import org.sonar.server.computation.qualityprofile.QualityProfile;
 import org.sonar.server.db.DbClient;
 
-import javax.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
@@ -68,13 +66,14 @@ public class QualityProfileEventsStepTest {
   private MeasureRepository measureRepository = mock(MeasureRepository.class);
   private LanguageRepository languageRepository = mock(LanguageRepository.class);
 
-  private QualityProfileEventsStep underTest = new QualityProfileEventsStep();
+  private QualityProfileEventsStep underTest = new QualityProfileEventsStep(measureRepository);
 
   @Test
   public void no_effect_if_no_previous_measure() {
-    when(measureRepository.findPrevious(CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.<MeasureDto>absent());
-
     ComputationContext context = newNoChildRootContext();
+
+    when(measureRepository.findPrevious(context.getRoot(), CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.<MeasureDto>absent());
+
     underTest.execute(context);
 
     assertThat(context.getRoot().getEventRepository().getEvents()).isEmpty();
@@ -82,17 +81,20 @@ public class QualityProfileEventsStepTest {
 
   @Test(expected = IllegalStateException.class)
   public void ISE_if_no_current_measure() {
-    when(measureRepository.findPrevious(CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newMeasureDto()));
-    when(measureRepository.findCurrent(CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.<BatchReport.Measure>absent());
+    ComputationContext context = newNoChildRootContext();
+
+    when(measureRepository.findPrevious(context.getRoot(), CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newMeasureDto()));
+    when(measureRepository.findCurrent(context.getRoot(), CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.<BatchReport.Measure>absent());
 
-    underTest.execute(newNoChildRootContext());
+    underTest.execute(context);
   }
 
   @Test
   public void no_event_if_no_qp_now_nor_before() {
-    mockMeasures(null, null);
-
     ComputationContext context = newNoChildRootContext();
+
+    mockMeasures(context.getRoot(), null, null);
+
     underTest.execute(context);
 
     assertThat(context.getRoot().getEventRepository().getEvents()).isEmpty();
@@ -101,10 +103,11 @@ public class QualityProfileEventsStepTest {
   @Test
   public void added_event_if_one_new_qp() {
     QualityProfile qp = qp(QP_NAME_1, LANGUAGE_KEY_1);
-    mockMeasures(null, arrayOf(qp));
+    ComputationContext context = newNoChildRootContext();
+
     Language language = mockLanguageInRepository(LANGUAGE_KEY_1);
+    mockMeasures(context.getRoot(), null, arrayOf(qp));
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     List<Event> events = Lists.newArrayList(context.getRoot().getEventRepository().getEvents());
@@ -115,10 +118,11 @@ public class QualityProfileEventsStepTest {
   @Test
   public void added_event_uses_language_key_in_message_if_language_not_found() {
     QualityProfile qp = qp(QP_NAME_1, LANGUAGE_KEY_1);
-    mockMeasures(null, arrayOf(qp));
+    ComputationContext context = newNoChildRootContext();
+
     mockLanguageNotInRepository(LANGUAGE_KEY_1);
+    mockMeasures(context.getRoot(), null, arrayOf(qp));
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     List<Event> events = Lists.newArrayList(context.getRoot().getEventRepository().getEvents());
@@ -129,10 +133,11 @@ public class QualityProfileEventsStepTest {
   @Test
   public void no_more_used_event_if_qp_no_more_listed() {
     QualityProfile qp = qp(QP_NAME_1, LANGUAGE_KEY_1);
-    mockMeasures(arrayOf(qp), null);
+    ComputationContext context = newNoChildRootContext();
+
+    mockMeasures(context.getRoot(), arrayOf(qp), null);
     Language language = mockLanguageInRepository(LANGUAGE_KEY_1);
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     List<Event> events = Lists.newArrayList(context.getRoot().getEventRepository().getEvents());
@@ -143,10 +148,11 @@ public class QualityProfileEventsStepTest {
   @Test
   public void no_more_used_event_uses_language_key_in_message_if_language_not_found() {
     QualityProfile qp = qp(QP_NAME_1, LANGUAGE_KEY_1);
-    mockMeasures(arrayOf(qp), null);
+    ComputationContext context = newNoChildRootContext();
+
+    mockMeasures(context.getRoot(), arrayOf(qp), null);
     mockLanguageNotInRepository(LANGUAGE_KEY_1);
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     List<Event> events = Lists.newArrayList(context.getRoot().getEventRepository().getEvents());
@@ -157,9 +163,10 @@ public class QualityProfileEventsStepTest {
   @Test
   public void no_event_if_same_qp_with_same_date() {
     QualityProfile qp = qp(QP_NAME_1, LANGUAGE_KEY_1);
-    mockMeasures(arrayOf(qp), arrayOf(qp));
-
     ComputationContext context = newNoChildRootContext();
+
+    mockMeasures(context.getRoot(), arrayOf(qp), arrayOf(qp));
+
     underTest.execute(context);
 
     assertThat(context.getRoot().getEventRepository().getEvents()).isEmpty();
@@ -169,10 +176,11 @@ public class QualityProfileEventsStepTest {
   public void changed_event_if_same_qp_but_no_same_date() {
     QualityProfile qp1 = qp(QP_NAME_1, LANGUAGE_KEY_1, parseDateTime("2011-04-25T01:05:13+0100"));
     QualityProfile qp2 = qp(QP_NAME_1, LANGUAGE_KEY_1, parseDateTime("2011-04-25T01:05:17+0100"));
-    mockMeasures(arrayOf(qp1), arrayOf(qp2));
+    ComputationContext context = newNoChildRootContext();
+
+    mockMeasures(context.getRoot(), arrayOf(qp1), arrayOf(qp2));
     Language language = mockLanguageInRepository(LANGUAGE_KEY_1);
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     List<Event> events = Lists.newArrayList(context.getRoot().getEventRepository().getEvents());
@@ -186,8 +194,10 @@ public class QualityProfileEventsStepTest {
 
   @Test
   public void verify_detection_with_complex_mix_of_qps() {
+    ComputationContext context = newNoChildRootContext();
+
     mockMeasures(
-      arrayOf(
+      context.getRoot(), arrayOf(
         qp(QP_NAME_2, LANGUAGE_KEY_1),
         qp(QP_NAME_2, LANGUAGE_KEY_2),
         qp(QP_NAME_1, LANGUAGE_KEY_1, parseDateTime("2011-04-25T01:05:13+0100"))
@@ -199,13 +209,12 @@ public class QualityProfileEventsStepTest {
       ));
     mockNoLanguageInRepository();
 
-    ComputationContext context = newNoChildRootContext();
     underTest.execute(context);
 
     assertThat(context.getRoot().getEventRepository().getEvents()).extracting("name").containsOnly(
-        "Stop using '" + QP_NAME_2 + "' (" + LANGUAGE_KEY_1 + ")",
-        "Use '" + QP_NAME_2 + "' (" + LANGUAGE_KEY_3 + ")",
-        "Changes in '" + QP_NAME_1 + "' (" + LANGUAGE_KEY_1 + ")"
+      "Stop using '" + QP_NAME_2 + "' (" + LANGUAGE_KEY_1 + ")",
+      "Use '" + QP_NAME_2 + "' (" + LANGUAGE_KEY_3 + ")",
+      "Changes in '" + QP_NAME_1 + "' (" + LANGUAGE_KEY_1 + ")"
       );
 
   }
@@ -229,9 +238,9 @@ public class QualityProfileEventsStepTest {
     when(languageRepository.find(anyString())).thenReturn(Optional.<Language>absent());
   }
 
-  private void mockMeasures(@Nullable QualityProfile[] previous, @Nullable QualityProfile[] current) {
-    when(measureRepository.findPrevious(CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newMeasureDto(previous)));
-    when(measureRepository.findCurrent(CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newQPBatchMeasure(current)));
+  private void mockMeasures(Component component, @Nullable QualityProfile[] previous, @Nullable QualityProfile[] current) {
+    when(measureRepository.findPrevious(component, CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newMeasureDto(previous)));
+    when(measureRepository.findCurrent(component, CoreMetrics.QUALITY_PROFILES)).thenReturn(Optional.of(newQPBatchMeasure(current)));
   }
 
   private static void verifyEvent(Event event, String expectedName, @Nullable String expectedData) {
@@ -273,7 +282,7 @@ public class QualityProfileEventsStepTest {
     return newContext(new ComponentTreeBuilder() {
       @Override
       public Component build(ComputationContext context) {
-        return new EventAndMeasureRepoComponent(context, Component.Type.PROJECT, 1);
+        return new EvenRepoComponent(context, Component.Type.PROJECT, 1);
       }
     });
   }
@@ -283,7 +292,7 @@ public class QualityProfileEventsStepTest {
       builder, languageRepository);
   }
 
-  private class EventAndMeasureRepoComponent extends DumbComponent {
+  private class EvenRepoComponent extends DumbComponent {
     private final EventRepository eventRepository = new EventRepository() {
       private final Set<Event> events = new HashSet<>();
 
@@ -298,16 +307,11 @@ public class QualityProfileEventsStepTest {
       }
     };
 
-    public EventAndMeasureRepoComponent(@Nullable org.sonar.server.computation.context.ComputationContext context,
+    public EvenRepoComponent(@Nullable org.sonar.server.computation.context.ComputationContext context,
       Type type, int ref, @Nullable Component... children) {
       super(context, type, ref, null, null, children);
     }
 
-    @Override
-    public MeasureRepository getMeasureRepository() {
-      return measureRepository;
-    }
-
     @Override
     public EventRepository getEventRepository() {
       return eventRepository;