]> source.dussan.org Git - sonarqube.git/commitdiff
Merge FillComponentsStep in BuildComponentTreeStep
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 22 Sep 2015 10:41:51 +0000 (12:41 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 25 Sep 2015 08:17:02 +0000 (10:17 +0200)
server/sonar-server/src/main/java/org/sonar/server/computation/step/BuildComponentTreeStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/FillComponentsStep.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportComputationSteps.java
server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/component/ComponentTreeBuilder.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/step/BuildComponentTreeStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/FillComponentsStepTest.java [deleted file]

index 42b9a52a799a8663111b9827506b9f43ec03eca3..74d8f179fc5f52f8fabb5f647012f5e2493508b6 100644 (file)
@@ -22,23 +22,31 @@ package org.sonar.server.computation.step;
 import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import java.util.Date;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.db.DbClient;
 import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolder;
 import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.ComponentImpl;
 import org.sonar.server.computation.component.MutableTreeRootHolder;
+import org.sonar.server.computation.component.UuidFactory;
 
 /**
  * Populates the {@link MutableTreeRootHolder} and {@link MutableAnalysisMetadataHolder} from the {@link BatchReportReader}
  */
 public class BuildComponentTreeStep implements ComputationStep {
+
+  private final DbClient dbClient;
   private final BatchReportReader reportReader;
   private final MutableTreeRootHolder treeRootHolder;
   private final MutableAnalysisMetadataHolder analysisMetadataHolder;
 
-  public BuildComponentTreeStep(BatchReportReader reportReader, MutableTreeRootHolder treeRootHolder, MutableAnalysisMetadataHolder analysisMetadataHolder) {
+  public BuildComponentTreeStep(DbClient dbClient, BatchReportReader reportReader, MutableTreeRootHolder treeRootHolder, MutableAnalysisMetadataHolder analysisMetadataHolder) {
+    this.dbClient = dbClient;
     this.reportReader = reportReader;
     this.treeRootHolder = treeRootHolder;
     this.analysisMetadataHolder = analysisMetadataHolder;
@@ -46,28 +54,70 @@ public class BuildComponentTreeStep implements ComputationStep {
 
   @Override
   public void execute() {
-    BatchReport.Metadata metadata = reportReader.readMetadata();
-    treeRootHolder.setRoot(buildComponentRoot(metadata));
-    analysisMetadataHolder.setAnalysisDate(new Date(metadata.getAnalysisDate()));
+    analysisMetadataHolder.setAnalysisDate(new Date(reportReader.readMetadata().getAnalysisDate()));
+    BatchReport.Metadata reportMetadata = reportReader.readMetadata();
+    String branch = reportMetadata.hasBranch() ? reportMetadata.getBranch() : null;
+    BatchReport.Component reportProject = reportReader.readComponent(reportMetadata.getRootComponentRef());
+    UuidFactory uuidFactory = new UuidFactory(dbClient, moduleKey(reportProject, branch));
+    treeRootHolder.setRoot(new ComponentRootBuilder(reportProject, uuidFactory, branch).build());
   }
 
-  private Component buildComponentRoot(BatchReport.Metadata metadata) {
-    int rootComponentRef = metadata.getRootComponentRef();
-    BatchReport.Component component = reportReader.readComponent(rootComponentRef);
-    return new ComponentImpl(component, buildChildren(component));
-  }
+  private class ComponentRootBuilder {
+
+    private final BatchReport.Component reportProject;
+
+    private final UuidFactory uuidFactory;
+
+    @CheckForNull
+    private final String branch;
+
+    public ComponentRootBuilder(BatchReport.Component reportProject, UuidFactory uuidFactory, @Nullable String branch) {
+      this.reportProject = reportProject;
+      this.uuidFactory = uuidFactory;
+      this.branch = branch;
+    }
 
-  private Iterable<Component> buildChildren(BatchReport.Component component) {
-    return Iterables.transform(
+    private Component build() {
+      return buildComponent(reportProject, moduleKey(reportProject, branch));
+    }
+
+    private ComponentImpl buildComponent(BatchReport.Component reportComponent, String latestModuleKey) {
+      switch (reportComponent.getType()) {
+        case PROJECT:
+        case MODULE:
+          String moduleKey = moduleKey(reportComponent, branch);
+          return buildComponent(reportComponent, moduleKey, moduleKey);
+        case DIRECTORY:
+        case FILE:
+          return buildComponent(reportComponent, ComponentKeys.createEffectiveKey(latestModuleKey, reportComponent.getPath()), latestModuleKey);
+        default:
+          throw new IllegalStateException(String.format("Unsupported component type '%s'", reportComponent.getType()));
+      }
+    }
+
+    private ComponentImpl buildComponent(BatchReport.Component reportComponent, String componentKey, String latestModuleKey){
+      // TODO create builder for component
+      ComponentImpl component = new ComponentImpl(reportComponent, buildChildren(reportComponent, latestModuleKey));
+      component.setKey(componentKey);
+      component.setUuid(uuidFactory.getOrCreateForKey(componentKey));
+      return component;
+    }
+
+    private Iterable<Component> buildChildren(BatchReport.Component component, final String latestModuleKey) {
+      return Iterables.transform(
         component.getChildRefList(),
         new Function<Integer, Component>() {
           @Override
           public Component apply(@Nonnull Integer componentRef) {
-            BatchReport.Component component = reportReader.readComponent(componentRef);
-            return new ComponentImpl(component, buildChildren(component));
+            return buildComponent(reportReader.readComponent(componentRef), latestModuleKey);
           }
         }
-    );
+      );
+    }
+  }
+
+  private static String moduleKey(BatchReport.Component reportComponent, @Nullable String branch) {
+    return ComponentKeys.createKey(reportComponent.getKey(), branch);
   }
 
   @Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/FillComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/FillComponentsStep.java
deleted file mode 100644 (file)
index 3b20492..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.step;
-
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.component.ComponentKeys;
-import org.sonar.db.DbClient;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentImpl;
-import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.component.UuidFactory;
-
-/**
- * Read all components from the batch report and fill component UUID and key.
- * This step loads the tree of components from database. It does not insert or update database.
- */
-public class FillComponentsStep implements ComputationStep {
-
-  private final DbClient dbClient;
-  private final BatchReportReader reportReader;
-  private final TreeRootHolder treeRootHolder;
-
-  public FillComponentsStep(DbClient dbClient, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
-    this.dbClient = dbClient;
-    this.reportReader = reportReader;
-    this.treeRootHolder = treeRootHolder;
-  }
-
-  @Override
-  public void execute() {
-    BatchReport.Metadata reportMetadata = reportReader.readMetadata();
-    String branch = reportMetadata.hasBranch() ? reportMetadata.getBranch() : null;
-    BatchReport.Component reportProject = reportReader.readComponent(reportMetadata.getRootComponentRef());
-    String projectKey = ComponentKeys.createKey(reportProject.getKey(), branch);
-    UuidFactory uuidFactory = new UuidFactory(dbClient, projectKey);
-
-    // feed project information
-    ComponentImpl root = (ComponentImpl) treeRootHolder.getRoot();
-    root.setKey(projectKey);
-    root.setUuid(uuidFactory.getOrCreateForKey(projectKey));
-
-    processChildren(uuidFactory, root, root);
-  }
-
-  private void recursivelyProcessComponent(UuidFactory uuidFactory, ComponentImpl component, Component nearestModule) {
-    switch (component.getType()) {
-      case MODULE:
-        processModule(uuidFactory, component);
-        processChildren(uuidFactory, component, component);
-        break;
-      case DIRECTORY:
-      case FILE:
-        processDirectoryAndFile(uuidFactory, component, nearestModule);
-        processChildren(uuidFactory, component, nearestModule);
-        break;
-      default:
-        throw new IllegalStateException(String.format("Unsupported component type '%s'", component.getType()));
-    }
-  }
-
-  private void processChildren(UuidFactory uuidFactory, Component component, Component nearestModule) {
-    for (Component child : component.getChildren()) {
-      recursivelyProcessComponent(uuidFactory, (ComponentImpl) child, nearestModule);
-    }
-  }
-
-  private void processModule(UuidFactory uuidFactory, ComponentImpl component) {
-    BatchReport.Metadata reportMetadata = reportReader.readMetadata();
-    String branch = reportMetadata.hasBranch() ? reportMetadata.getBranch() : null;
-
-    BatchReport.Component reportComponent = reportReader.readComponent(component.getReportAttributes().getRef());
-    String key = ComponentKeys.createKey(reportComponent.getKey(), branch);
-    component.setKey(key);
-    component.setUuid(uuidFactory.getOrCreateForKey(key));
-  }
-
-  private void processDirectoryAndFile(UuidFactory uuidFactory, ComponentImpl component, Component nearestModule) {
-    BatchReport.Component reportComponent = reportReader.readComponent(component.getReportAttributes().getRef());
-    // TODO fail if path is null
-    String key = ComponentKeys.createEffectiveKey(nearestModule.getKey(), reportComponent.getPath());
-    component.setKey(key);
-    component.setUuid(uuidFactory.getOrCreateForKey(key));
-  }
-
-  @Override
-  public String getDescription() {
-    return "Initialize components";
-  }
-
-}
index ea8e690ec1bc71b2cec3c41b5664b22b46f4f067..a59b2635c4becd545f1c189e700775de4f5b82d7 100644 (file)
@@ -43,7 +43,6 @@ public class ReportComputationSteps implements ComputationSteps {
 
       // Builds Component tree
       BuildComponentTreeStep.class,
-      FillComponentsStep.class,
       ValidateProjectStep.class,
 
       LoadDebtModelStep.class,
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java
deleted file mode 100644 (file)
index b1a799d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.batch;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import java.util.Objects;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentImpl;
-import org.sonar.server.computation.component.ReportComponent;
-
-public class ComponentTreeRule implements TestRule {
-
-  @CheckForNull
-  private final BatchReportReader batchReportReader;
-  private final BUILD_OPTIONS buildOptions;
-
-  private Component root;
-
-  private ComponentTreeRule(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
-    this.batchReportReader = batchReportReader;
-    this.buildOptions = buildOptions;
-  }
-
-  public static ComponentTreeRule from(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
-    return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), buildOptions);
-  }
-
-  public static ComponentTreeRule from(BatchReportReader batchReportReader) {
-    return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), BUILD_OPTIONS.NONE);
-  }
-
-  @Override
-  public Statement apply(final Statement statement, Description description) {
-    return new Statement() {
-      @Override
-      public void evaluate() throws Throwable {
-        try {
-          statement.evaluate();
-        } finally {
-          clear();
-        }
-      }
-    };
-  }
-
-  private void clear() {
-    this.root = null;
-  }
-
-  public enum BUILD_OPTIONS {
-    NONE(false, false), KEY(false, true), UUID(true, false), KEY_AND_UUID(true, true);
-    private final boolean uuid;
-    private final boolean key;
-
-    BUILD_OPTIONS(boolean uuid, boolean key) {
-      this.uuid = uuid;
-      this.key = key;
-    }
-  }
-
-  public Component getRoot() {
-    if (root == null) {
-      buildComponentRoot(buildOptions);
-    }
-    return this.root;
-  }
-
-  private Component buildComponentRoot(BUILD_OPTIONS build_options) {
-    int rootComponentRef = batchReportReader.readMetadata().getRootComponentRef();
-    return newComponent(batchReportReader.readComponent(rootComponentRef), build_options);
-  }
-
-  private ReportComponent newComponent(BatchReport.Component component, BUILD_OPTIONS build_options) {
-    return ReportComponent.builder(ComponentImpl.convertType(component.getType()), component.getRef())
-      .setUuid(build_options.uuid ? uuidOf(component.getRef()) : null)
-      .setKey(build_options.key ? keyOf(component.getRef()) : null)
-      .addChildren(buildChildren(component, build_options))
-      .build();
-  }
-
-  private Component[] buildChildren(BatchReport.Component component, final BUILD_OPTIONS build_options) {
-    return Iterables.toArray(
-      Iterables.transform(
-        component.getChildRefList(),
-        new Function<Integer, Component>() {
-          @Override
-          public Component apply(@Nonnull Integer componentRef) {
-            return newComponent(batchReportReader.readComponent(componentRef), build_options);
-          }
-        }
-        ), Component.class);
-  }
-
-  public String keyOf(int ref) {
-    return "key_" + ref;
-  }
-
-  public String uuidOf(int ref) {
-    return "uuid_" + ref;
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/ComponentTreeBuilder.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/ComponentTreeBuilder.java
deleted file mode 100644 (file)
index 060cb47..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.component;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import javax.annotation.Nonnull;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.server.computation.batch.BatchReportReader;
-
-public final class ComponentTreeBuilder {
-  public static Component from(final BatchReportReader reportReader) {
-    return buildComponentRoot(reportReader);
-  }
-
-  private static Component buildComponentRoot(BatchReportReader reportReader) {
-    int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-    BatchReport.Component component = reportReader.readComponent(rootComponentRef);
-    return newComponent(reportReader, component);
-  }
-
-  private static Iterable<Component> buildChildren(final BatchReportReader reportReader, final BatchReport.Component component) {
-    return Iterables.transform(
-        component.getChildRefList(),
-        new Function<Integer, Component>() {
-          @Override
-          public Component apply(@Nonnull Integer componentRef) {
-            BatchReport.Component component = reportReader.readComponent(componentRef);
-            return newComponent(reportReader, component);
-          }
-        }
-    );
-  }
-
-  private static Component newComponent(BatchReportReader reportReader, BatchReport.Component component) {
-    return new ComponentImpl(component, buildChildren(reportReader, component));
-  }
-}
index 1262d012d9449cb32f8f623044903287e6f456d7..788507d9197715f2f9cc4dc59a7ea43fce6889ea 100644 (file)
@@ -23,48 +23,80 @@ import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
+import org.sonar.api.utils.System2;
 import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.batch.protocol.output.BatchReport.Metadata;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
 import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolderRule;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.MutableTreeRootHolderRule;
+import org.sonar.test.DbTests;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.batch.protocol.Constants.ComponentType.DIRECTORY;
 import static org.sonar.batch.protocol.Constants.ComponentType.FILE;
 import static org.sonar.batch.protocol.Constants.ComponentType.MODULE;
 import static org.sonar.batch.protocol.Constants.ComponentType.PROJECT;
+import static org.sonar.db.component.ComponentTesting.newDirectory;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
 
+@Category(DbTests.class)
 @RunWith(DataProviderRunner.class)
 public class BuildComponentTreeStepTest {
-  private static final int ROOT_REF = 1;
-  private static final int MODULE_REF = 2;
-  private static final int DIR_REF_1 = 3;
-  private static final int FILE_1_REF = 4;
-  private static final int FILE_2_REF = 5;
-  private static final int DIR_REF_2 = 6;
-  private static final int FILE_3_REF = 7;
+
+  static final int ROOT_REF = 1;
+  static final int MODULE_REF = 2;
+  static final int DIR_REF_1 = 3;
+  static final int FILE_1_REF = 4;
+  static final int FILE_2_REF = 5;
+  static final int DIR_REF_2 = 6;
+  static final int FILE_3_REF = 7;
+
+  static final String REPORT_PROJECT_KEY = "REPORT_PROJECT_KEY";
+  static final String REPORT_MODULE_KEY = "MODULE_KEY";
+  static final String REPORT_DIR_KEY_1 = "src/main/java/dir1";
+  static final String REPORT_FILE_KEY_1 = "src/main/java/dir1/File1.java";
+  static final String REPORT_DIR_KEY_2 = "src/main/java/dir2";
+  static final String REPORT_FILE_KEY_2 = "src/main/java/dir2/File2.java";
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+
   @Rule
   public MutableTreeRootHolderRule treeRootHolder = new MutableTreeRootHolderRule();
+
   @Rule
   public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
 
-  private Date someDate = new Date();
+  Date someDate = new Date();
+
+  DbClient dbClient = dbTester.getDbClient();
 
-  private BuildComponentTreeStep underTest = new BuildComponentTreeStep(reportReader, treeRootHolder, analysisMetadataHolder);
+  BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
 
   @Before
   public void setUp() {
-    reportReader.setMetadata(Metadata.newBuilder().setRootComponentRef(ROOT_REF).setAnalysisDate(someDate.getTime()).build());
+    reportReader.setMetadata(Metadata.newBuilder()
+      .setRootComponentRef(ROOT_REF)
+      .setAnalysisDate(someDate.getTime())
+      .build());
   }
 
   @Test(expected = NullPointerException.class)
@@ -128,18 +160,186 @@ public class BuildComponentTreeStepTest {
     assertThat(analysisMetadataHolder.getAnalysisDate().getTime()).isEqualTo(someDate.getTime());
   }
 
+  @Test
+  public void compute_keys_and_uuids() {
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY);
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY);
+    verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1);
+    verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1);
+  }
+
+  @Test
+  public void return_existing_uuids() {
+    ComponentDto project = insertComponent(newProjectDto("ABCD").setKey(REPORT_PROJECT_KEY));
+    ComponentDto module = insertComponent(newModuleDto("BCDE", project).setKey(REPORT_MODULE_KEY));
+    insertComponent(newDirectory(module, "CDEF", REPORT_DIR_KEY_1).setKey(REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1));
+    insertComponent(newFileDto(module, "DEFG").setKey(REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1));
+
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY, "ABCD");
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY, "BCDE");
+    verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1, "CDEF");
+    verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1, "DEFG");
+  }
+
+  @Test
+  public void use_branch_to_generate_keys() {
+    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
+      .setRootComponentRef(ROOT_REF)
+      .setBranch("origin/master")
+      .setProjectKey("")
+      .build());
+
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY + ":origin/master");
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY + ":origin/master");
+    verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":origin/master:" + REPORT_DIR_KEY_1);
+    verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":origin/master:" + REPORT_FILE_KEY_1);
+  }
+
+  @Test
+  public void compute_keys_and_uuids_on_project_having_module_and_directory() {
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF, DIR_REF_2));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_2, DIRECTORY, REPORT_DIR_KEY_2, FILE_2_REF));
+    reportReader.putComponent(componentWithPath(FILE_2_REF, FILE, REPORT_FILE_KEY_2));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY);
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY);
+    verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1);
+    verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1);
+    verifyComponent(DIR_REF_2, REPORT_PROJECT_KEY + ":" + REPORT_DIR_KEY_2);
+    verifyComponent(FILE_2_REF, REPORT_PROJECT_KEY + ":" + REPORT_FILE_KEY_2);
+  }
+
+  @Test
+  public void compute_keys_and_uuids_on_multi_modules() {
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, 100));
+    reportReader.putComponent(componentWithKey(100, MODULE, "SUB_MODULE_KEY", DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY);
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY);
+    verifyComponent(100, "SUB_MODULE_KEY");
+    verifyComponent(DIR_REF_1, "SUB_MODULE_KEY" + ":" + REPORT_DIR_KEY_1);
+    verifyComponent(FILE_1_REF, "SUB_MODULE_KEY" + ":" + REPORT_FILE_KEY_1);
+  }
+
+  @Test
+  public void return_existing_uuids_when_components_were_removed() {
+    ComponentDto project = insertComponent(newProjectDto("ABCD").setKey(REPORT_PROJECT_KEY));
+    ComponentDto removedModule = insertComponent(newModuleDto("BCDE", project).setKey(REPORT_MODULE_KEY).setEnabled(false));
+    ComponentDto removedDirectory = insertComponent(newDirectory(removedModule, "CDEF", REPORT_DIR_KEY_1).setKey(REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1).setEnabled(false));
+    insertComponent(newFileDto(removedDirectory, "DEFG").setKey(REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1).setEnabled(false));
+
+    reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+    reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+    reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+    reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+
+    underTest.execute();
+
+    verifyComponent(ROOT_REF, REPORT_PROJECT_KEY, "ABCD");
+
+    // No new UUID is generated on removed components
+    verifyComponent(MODULE_REF, REPORT_MODULE_KEY, "BCDE");
+    verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":" + REPORT_DIR_KEY_1, "CDEF");
+    verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1, "DEFG");
+  }
+
   private void verifyComponent(Component component, Component.Type type, int componentRef, int size) {
     assertThat(component.getType()).isEqualTo(type);
     assertThat(component.getReportAttributes().getRef()).isEqualTo(componentRef);
     assertThat(component.getChildren()).hasSize(size);
   }
 
