*/
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 java.util.List;
+import org.sonar.server.computation.step.PopulateComponentsUuidAndKeyStep;
public interface Component {
enum Type {
Type getType();
+ /**
+ * Return the component uuid only when {@link PopulateComponentsUuidAndKeyStep} has been executed, otherwise it will throw an exception.
+ */
String getUuid();
+ /**
+ * Return the component key only when {@link PopulateComponentsUuidAndKeyStep} has been executed, otherwise it will throw an exception.
+ */
String getKey();
// FIXME we should not expose a batch specific information
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.server.computation.measure.MeasureRepository;
import org.sonar.server.db.DbClient;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
import static com.google.common.base.Predicates.notNull;
import static com.google.common.collect.ImmutableList.copyOf;
import static com.google.common.collect.Iterables.filter;
}
public String getUuid() {
+ if (uuid == null) {
+ throw new UnsupportedOperationException(String.format("Component uuid of ref '%s' has not be fed yet", getRef()));
+ }
return uuid;
}
package org.sonar.server.computation.step;
import com.google.common.collect.Lists;
-import org.sonar.server.computation.ComputationContainer;
-
import java.util.Arrays;
import java.util.List;
+import org.sonar.server.computation.ComputationContainer;
/**
* Ordered list of steps to be executed
*/
public static List<Class<? extends ComputationStep>> orderedStepClasses() {
return Arrays.asList(
- FeedComponentUuidsStep.class,
+ PopulateComponentsUuidAndKeyStep.class,
// Read report
ParseReportStep.class,
+++ /dev/null
-/*
- * 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.api.utils.internal.Uuids;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentImpl;
-import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
-import org.sonar.server.db.DbClient;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Read all components from the batch report and set components uuid and key
- */
-public class FeedComponentUuidsStep implements ComputationStep {
-
- private final DbClient dbClient;
-
- public FeedComponentUuidsStep(DbClient dbClient) {
- this.dbClient = dbClient;
- }
-
- @Override
- public void execute(final ComputationContext context) {
- new ComponentDepthTraversalTypeAwareVisitor(context).visit(context.getRoot());
- }
-
- @Override
- public String getDescription() {
- return "Feed components uuid";
- }
-
- private class ComponentDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
-
- private BatchReportReader reportReader;
- private Map<String, String> componentUuidByKey;
- private String branch;
- private Component nearestModule;
-
- public ComponentDepthTraversalTypeAwareVisitor(ComputationContext context) {
- super(Component.Type.FILE, Order.PRE_ORDER);
- this.componentUuidByKey = new HashMap<>();
- this.branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null;
- this.reportReader = context.getReportReader();
- this.nearestModule = null;
- }
-
- @Override
- public void visitProject(Component project) {
- executeForProject(project);
- nearestModule = project;
- }
-
- @Override
- public void visitModule(Component module) {
- executeForModule(module);
- nearestModule = module;
- }
-
- @Override
- public void visitDirectory(Component directory) {
- executeForDirectoryAndFile(directory);
- }
-
- @Override
- public void visitFile(Component file) {
- executeForDirectoryAndFile(file);
- }
-
- private void executeForProject(Component component) {
- BatchReport.Component project = reportReader.readComponent(component.getRef());
- String projectKey = ComponentKeys.createKey(project.getKey(), branch);
- DbSession session = dbClient.openSession(false);
- try {
- List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, projectKey);
- for (ComponentDto componentDto : components) {
- componentUuidByKey.put(componentDto.getKey(), componentDto.uuid());
- }
-
- feedComponent((ComponentImpl) component, projectKey);
- } finally {
- session.close();
- }
- }
-
- private void executeForModule(Component component) {
- BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
- String componentKey = ComponentKeys.createKey(batchComponent.getKey(), branch);
- feedComponent((ComponentImpl) component, componentKey);
- }
-
- private void executeForDirectoryAndFile(Component component) {
- BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
- // TODO fail if path is null
- String componentKey = ComponentKeys.createEffectiveKey(nearestModule.getKey(), batchComponent.getPath());
- feedComponent((ComponentImpl) component, componentKey);
- }
-
- private void feedComponent(ComponentImpl projectImpl, String componentKey) {
- projectImpl.setKey(componentKey);
-
- String componentUuid = componentUuidByKey.get(componentKey);
- if (componentUuid == null) {
- projectImpl.setUuid(Uuids.create());
- } else {
- projectImpl.setUuid(componentUuid);
- }
- }
- }
-}
package org.sonar.server.computation.step;
+import java.util.List;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.issue.IssueComputation;
-import java.util.List;
-
public class ParseReportStep implements ComputationStep {
private final IssueComputation issueComputation;
}
@Override
- public void execute(final ComputationContext context) {
+ public void execute(ComputationContext context) {
IssueDepthTraversalTypeAwareVisitor visitor = new IssueDepthTraversalTypeAwareVisitor(context);
visitor.visit(context.getRoot());
processDeletedComponents(context, visitor);
package org.sonar.server.computation.step;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.db.DbClient;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
public class PersistComponentsStep implements ComputationStep {
private final DbClient dbClient;
}
private static String getFileQualifier(BatchReport.Component reportComponent) {
- return !reportComponent.getIsTest() ? Qualifiers.FILE : Qualifiers.UNIT_TEST_FILE;
+ return reportComponent.getIsTest() ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE;
}
@Override
--- /dev/null
+/*
+ * 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.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.internal.Uuids;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.ComponentImpl;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.db.DbClient;
+
+/**
+ * Read all components from the batch report and set components uuid and key
+ */
+public class PopulateComponentsUuidAndKeyStep implements ComputationStep {
+
+ private final DbClient dbClient;
+
+ public PopulateComponentsUuidAndKeyStep(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public void execute(ComputationContext context) {
+ new ComponentDepthTraversalTypeAwareVisitor(context).visit(context.getRoot());
+ }
+
+ @Override
+ public String getDescription() {
+ return "Feed components uuid";
+ }
+
+ private class ComponentDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
+
+ private final BatchReportReader reportReader;
+ private final Map<String, String> componentUuidByKey;
+
+ @Nullable
+ private final String branch;
+
+ private Component nearestModule;
+
+ public ComponentDepthTraversalTypeAwareVisitor(ComputationContext context) {
+ super(Component.Type.FILE, Order.PRE_ORDER);
+ this.componentUuidByKey = new HashMap<>();
+ this.branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null;
+ this.reportReader = context.getReportReader();
+ this.nearestModule = null;
+ }
+
+ @Override
+ public void visitProject(Component project) {
+ executeForProject(project);
+ nearestModule = project;
+ }
+
+ @Override
+ public void visitModule(Component module) {
+ executeForModule(module);
+ nearestModule = module;
+ }
+
+ @Override
+ public void visitDirectory(Component directory) {
+ executeForDirectoryAndFile(directory);
+ }
+
+ @Override
+ public void visitFile(Component file) {
+ executeForDirectoryAndFile(file);
+ }
+
+ private void executeForProject(Component component) {
+ BatchReport.Component project = reportReader.readComponent(component.getRef());
+ String projectKey = ComponentKeys.createKey(project.getKey(), branch);
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, projectKey);
+ for (ComponentDto componentDto : components) {
+ componentUuidByKey.put(componentDto.getKey(), componentDto.uuid());
+ }
+
+ feedComponent((ComponentImpl) component, projectKey);
+ } finally {
+ session.close();
+ }
+ }
+
+ private void executeForModule(Component component) {
+ BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+ String componentKey = ComponentKeys.createKey(batchComponent.getKey(), branch);
+ feedComponent((ComponentImpl) component, componentKey);
+ }
+
+ private void executeForDirectoryAndFile(Component component) {
+ BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+ // TODO fail if path is null
+ String componentKey = ComponentKeys.createEffectiveKey(nearestModule.getKey(), batchComponent.getPath());
+ feedComponent((ComponentImpl) component, componentKey);
+ }
+
+ private void feedComponent(ComponentImpl component, String componentKey) {
+ component.setKey(componentKey);
+
+ String componentUuid = componentUuidByKey.get(componentKey);
+ if (componentUuid == null) {
+ component.setUuid(Uuids.create());
+ } else {
+ component.setUuid(componentUuid);
+ }
+ }
+ }
+}
mock(PersistFileSourcesStep.class),
mock(PersistTestsStep.class),
mock(IndexTestsStep.class),
- mock(FeedComponentUuidsStep.class),
+ mock(PopulateComponentsUuidAndKeyStep.class),
mock(PersistComponentsStep.class),
mock(IndexTestsStep.class),
mock(QualityProfileEventsStep.class)
);
assertThat(registry.orderedSteps()).hasSize(20);
- assertThat(registry.orderedSteps().get(0)).isInstanceOf(FeedComponentUuidsStep.class);
+ assertThat(registry.orderedSteps().get(0)).isInstanceOf(PopulateComponentsUuidAndKeyStep.class);
assertThat(registry.orderedSteps().get(19)).isInstanceOf(SendIssueNotificationsStep.class);
}
+++ /dev/null
-/*
- * 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.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.config.Settings;
-import org.sonar.batch.protocol.Constants;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.DbTester;
-import org.sonar.server.component.db.ComponentDao;
-import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentTreeBuilders;
-import org.sonar.server.computation.language.LanguageRepository;
-import org.sonar.server.db.DbClient;
-import org.sonar.test.DbTests;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-@Category(DbTests.class)
-public class FeedComponentUuidsStepTest extends BaseStepTest {
-
- private static final String PROJECT_KEY = "PROJECT_KEY";
-
- @ClassRule
- public static DbTester dbTester = new DbTester();
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- File reportDir;
-
- DbSession session;
-
- DbClient dbClient;
-
- Settings projectSettings;
-
- LanguageRepository languageRepository = mock(LanguageRepository.class);
-
- FeedComponentUuidsStep sut;
-
- @Before
- public void setup() throws Exception {
- dbTester.truncateTables();
- session = dbTester.myBatis().openSession(false);
- dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
-
- reportDir = temp.newFolder();
-
- projectSettings = new Settings();
- sut = new FeedComponentUuidsStep(dbClient);
- }
-
- @Override
- protected ComputationStep step() {
- return sut;
- }
-
- @Test
- public void add_components() throws Exception {
- File reportDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(reportDir);
- writer.writeMetadata(BatchReport.Metadata.newBuilder()
- .setRootComponentRef(1)
- .build());
-
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(1)
- .setType(Constants.ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .addChildRef(2)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(2)
- .setType(Constants.ComponentType.MODULE)
- .setKey("MODULE_KEY")
- .addChildRef(3)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(3)
- .setType(Constants.ComponentType.DIRECTORY)
- .setPath("src/main/java/dir")
- .addChildRef(4)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(4)
- .setType(Constants.ComponentType.FILE)
- .setPath("src/main/java/dir/Foo.java")
- .build());
-
- BatchReportReader batchReportReader = new BatchReportReader(reportDir);
- ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
- dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
- sut.execute(context);
-
- Map<Integer, Component> componentsByRef = getComponentsByRef(context.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 use_latest_module_for_files_key() throws Exception {
- File reportDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(reportDir);
- writer.writeMetadata(BatchReport.Metadata.newBuilder()
- .setRootComponentRef(1)
- .build());
-
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(1)
- .setType(Constants.ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .setName("Project")
- .addChildRef(2)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(2)
- .setType(Constants.ComponentType.MODULE)
- .setKey("MODULE_KEY")
- .setName("Module")
- .addChildRef(3)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(3)
- .setType(Constants.ComponentType.MODULE)
- .setKey("SUB_MODULE_KEY")
- .setName("Sub Module")
- .addChildRef(4)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(4)
- .setType(Constants.ComponentType.DIRECTORY)
- .setPath("src/main/java/dir")
- .addChildRef(5)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(5)
- .setType(Constants.ComponentType.FILE)
- .setPath("src/main/java/dir/Foo.java")
- .build());
-
- BatchReportReader batchReportReader = new BatchReportReader(reportDir);
- ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
- dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
- sut.execute(context);
-
- Map<Integer, Component> componentsByRef = getComponentsByRef(context.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() throws Exception {
- File reportDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(reportDir);
- writer.writeMetadata(BatchReport.Metadata.newBuilder()
- .setRootComponentRef(1)
- .setBranch("origin/master")
- .setProjectKey("")
- .build());
-
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(1)
- .setType(Constants.ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .setName("Project")
- .addChildRef(2)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(2)
- .setType(Constants.ComponentType.MODULE)
- .setKey("MODULE_KEY")
- .setName("Module")
- .addChildRef(3)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(3)
- .setType(Constants.ComponentType.DIRECTORY)
- .setPath("src/main/java/dir")
- .addChildRef(4)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(4)
- .setType(Constants.ComponentType.FILE)
- .setPath("src/main/java/dir/Foo.java")
- .build());
-
- BatchReportReader batchReportReader = new BatchReportReader(reportDir);
- ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
- dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
- sut.execute(context);
-
- Map<Integer, Component> componentsByRef = getComponentsByRef(context.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");
- }
-
- 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.getRef(), component);
- for (Component child : component.getChildren()) {
- feedComponentByRef(child, map);
- }
- }
-
-}
package org.sonar.server.computation.step;
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.sonar.server.source.db.FileSourceDao;
import org.sonar.server.source.db.FileSourceDb;
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
--- /dev/null
+/*
+ * 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.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.config.Settings;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.ComponentTreeBuilders;
+import org.sonar.server.computation.language.LanguageRepository;
+import org.sonar.server.db.DbClient;
+import org.sonar.test.DbTests;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+@Category(DbTests.class)
+public class PopulateComponentsUuidAndKeyStepTest extends BaseStepTest {
+
+ private static final String PROJECT_KEY = "PROJECT_KEY";
+
+ @ClassRule
+ public static DbTester dbTester = new DbTester();
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ File reportDir;
+
+ DbSession session;
+
+ DbClient dbClient;
+
+ Settings projectSettings;
+
+ LanguageRepository languageRepository = mock(LanguageRepository.class);
+
+ PopulateComponentsUuidAndKeyStep sut;
+
+ @Before
+ public void setup() throws Exception {
+ dbTester.truncateTables();
+ session = dbTester.myBatis().openSession(false);
+ dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+
+ reportDir = temp.newFolder();
+
+ projectSettings = new Settings();
+ sut = new PopulateComponentsUuidAndKeyStep(dbClient);
+ }
+
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
+
+ @Test
+ public void add_components() throws Exception {
+ File reportDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(reportDir);
+ writer.writeMetadata(BatchReport.Metadata.newBuilder()
+ .setRootComponentRef(1)
+ .build());
+
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(1)
+ .setType(Constants.ComponentType.PROJECT)
+ .setKey(PROJECT_KEY)
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/main/java/dir")
+ .addChildRef(4)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(4)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/main/java/dir/Foo.java")
+ .build());
+
+ BatchReportReader batchReportReader = new BatchReportReader(reportDir);
+ ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
+ dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
+ sut.execute(context);
+
+ Map<Integer, Component> componentsByRef = getComponentsByRef(context.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 use_latest_module_for_files_key() throws Exception {
+ File reportDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(reportDir);
+ writer.writeMetadata(BatchReport.Metadata.newBuilder()
+ .setRootComponentRef(1)
+ .build());
+
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(1)
+ .setType(Constants.ComponentType.PROJECT)
+ .setKey(PROJECT_KEY)
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("SUB_MODULE_KEY")
+ .setName("Sub Module")
+ .addChildRef(4)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(4)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/main/java/dir")
+ .addChildRef(5)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(5)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/main/java/dir/Foo.java")
+ .build());
+
+ BatchReportReader batchReportReader = new BatchReportReader(reportDir);
+ ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
+ dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
+ sut.execute(context);
+
+ Map<Integer, Component> componentsByRef = getComponentsByRef(context.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() throws Exception {
+ File reportDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(reportDir);
+ writer.writeMetadata(BatchReport.Metadata.newBuilder()
+ .setRootComponentRef(1)
+ .setBranch("origin/master")
+ .setProjectKey("")
+ .build());
+
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(1)
+ .setType(Constants.ComponentType.PROJECT)
+ .setKey(PROJECT_KEY)
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/main/java/dir")
+ .addChildRef(4)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(4)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/main/java/dir/Foo.java")
+ .build());
+
+ BatchReportReader batchReportReader = new BatchReportReader(reportDir);
+ ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
+ dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
+ sut.execute(context);
+
+ Map<Integer, Component> componentsByRef = getComponentsByRef(context.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");
+ }
+
+ 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.getRef(), component);
+ for (Component child : component.getChildren()) {
+ feedComponentByRef(child, map);
+ }
+ }
+
+}
package org.sonar.server.computation.step;
+import java.io.File;
+import java.io.IOException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.server.computation.language.LanguageRepository;
import org.sonar.server.db.DbClient;
-import java.io.File;
-import java.io.IOException;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;