+  private void verifyComponent(int ref, String key) {
+    verifyComponent(ref, key, null);
+  }
+
+  private void verifyComponent(int ref, String key, @Nullable String uuid) {
+    Map<Integer, Component> componentsByRef = indexAllComponentsInTreeByRef(treeRootHolder.getRoot());
+    Component component = componentsByRef.get(ref);
+    assertThat(component.getKey()).isEqualTo(key);
+    if (uuid != null) {
+      assertThat(component.getUuid()).isEqualTo(uuid);
+    } else {
+      assertThat(component.getUuid()).isNotNull();
+    }
+  }
+
   private static BatchReport.Component component(int componentRef, Constants.ComponentType componentType, int... children) {
-    BatchReport.Component.Builder builder = BatchReport.Component.newBuilder().setType(componentType).setRef(componentRef);
+    return component(componentRef, componentType, null, null, children);
+  }
+
+  private static BatchReport.Component componentWithKey(int componentRef, Constants.ComponentType componentType, String key, int... children) {
+    return component(componentRef, componentType, key, null, children);
+  }
+
+  private static BatchReport.Component componentWithPath(int componentRef, Constants.ComponentType componentType, String path, int... children) {
+    return component(componentRef, componentType, null, path, children);
+  }
+
+  private static BatchReport.Component component(int componentRef, Constants.ComponentType componentType, @Nullable String key, @Nullable String path, int... children) {
+    BatchReport.Component.Builder builder = BatchReport.Component.newBuilder()
+      .setType(componentType)
+      .setRef(componentRef);
+    if (key != null) {
+      builder.setKey(key);
+    }
+    if (path != null) {
+      builder.setPath(path);
+    }
     for (int child : children) {
       builder.addChildRef(child);
     }
     return builder.build();
   }
 
+  private static Map<Integer, Component> indexAllComponentsInTreeByRef(Component root) {
+    Map<Integer, Component> componentsByRef = new HashMap<>();
+    feedComponentByRef(root, componentsByRef);
+    return componentsByRef;
+  }
+
+  private static void feedComponentByRef(Component component, Map<Integer, Component> map) {
+    map.put(component.getReportAttributes().getRef(), component);
+    for (Component child : component.getChildren()) {
+      feedComponentByRef(child, map);
+    }
+  }
+
+  private ComponentDto insertComponent(ComponentDto component) {
+    dbClient.componentDao().insert(dbTester.getSession(), component);
+    dbTester.getSession().commit();
+    return component;
+  }
+
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/FillComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/FillComponentsStepTest.java
deleted file mode 100644 (file)
index ba491b0..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * 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.step;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.sonar.api.utils.System2;
-import org.sonar.batch.protocol.Constants;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.batch.TreeRootHolderRule;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentTreeBuilder;
-import org.sonar.test.DbTests;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@Category(DbTests.class)
-public class FillComponentsStepTest extends BaseStepTest {
-
-  private static final String PROJECT_KEY = "PROJECT_KEY";
-
-  @Rule
-  public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
-  @Rule
-  public BatchReportReaderRule reportReader = new BatchReportReaderRule();
-
-  @Rule
-  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
-
-  DbClient dbClient = dbTester.getDbClient();
-
-  FillComponentsStep underTest;
-
-  @Before
-  public void setup() {
-    dbTester.truncateTables();
-    underTest = new FillComponentsStep(dbClient, reportReader, treeRootHolder);
-  }
-
-  @Override
-  protected ComputationStep step() {
-    return underTest;
-  }
-
-  @Test
-  public void compute_keys_and_uuids() {
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
-    assertThat(componentsByRef.get(1).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
-    assertThat(componentsByRef.get(2).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(3).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(componentsByRef.get(4).getUuid()).isNotNull();
-  }
-
-  @Test
-  public void return_existing_uuids() {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    dbClient.componentDao().insert(dbTester.getSession(), project);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY");
-    dbClient.componentDao().insert(dbTester.getSession(), module);
-    ComponentDto directory = ComponentTesting.newDirectory(module, "CDEF", "src/main/java/dir").setKey("MODULE_KEY:src/main/java/dir");
-    ComponentDto file = ComponentTesting.newFileDto(module, "DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java");
-    dbClient.componentDao().insert(dbTester.getSession(), directory, file);
-    dbTester.getSession().commit();
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
-    assertThat(componentsByRef.get(1).getUuid()).isEqualTo("ABCD");
-
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
-    assertThat(componentsByRef.get(2).getUuid()).isEqualTo("BCDE");
-
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(3).getUuid()).isEqualTo("CDEF");
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(componentsByRef.get(4).getUuid()).isEqualTo("DEFG");
-  }
-
-  @Test
-  public void use_latest_module_for_files_key() {
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .setName("Project")
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .setName("Module")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("SUB_MODULE_KEY")
-      .setName("Sub Module")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(5)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(5)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(5).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir/Foo.java");
-  }
-
-  @Test
-  public void use_branch_to_generate_keys() {
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setBranch("origin/master")
-      .setProjectKey("")
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .setName("Project")
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .setName("Module")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo("PROJECT_KEY:origin/master");
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY:origin/master");
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:origin/master:src/main/java/dir");
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:origin/master:src/main/java/dir/Foo.java");
-  }
-
-  @Test
-  public void compute_keys_and_uuids_on_project_having_module_and_directory() {
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .addChildRef(2)
-      .addChildRef(5)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(5)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("/")
-      .addChildRef(6)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(6)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("pom.xml")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
-    assertThat(componentsByRef.get(1).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
-    assertThat(componentsByRef.get(2).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(3).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(componentsByRef.get(4).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(5).getKey()).isEqualTo(PROJECT_KEY + ":/");
-    assertThat(componentsByRef.get(5).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(6).getKey()).isEqualTo(PROJECT_KEY + ":pom.xml");
-    assertThat(componentsByRef.get(6).getUuid()).isNotNull();
-  }
-
-  @Test
-  public void compute_keys_and_uuids_on_multi_modules() {
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("SUB_MODULE_KEY")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(5)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(5)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
-    assertThat(componentsByRef.get(1).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
-    assertThat(componentsByRef.get(2).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("SUB_MODULE_KEY");
-    assertThat(componentsByRef.get(3).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(4).getUuid()).isNotNull();
-
-    assertThat(componentsByRef.get(5).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(componentsByRef.get(5).getUuid()).isNotNull();
-  }
-
-  @Test
-  public void return_existing_uuids_when_components_were_removed() {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    dbClient.componentDao().insert(dbTester.getSession(), project);
-    ComponentDto removedModule = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setEnabled(false);
-    dbClient.componentDao().insert(dbTester.getSession(), removedModule);
-    ComponentDto removedDirectory = ComponentTesting.newDirectory(removedModule, "CDEF", "src/main/java/dir").setKey("MODULE_KEY:src/main/java/dir").setEnabled(false);
-    ComponentDto removedFile = ComponentTesting.newFileDto(removedModule, "DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java").setEnabled(false);
-    dbClient.componentDao().insert(dbTester.getSession(), removedDirectory, removedFile);
-    dbTester.getSession().commit();
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(1)
-      .setType(Constants.ComponentType.PROJECT)
-      .setKey(PROJECT_KEY)
-      .addChildRef(2)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(2)
-      .setType(Constants.ComponentType.MODULE)
-      .setKey("MODULE_KEY")
-      .addChildRef(3)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(3)
-      .setType(Constants.ComponentType.DIRECTORY)
-      .setPath("src/main/java/dir")
-      .addChildRef(4)
-      .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-      .setRef(4)
-      .setType(Constants.ComponentType.FILE)
-      .setPath("src/main/java/dir/Foo.java")
-      .build());
-
-    treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader));
-    underTest.execute();
-
-    Map<Integer, Component> componentsByRef = getComponentsByRef(treeRootHolder.getRoot());
-
-    assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
-    assertThat(componentsByRef.get(1).getUuid()).isEqualTo("ABCD");
-
-    // No new UUID is generated on removed components
-
-    assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
-    assertThat(componentsByRef.get(2).getUuid()).isEqualTo("BCDE");
-
-    assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
-    assertThat(componentsByRef.get(3).getUuid()).isEqualTo("CDEF");
-
-    assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(componentsByRef.get(4).getUuid()).isEqualTo("DEFG");
-  }
-
-  private static Map<Integer, Component> getComponentsByRef(Component root) {
-    Map<Integer, Component> componentsByRef = new HashMap<>();
-    feedComponentByRef(root, componentsByRef);
-    return componentsByRef;
-  }
-
-  private static void feedComponentByRef(Component component, Map<Integer, Component> map) {
-    map.put(component.getReportAttributes().getRef(), component);
-    for (Component child : component.getChildren()) {
-      feedComponentByRef(child, map);
-    }
-  }
-
-}