From 5fadc715d37aea7067e1c7308c218af40ce96327 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Mon, 8 Jun 2015 09:48:38 +0200 Subject: [PATCH] SONAR-6260 Split persistence of snapshots and projects --- .../container/ComputeEngineContainerImpl.java | 7 +- .../computation/step/ComputationSteps.java | 3 +- ...tsStep.java => PersistComponentsStep.java} | 135 ++----- .../step/PersistSnapshotsStep.java | 160 ++++++++ ...st.java => PersistComponentsStepTest.java} | 216 +---------- .../step/PersistSnapshotStepTest.java | 360 ++++++++++++++++++ 6 files changed, 574 insertions(+), 307 deletions(-) rename server/sonar-server/src/main/java/org/sonar/server/computation/step/{PersistComponentsAndSnapshotsStep.java => PersistComponentsStep.java} (63%) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistSnapshotsStep.java rename server/sonar-server/src/test/java/org/sonar/server/computation/step/{PersistComponentsAndSnapshotsStepTest.java => PersistComponentsStepTest.java} (76%) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotStepTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java index 897160138c1..103dc9ce2e9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java @@ -50,6 +50,8 @@ 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.period.PeriodFinder; +import org.sonar.server.computation.period.PeriodsRepository; import org.sonar.server.computation.step.ComputationStep; import org.sonar.server.computation.step.ComputationSteps; import org.sonar.server.view.index.ViewIndex; @@ -119,13 +121,14 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co BatchReportDirectoryHolderImpl.class, + PeriodFinder.class, + // repositories PlatformLanguageRepository.class, MeasureRepositoryImpl.class, EventRepositoryImpl.class, ProjectSettingsRepository.class, - - // component caches + PeriodsRepository.class, DbIdsRepository.class, // issues diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java index d492deabb5c..36492c13f77 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java @@ -52,7 +52,8 @@ public class ComputationSteps { QualityGateEventsStep.class, // Persist data - PersistComponentsAndSnapshotsStep.class, + PersistComponentsStep.class, + PersistSnapshotsStep.class, PersistNumberOfDaysSinceLastCommitStep.class, PersistMeasuresStep.class, PersistIssuesStep.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java similarity index 63% rename from server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java rename to server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java index 206752d756c..63014c5abc5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java @@ -29,10 +29,8 @@ import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; -import org.sonar.api.utils.System2; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; import org.sonar.core.persistence.DbSession; import org.sonar.core.util.NonNullInputFunction; import org.sonar.server.computation.batch.BatchReportReader; @@ -42,20 +40,18 @@ import org.sonar.server.computation.component.TreeRootHolder; import org.sonar.server.db.DbClient; /** - * Persist components and snapshots - * Also feed the components cache {@link DbIdsRepository} + * Persist components + * Also feed the components cache {@link DbIdsRepository} with component ids */ -public class PersistComponentsAndSnapshotsStep implements ComputationStep { +public class PersistComponentsStep implements ComputationStep { - private final System2 system2; private final DbClient dbClient; private final TreeRootHolder treeRootHolder; private final BatchReportReader reportReader; private final DbIdsRepository dbIdsRepository; - public PersistComponentsAndSnapshotsStep(System2 system2, DbClient dbClient, TreeRootHolder treeRootHolder, BatchReportReader reportReader, DbIdsRepository dbIdsRepository) { - this.system2 = system2; + public PersistComponentsStep(DbClient dbClient, TreeRootHolder treeRootHolder, BatchReportReader reportReader, DbIdsRepository dbIdsRepository) { this.dbClient = dbClient; this.treeRootHolder = treeRootHolder; this.reportReader = reportReader; @@ -67,63 +63,58 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { DbSession session = dbClient.openSession(false); try { org.sonar.server.computation.component.Component root = treeRootHolder.getRoot(); - List components = dbClient.componentDao().selectComponentsFromProjectKey(session, root.getKey()); - Map componentDtosByKey = componentDtosByKey(components); - PersisComponentExecutor componentContext = new PersisComponentExecutor(session, componentDtosByKey, reportReader, reportReader.readMetadata().getAnalysisDate()); + List existingComponents = dbClient.componentDao().selectComponentsFromProjectKey(session, root.getKey()); + Map existingComponentDtosByKey = componentDtosByKey(existingComponents); + PersisComponent persisComponent = new PersisComponent(session, existingComponentDtosByKey, reportReader); - componentContext.recursivelyProcessComponent(root, null, null); + persisComponent.recursivelyProcessComponent(root, null); session.commit(); } finally { session.close(); } } - private class PersisComponentExecutor { + private class PersisComponent { private final BatchReportReader reportReader; - private final Map componentDtosByKey; + private final Map existingComponentDtosByKey; private final DbSession dbSession; - private final long analysisDate; private ComponentDto project; - private SnapshotDto projectSnapshot; - public PersisComponentExecutor(DbSession dbSession, Map componentDtosByKey, BatchReportReader reportReader, long analysisDate) { + public PersisComponent(DbSession dbSession, Map existingComponentDtosByKey, BatchReportReader reportReader) { this.reportReader = reportReader; - this.componentDtosByKey = componentDtosByKey; + this.existingComponentDtosByKey = existingComponentDtosByKey; this.dbSession = dbSession; - this.analysisDate = analysisDate; } - private void recursivelyProcessComponent(Component component, @Nullable ComponentDto lastModule, @Nullable SnapshotDto parentSnapshot) { + private void recursivelyProcessComponent(Component component, @Nullable ComponentDto lastModule) { BatchReport.Component reportComponent = reportReader.readComponent(component.getRef()); switch (component.getType()) { case PROJECT: - PersistedComponent persistedProject = processProject(component, reportComponent); - this.project = persistedProject.componentDto; - this.projectSnapshot = persistedProject.parentSnapshot; - processChildren(component, project, persistedProject.parentSnapshot); + this.project = processProject(component, reportComponent); + processChildren(component, project); break; case MODULE: - PersistedComponent persistedModule = processModule(component, reportComponent, nonNullLastModule(lastModule), nonNullParentSnapshot(parentSnapshot)); - processChildren(component, persistedModule.componentDto, persistedModule.parentSnapshot); + ComponentDto persistedModule = processModule(component, reportComponent, nonNullLastModule(lastModule)); + processChildren(component, persistedModule); break; case DIRECTORY: - PersistedComponent persistedDirectory = processDirectory(component, reportComponent, nonNullLastModule(lastModule), nonNullParentSnapshot(parentSnapshot)); - processChildren(component, nonNullLastModule(lastModule), persistedDirectory.parentSnapshot); + processDirectory(component, reportComponent, nonNullLastModule(lastModule)); + processChildren(component, nonNullLastModule(lastModule)); break; case FILE: - processFile(component, reportComponent, nonNullLastModule(lastModule), nonNullParentSnapshot(parentSnapshot)); + processFile(component, reportComponent, nonNullLastModule(lastModule)); break; default: throw new IllegalStateException(String.format("Unsupported component type '%s'", component.getType())); } } - private void processChildren(Component component, ComponentDto lastModule, SnapshotDto parentSnapshot) { + private void processChildren(Component component, ComponentDto lastModule) { for (Component child : component.getChildren()) { - recursivelyProcessComponent(child, lastModule, parentSnapshot); + recursivelyProcessComponent(child, lastModule); } } @@ -131,11 +122,7 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { return lastModule == null ? project : lastModule; } - private SnapshotDto nonNullParentSnapshot(@Nullable SnapshotDto parentSnapshot) { - return parentSnapshot == null ? projectSnapshot : parentSnapshot; - } - - public PersistedComponent processProject(Component project, BatchReport.Component reportComponent) { + public ComponentDto processProject(Component project, BatchReport.Component reportComponent) { ComponentDto componentDto = createComponentDto(reportComponent, project); componentDto.setScope(Scopes.PROJECT); @@ -149,14 +136,11 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(ComponentDto.MODULE_UUID_PATH_SEP + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP); ComponentDto projectDto = persistComponent(project.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(projectDto, projectDto.getId(), reportComponent.getVersion(), null); - - addToCache(project, projectDto, snapshotDto); - - return new PersistedComponent(projectDto, snapshotDto); + addToCache(project, projectDto); + return projectDto; } - public PersistedComponent processModule(Component module, BatchReport.Component reportComponent, ComponentDto lastModule, SnapshotDto parentSnapshot) { + public ComponentDto processModule(Component module, BatchReport.Component reportComponent, ComponentDto lastModule) { ComponentDto componentDto = createComponentDto(reportComponent, module); componentDto.setScope(Scopes.PROJECT); @@ -175,14 +159,11 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath() + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP); ComponentDto moduleDto = persistComponent(module.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(moduleDto, project.getId(), reportComponent.getVersion(), parentSnapshot); - - addToCache(module, moduleDto, snapshotDto); - return new PersistedComponent(moduleDto, snapshotDto); + addToCache(module, moduleDto); + return moduleDto; } - public PersistedComponent processDirectory(org.sonar.server.computation.component.Component directory, BatchReport.Component reportComponent, - ComponentDto lastModule, SnapshotDto parentSnapshot) { + public ComponentDto processDirectory(org.sonar.server.computation.component.Component directory, BatchReport.Component reportComponent, ComponentDto lastModule) { ComponentDto componentDto = createComponentDto(reportComponent, directory); componentDto.setScope(Scopes.DIRECTORY); @@ -199,14 +180,11 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath()); ComponentDto directoryDto = persistComponent(directory.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(directoryDto, project.getId(), null, parentSnapshot); - - addToCache(directory, directoryDto, snapshotDto); - return new PersistedComponent(directoryDto, snapshotDto); + addToCache(directory, directoryDto); + return directoryDto; } - public void processFile(org.sonar.server.computation.component.Component file, BatchReport.Component reportComponent, - ComponentDto lastModule, SnapshotDto parentSnapshot) { + public void processFile(org.sonar.server.computation.component.Component file, BatchReport.Component reportComponent, ComponentDto lastModule) { ComponentDto componentDto = createComponentDto(reportComponent, file); componentDto.setScope(Scopes.FILE); @@ -226,13 +204,11 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath()); ComponentDto fileDto = persistComponent(file.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(fileDto, project.getId(), null, parentSnapshot); - - addToCache(file, fileDto, snapshotDto); + addToCache(file, fileDto); } private ComponentDto persistComponent(int componentRef, ComponentDto componentDto) { - ComponentDto existingComponent = componentDtosByKey.get(componentDto.getKey()); + ComponentDto existingComponent = existingComponentDtosByKey.get(componentDto.getKey()); if (existingComponent == null) { dbClient.componentDao().insert(dbSession, componentDto); return componentDto; @@ -244,37 +220,10 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { } } - private SnapshotDto persistSnapshot(ComponentDto componentDto, long projectId, @Nullable String version, @Nullable SnapshotDto parentSnapshot){ - SnapshotDto snapshotDto = new SnapshotDto() - .setRootProjectId(projectId) - .setVersion(version) - .setComponentId(componentDto.getId()) - .setQualifier(componentDto.qualifier()) - .setScope(componentDto.scope()) - .setLast(false) - .setStatus(SnapshotDto.STATUS_UNPROCESSED) - .setCreatedAt(analysisDate) - .setBuildDate(system2.now()); - - if (parentSnapshot != null) { - snapshotDto - .setParentId(parentSnapshot.getId()) - .setRootId(parentSnapshot.getRootId() == null ? parentSnapshot.getId() : parentSnapshot.getRootId()) - .setDepth(parentSnapshot.getDepth() + 1) - .setPath(parentSnapshot.getPath() + parentSnapshot.getId() + "."); - } else { - snapshotDto - .setPath("") - .setDepth(0); - } - dbClient.snapshotDao().insert(dbSession, snapshotDto); - return snapshotDto; - } - - private void addToCache(Component component, ComponentDto componentDto, SnapshotDto snapshotDto) { + private void addToCache(Component component, ComponentDto componentDto) { dbIdsRepository.setComponentId(component, componentDto.getId()); - dbIdsRepository.setSnapshotId(component, snapshotDto.getId()); } + } private static ComponentDto createComponentDto(BatchReport.Component reportComponent, Component component) { @@ -331,18 +280,8 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { }); } - private static class PersistedComponent { - private ComponentDto componentDto; - private SnapshotDto parentSnapshot; - - public PersistedComponent(ComponentDto componentDto, SnapshotDto parentSnapshot) { - this.componentDto = componentDto; - this.parentSnapshot = parentSnapshot; - } - } - @Override public String getDescription() { - return "Feed components and snapshots"; + return "Persist components"; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistSnapshotsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistSnapshotsStep.java new file mode 100644 index 00000000000..df2111a9644 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistSnapshotsStep.java @@ -0,0 +1,160 @@ +/* + * 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 javax.annotation.Nullable; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.System2; +import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.core.component.SnapshotDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.computation.batch.BatchReportReader; +import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.component.DbIdsRepository; +import org.sonar.server.computation.component.TreeRootHolder; +import org.sonar.server.db.DbClient; + +/** + * Persist snapshots + * Also feed the components cache {@link DbIdsRepository} with snapshot ids + */ +public class PersistSnapshotsStep implements ComputationStep { + + private final System2 system2; + private final DbClient dbClient; + private final TreeRootHolder treeRootHolder; + private final BatchReportReader reportReader; + + private final DbIdsRepository dbIdsRepository; + + public PersistSnapshotsStep(System2 system2, DbClient dbClient, TreeRootHolder treeRootHolder, BatchReportReader reportReader, DbIdsRepository dbIdsRepository) { + this.system2 = system2; + this.dbClient = dbClient; + this.treeRootHolder = treeRootHolder; + this.reportReader = reportReader; + this.dbIdsRepository = dbIdsRepository; + } + + @Override + public void execute() { + DbSession session = dbClient.openSession(false); + try { + Component root = treeRootHolder.getRoot(); + ProcessPersistSnapshot processPersistSnapshot = new ProcessPersistSnapshot(session, reportReader, reportReader.readMetadata().getAnalysisDate()); + processPersistSnapshot.process(root, null); + session.commit(); + } finally { + session.close(); + } + } + + private class ProcessPersistSnapshot { + + private final BatchReportReader reportReader; + private final DbSession dbSession; + private final long analysisDate; + + private long projectId; + + public ProcessPersistSnapshot(DbSession dbSession, BatchReportReader reportReader, long analysisDate) { + this.reportReader = reportReader; + this.dbSession = dbSession; + this.analysisDate = analysisDate; + } + + private void process(Component component, @Nullable SnapshotDto parentSnapshot) { + BatchReport.Component reportComponent = reportReader.readComponent(component.getRef()); + long componentId = dbIdsRepository.getComponentId(component); + + switch (component.getType()) { + case PROJECT: + this.projectId = componentId; + SnapshotDto projectSnapshot = persistSnapshot(componentId, Qualifiers.PROJECT, Scopes.PROJECT, reportComponent.getVersion(), parentSnapshot); + addToCache(component, projectSnapshot); + processChildren(component, projectSnapshot); + break; + case MODULE: + SnapshotDto moduleSnapshot = persistSnapshot(componentId, Qualifiers.MODULE, Scopes.PROJECT, reportComponent.getVersion(), parentSnapshot); + addToCache(component, moduleSnapshot); + processChildren(component, moduleSnapshot); + break; + case DIRECTORY: + SnapshotDto directorySnapshot = persistSnapshot(componentId, Qualifiers.DIRECTORY, Scopes.DIRECTORY, null, parentSnapshot); + addToCache(component, directorySnapshot); + processChildren(component, directorySnapshot); + break; + case FILE: + SnapshotDto fileSnapshot = persistSnapshot(componentId, getFileQualifier(reportComponent), Scopes.FILE, null, parentSnapshot); + addToCache(component, fileSnapshot); + break; + default: + throw new IllegalStateException(String.format("Unsupported component type '%s'", component.getType())); + } + } + + private void processChildren(Component component, SnapshotDto parentSnapshot) { + for (Component child : component.getChildren()) { + process(child, parentSnapshot); + } + } + + private SnapshotDto persistSnapshot(long componentId, String qualifier, String scope, @Nullable String version, @Nullable SnapshotDto parentSnapshot) { + SnapshotDto snapshotDto = new SnapshotDto() + .setRootProjectId(projectId) + .setVersion(version) + .setComponentId(componentId) + .setQualifier(qualifier) + .setScope(scope) + .setLast(false) + .setStatus(SnapshotDto.STATUS_UNPROCESSED) + .setCreatedAt(analysisDate) + .setBuildDate(system2.now()); + + if (parentSnapshot != null) { + snapshotDto + .setParentId(parentSnapshot.getId()) + .setRootId(parentSnapshot.getRootId() == null ? parentSnapshot.getId() : parentSnapshot.getRootId()) + .setDepth(parentSnapshot.getDepth() + 1) + .setPath(parentSnapshot.getPath() + parentSnapshot.getId() + "."); + } else { + snapshotDto + .setPath("") + .setDepth(0); + } + dbClient.snapshotDao().insert(dbSession, snapshotDto); + return snapshotDto; + } + + private void addToCache(Component component, SnapshotDto snapshotDto) { + dbIdsRepository.setSnapshotId(component, snapshotDto.getId()); + } + } + + private static String getFileQualifier(BatchReport.Component reportComponent) { + return reportComponent.getIsTest() ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE; + } + + @Override + public String getDescription() { + return "Persist snapshots"; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java similarity index 76% rename from server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java rename to server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java index becc43aacde..d9b46a0c897 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java @@ -20,18 +20,16 @@ package org.sonar.server.computation.step; -import java.util.List; +import java.text.SimpleDateFormat; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; 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.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.DbTester; import org.sonar.server.component.ComponentTesting; @@ -46,15 +44,13 @@ 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; -import static org.mockito.Mockito.when; @Category(DbTests.class) -public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { +public class PersistComponentsStepTest extends BaseStepTest { + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); private static final String PROJECT_KEY = "PROJECT_KEY"; - private static final long ANALYSIS_DATE = 1000; - private static final long NOW = 2000; @ClassRule public static DbTester dbTester = new DbTester(); @@ -65,29 +61,27 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { @Rule public BatchReportReaderRule reportReader = new BatchReportReaderRule(); - System2 system2 = mock(System2.class); - DbIdsRepository dbIdsRepository; DbSession session; DbClient dbClient; - PersistComponentsAndSnapshotsStep sut; + long now; + + PersistComponentsStep sut; @Before public void setup() throws Exception { dbTester.truncateTables(); session = dbTester.myBatis().openSession(false); dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao()); - reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setAnalysisDate(ANALYSIS_DATE) - .build()); + dbIdsRepository = new DbIdsRepository(); - when(system2.now()).thenReturn(NOW); + now = DATE_FORMAT.parse("2015-06-02").getTime(); - sut = new PersistComponentsAndSnapshotsStep(system2, dbClient, treeRootHolder, reportReader, dbIdsRepository); + sut = new PersistComponentsStep( dbClient, treeRootHolder, reportReader, dbIdsRepository); } @Override @@ -201,118 +195,6 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); } - @Test - public void persist_snapshots() throws Exception { - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .setKey(PROJECT_KEY) - .setName("Project") - .setVersion("1.0") - .addChildRef(2) - .build()); - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(2) - .setType(Constants.ComponentType.MODULE) - .setKey("MODULE_KEY") - .setPath("module") - .setName("Module") - .setVersion("1.1") - .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") - .setLanguage("java") - .build()); - - Component file = new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java"); - Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir", file); - Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", directory); - Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module); - treeRootHolder.setRoot(project); - - sut.execute(); - - assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); - - ComponentDto projectDto = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY); - SnapshotDto projectSnapshot = getSnapshot(projectDto.getId()); - assertThat(projectSnapshot.getComponentId()).isEqualTo(projectDto.getId()); - assertThat(projectSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); - assertThat(projectSnapshot.getRootId()).isNull(); - assertThat(projectSnapshot.getParentId()).isNull(); - assertThat(projectSnapshot.getDepth()).isEqualTo(0); - assertThat(projectSnapshot.getPath()).isEqualTo(""); - assertThat(projectSnapshot.getQualifier()).isEqualTo("TRK"); - assertThat(projectSnapshot.getScope()).isEqualTo("PRJ"); - assertThat(projectSnapshot.getVersion()).isEqualTo("1.0"); - assertThat(projectSnapshot.getLast()).isFalse(); - assertThat(projectSnapshot.getStatus()).isEqualTo("U"); - assertThat(projectSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); - assertThat(projectSnapshot.getBuildDate()).isEqualTo(NOW); - - ComponentDto moduleDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY"); - SnapshotDto moduleSnapshot = getSnapshot(moduleDto.getId()); - assertThat(moduleSnapshot.getComponentId()).isEqualTo(moduleDto.getId()); - assertThat(moduleSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); - assertThat(moduleSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); - assertThat(moduleSnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); - assertThat(moduleSnapshot.getDepth()).isEqualTo(1); - assertThat(moduleSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); - assertThat(moduleSnapshot.getQualifier()).isEqualTo("BRC"); - assertThat(moduleSnapshot.getScope()).isEqualTo("PRJ"); - assertThat(moduleSnapshot.getVersion()).isEqualTo("1.1"); - assertThat(moduleSnapshot.getLast()).isFalse(); - assertThat(moduleSnapshot.getStatus()).isEqualTo("U"); - assertThat(moduleSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); - assertThat(moduleSnapshot.getBuildDate()).isEqualTo(NOW); - - ComponentDto directoryDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir"); - SnapshotDto directorySnapshot = getSnapshot(directoryDto.getId()); - assertThat(directorySnapshot.getComponentId()).isEqualTo(directoryDto.getId()); - assertThat(directorySnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); - assertThat(directorySnapshot.getRootId()).isEqualTo(projectDto.getId()); - assertThat(directorySnapshot.getParentId()).isEqualTo(moduleDto.getId()); - assertThat(directorySnapshot.getDepth()).isEqualTo(2); - assertThat(directorySnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleDto.getId() + "."); - assertThat(directorySnapshot.getQualifier()).isEqualTo("DIR"); - assertThat(directorySnapshot.getScope()).isEqualTo("DIR"); - assertThat(directorySnapshot.getVersion()).isNull(); - assertThat(directorySnapshot.getLast()).isFalse(); - assertThat(directorySnapshot.getStatus()).isEqualTo("U"); - assertThat(directorySnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); - assertThat(directorySnapshot.getBuildDate()).isEqualTo(NOW); - - ComponentDto fileDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java"); - SnapshotDto fileSnapshot = getSnapshot(fileDto.getId()); - assertThat(fileSnapshot.getComponentId()).isEqualTo(fileDto.getId()); - assertThat(fileSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); - assertThat(fileSnapshot.getRootId()).isEqualTo(projectDto.getId()); - assertThat(fileSnapshot.getParentId()).isEqualTo(directoryDto.getId()); - assertThat(fileSnapshot.getDepth()).isEqualTo(3); - assertThat(fileSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleDto.getId() + "." + directoryDto.getId() + "."); - assertThat(fileSnapshot.getQualifier()).isEqualTo("FIL"); - assertThat(fileSnapshot.getScope()).isEqualTo("FIL"); - assertThat(fileSnapshot.getVersion()).isNull(); - assertThat(fileSnapshot.getLast()).isFalse(); - assertThat(fileSnapshot.getStatus()).isEqualTo("U"); - assertThat(fileSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); - assertThat(fileSnapshot.getBuildDate()).isEqualTo(NOW); - - assertThat(dbIdsRepository.getSnapshotId(project)).isEqualTo(projectSnapshot.getId()); - assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId()); - assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId()); - assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); - } - @Test public void persist_file_directly_attached_on_root_directory() throws Exception { reportReader.putComponent(BatchReport.Component.newBuilder() @@ -601,78 +483,6 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(moduleB.parentProjectId()).isEqualTo(project.getId()); } - @Test - public void persist_snapshots_on_multi_modules() throws Exception { - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .setKey(PROJECT_KEY) - .setName("Project") - .addChildRef(2) - .addChildRef(4) - .build()); - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(2) - .setType(Constants.ComponentType.MODULE) - .setKey("MODULE_A") - .setName("Module A") - .addChildRef(3) - .build()); - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(3) - .setType(Constants.ComponentType.MODULE) - .setKey("SUB_MODULE_A") - .setName("Sub Module A") - .build()); - reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(4) - .setType(Constants.ComponentType.MODULE) - .setKey("MODULE_B") - .setName("Module B") - .build()); - - treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, - new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_A", - new DumbComponent(Component.Type.MODULE, 3, "DEFG", "SUB_MODULE_A")), - new DumbComponent(Component.Type.MODULE, 4, "CDEF", "MODULE_B"))); - - sut.execute(); - - assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); - - ComponentDto project = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY); - SnapshotDto projectSnapshot = getSnapshot(project.getId()); - assertThat(projectSnapshot.getRootProjectId()).isEqualTo(project.getId()); - assertThat(projectSnapshot.getRootId()).isNull(); - assertThat(projectSnapshot.getParentId()).isNull(); - assertThat(projectSnapshot.getDepth()).isEqualTo(0); - assertThat(projectSnapshot.getPath()).isEqualTo(""); - - ComponentDto moduleA = dbClient.componentDao().selectNullableByKey(session, "MODULE_A"); - SnapshotDto moduleASnapshot = getSnapshot(moduleA.getId()); - assertThat(moduleASnapshot.getRootProjectId()).isEqualTo(project.getId()); - assertThat(moduleASnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); - assertThat(moduleASnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); - assertThat(moduleASnapshot.getDepth()).isEqualTo(1); - assertThat(moduleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); - - ComponentDto subModuleA = dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_A"); - SnapshotDto subModuleASnapshot = getSnapshot(subModuleA.getId()); - assertThat(subModuleASnapshot.getRootProjectId()).isEqualTo(project.getId()); - assertThat(subModuleASnapshot.getRootId()).isEqualTo(project.getId()); - assertThat(subModuleASnapshot.getParentId()).isEqualTo(moduleA.getId()); - assertThat(subModuleASnapshot.getDepth()).isEqualTo(2); - assertThat(subModuleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleA.getId() + "."); - - ComponentDto moduleB = dbClient.componentDao().selectNullableByKey(session, "MODULE_B"); - SnapshotDto moduleBSnapshot = getSnapshot(moduleB.getId()); - assertThat(moduleBSnapshot.getRootProjectId()).isEqualTo(project.getId()); - assertThat(moduleBSnapshot.getRootId()).isEqualTo(project.getId()); - assertThat(moduleBSnapshot.getParentId()).isEqualTo(project.getId()); - assertThat(moduleBSnapshot.getDepth()).isEqualTo(1); - assertThat(moduleBSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." ); - } - @Test public void nothing_to_persist() throws Exception { ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project"); @@ -957,10 +767,4 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(fileReloaded.parentProjectId()).isEqualTo(moduleBReloaded.getId()); } - private SnapshotDto getSnapshot(long componentId){ - List projectSnapshots = dbClient.snapshotDao().selectSnapshotsByComponentId(session, componentId); - assertThat(projectSnapshots).hasSize(1); - return projectSnapshots.get(0); - } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotStepTest.java new file mode 100644 index 00000000000..c176c66f4b1 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotStepTest.java @@ -0,0 +1,360 @@ +/* + * 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.text.SimpleDateFormat; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +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.core.component.ComponentDto; +import org.sonar.core.component.SnapshotDto; +import org.sonar.core.component.SnapshotQuery; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.component.db.SnapshotDao; +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.DbIdsRepository; +import org.sonar.server.computation.component.DumbComponent; +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; +import static org.mockito.Mockito.when; + +@Category(DbTests.class) +public class PersistSnapshotStepTest extends BaseStepTest { + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + + private static final String PROJECT_KEY = "PROJECT_KEY"; + + @ClassRule + public static DbTester dbTester = new DbTester(); + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); + + System2 system2 = mock(System2.class); + + DbIdsRepository dbIdsRepository; + + DbSession session; + + DbClient dbClient; + + long analysisDate; + + long now; + + PersistSnapshotsStep sut; + + @Before + public void setup() throws Exception { + dbTester.truncateTables(); + session = dbTester.myBatis().openSession(false); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao()); + + analysisDate = DATE_FORMAT.parse("2015-06-01").getTime(); + reportReader.setMetadata(BatchReport.Metadata.newBuilder() + .setAnalysisDate(analysisDate) + .build()); + dbIdsRepository = new DbIdsRepository(); + + now = DATE_FORMAT.parse("2015-06-02").getTime(); + + when(system2.now()).thenReturn(now); + + sut = new PersistSnapshotsStep(system2, dbClient, treeRootHolder, reportReader, dbIdsRepository); + } + + @Override + protected ComputationStep step() { + return sut; + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void persist_snapshots() throws Exception { + ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project"); + dbClient.componentDao().insert(session, projectDto); + ComponentDto moduleDto = ComponentTesting.newModuleDto("BCDE", projectDto).setKey("MODULE_KEY").setName("Module"); + dbClient.componentDao().insert(session, moduleDto); + ComponentDto directoryDto = ComponentTesting.newDirectory(moduleDto, "CDEF", "MODULE_KEY:src/main/java/dir").setKey("MODULE_KEY:src/main/java/dir"); + dbClient.componentDao().insert(session, directoryDto); + ComponentDto fileDto = ComponentTesting.newFileDto(moduleDto, "DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java"); + dbClient.componentDao().insert(session, fileDto); + session.commit(); + + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .setVersion("1.0") + .addChildRef(2) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(2) + .setType(Constants.ComponentType.MODULE) + .setVersion("1.1") + .addChildRef(3) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(3) + .setType(Constants.ComponentType.DIRECTORY) + .addChildRef(4) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(4) + .setType(Constants.ComponentType.FILE) + .build()); + + Component file = new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java"); + Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir", file); + Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", directory); + Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module); + treeRootHolder.setRoot(project); + + dbIdsRepository.setComponentId(project, projectDto.getId()); + dbIdsRepository.setComponentId(module, moduleDto.getId()); + dbIdsRepository.setComponentId(directory, directoryDto.getId()); + dbIdsRepository.setComponentId(file, fileDto.getId()); + + sut.execute(); + + assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); + + SnapshotDto projectSnapshot = getUnprocessedSnapshot(projectDto.getId()); + assertThat(projectSnapshot.getComponentId()).isEqualTo(projectDto.getId()); + assertThat(projectSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(projectSnapshot.getRootId()).isNull(); + assertThat(projectSnapshot.getParentId()).isNull(); + assertThat(projectSnapshot.getDepth()).isEqualTo(0); + assertThat(projectSnapshot.getPath()).isEqualTo(""); + assertThat(projectSnapshot.getQualifier()).isEqualTo("TRK"); + assertThat(projectSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(projectSnapshot.getVersion()).isEqualTo("1.0"); + assertThat(projectSnapshot.getLast()).isFalse(); + assertThat(projectSnapshot.getStatus()).isEqualTo("U"); + assertThat(projectSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(projectSnapshot.getBuildDate()).isEqualTo(now); + + SnapshotDto moduleSnapshot = getUnprocessedSnapshot(moduleDto.getId()); + assertThat(moduleSnapshot.getComponentId()).isEqualTo(moduleDto.getId()); + assertThat(moduleSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(moduleSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleSnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleSnapshot.getDepth()).isEqualTo(1); + assertThat(moduleSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); + assertThat(moduleSnapshot.getQualifier()).isEqualTo("BRC"); + assertThat(moduleSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(moduleSnapshot.getVersion()).isEqualTo("1.1"); + assertThat(moduleSnapshot.getLast()).isFalse(); + assertThat(moduleSnapshot.getStatus()).isEqualTo("U"); + assertThat(moduleSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(moduleSnapshot.getBuildDate()).isEqualTo(now); + + SnapshotDto directorySnapshot = getUnprocessedSnapshot(directoryDto.getId()); + assertThat(directorySnapshot.getComponentId()).isEqualTo(directoryDto.getId()); + assertThat(directorySnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(directorySnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(directorySnapshot.getParentId()).isEqualTo(moduleSnapshot.getId()); + assertThat(directorySnapshot.getDepth()).isEqualTo(2); + assertThat(directorySnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleSnapshot.getId() + "."); + assertThat(directorySnapshot.getQualifier()).isEqualTo("DIR"); + assertThat(directorySnapshot.getScope()).isEqualTo("DIR"); + assertThat(directorySnapshot.getVersion()).isNull(); + assertThat(directorySnapshot.getLast()).isFalse(); + assertThat(directorySnapshot.getStatus()).isEqualTo("U"); + assertThat(directorySnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(directorySnapshot.getBuildDate()).isEqualTo(now); + + SnapshotDto fileSnapshot = getUnprocessedSnapshot(fileDto.getId()); + assertThat(fileSnapshot.getComponentId()).isEqualTo(fileDto.getId()); + assertThat(fileSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(fileSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(fileSnapshot.getParentId()).isEqualTo(directorySnapshot.getId()); + assertThat(fileSnapshot.getDepth()).isEqualTo(3); + assertThat(fileSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleSnapshot.getId() + "." + directorySnapshot.getId() + "."); + assertThat(fileSnapshot.getQualifier()).isEqualTo("FIL"); + assertThat(fileSnapshot.getScope()).isEqualTo("FIL"); + assertThat(fileSnapshot.getVersion()).isNull(); + assertThat(fileSnapshot.getLast()).isFalse(); + assertThat(fileSnapshot.getStatus()).isEqualTo("U"); + assertThat(fileSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(fileSnapshot.getBuildDate()).isEqualTo(now); + + assertThat(dbIdsRepository.getSnapshotId(project)).isEqualTo(projectSnapshot.getId()); + assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId()); + assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId()); + assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); + } + + @Test + public void persist_unit_test() throws Exception { + ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project"); + dbClient.componentDao().insert(session, projectDto); + ComponentDto moduleDto = ComponentTesting.newModuleDto("BCDE", projectDto).setKey("MODULE_KEY").setName("Module"); + dbClient.componentDao().insert(session, moduleDto); + ComponentDto directoryDto = ComponentTesting.newDirectory(moduleDto, "CDEF", "MODULE_KEY:src/test/java/dir").setKey("MODULE_KEY:src/test/java/dir"); + dbClient.componentDao().insert(session, directoryDto); + ComponentDto fileDto = ComponentTesting.newFileDto(moduleDto, "DEFG").setKey("MODULE_KEY:src/test/java/dir/FooTest.java").setQualifier("UTS"); + dbClient.componentDao().insert(session, fileDto); + session.commit(); + + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .addChildRef(2) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(2) + .setType(Constants.ComponentType.DIRECTORY) + .addChildRef(3) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(3) + .setType(Constants.ComponentType.FILE) + .setIsTest(true) + .build()); + + Component file = new DumbComponent(Component.Type.FILE, 3, "DEFG", PROJECT_KEY + ":src/test/java/dir/FooTest.java"); + Component directory = new DumbComponent(Component.Type.DIRECTORY, 2, "CDEF", PROJECT_KEY + ":src/test/java/dir", file); + Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, directory); + treeRootHolder.setRoot(project); + + dbIdsRepository.setComponentId(project, projectDto.getId()); + dbIdsRepository.setComponentId(directory, directoryDto.getId()); + dbIdsRepository.setComponentId(file, fileDto.getId()); + + sut.execute(); + + SnapshotDto fileSnapshot = getUnprocessedSnapshot(fileDto.getId()); + assertThat(fileSnapshot.getQualifier()).isEqualTo("UTS"); + assertThat(fileSnapshot.getScope()).isEqualTo("FIL"); + } + + @Test + public void persist_snapshots_on_multi_modules() throws Exception { + ComponentDto projectDto = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY); + dbClient.componentDao().insert(session, projectDto); + ComponentDto moduleADto = ComponentTesting.newModuleDto("BCDE", projectDto).setKey("MODULE_A"); + dbClient.componentDao().insert(session, moduleADto); + ComponentDto subModuleADto = ComponentTesting.newModuleDto("CDEF", moduleADto).setKey("SUB_MODULE_A"); + dbClient.componentDao().insert(session, subModuleADto); + ComponentDto moduleBDto = ComponentTesting.newModuleDto("DEFG", projectDto).setKey("MODULE_B"); + dbClient.componentDao().insert(session, moduleBDto); + session.commit(); + + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .addChildRef(2) + .addChildRef(4) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(2) + .setType(Constants.ComponentType.MODULE) + .addChildRef(3) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(3) + .setType(Constants.ComponentType.MODULE) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(4) + .setType(Constants.ComponentType.MODULE) + .build()); + + Component moduleB = new DumbComponent(Component.Type.MODULE, 4, "DEFG", "MODULE_B"); + Component subModuleA = new DumbComponent(Component.Type.MODULE, 3, "CDEF", "SUB_MODULE_A"); + Component moduleA = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_A", subModuleA); + Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, moduleA, moduleB); + treeRootHolder.setRoot(project); + + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_A", + new DumbComponent(Component.Type.MODULE, 3, "DEFG", "SUB_MODULE_A")), + new DumbComponent(Component.Type.MODULE, 4, "CDEF", "MODULE_B"))); + + dbIdsRepository.setComponentId(project, projectDto.getId()); + dbIdsRepository.setComponentId(moduleA, moduleADto.getId()); + dbIdsRepository.setComponentId(subModuleA, subModuleADto.getId()); + dbIdsRepository.setComponentId(moduleB, moduleBDto.getId()); + + sut.execute(); + + assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); + + SnapshotDto projectSnapshot = getUnprocessedSnapshot(projectDto.getId()); + assertThat(projectSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(projectSnapshot.getRootId()).isNull(); + assertThat(projectSnapshot.getParentId()).isNull(); + assertThat(projectSnapshot.getDepth()).isEqualTo(0); + assertThat(projectSnapshot.getPath()).isEqualTo(""); + + SnapshotDto moduleASnapshot = getUnprocessedSnapshot(moduleADto.getId()); + assertThat(moduleASnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(moduleASnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleASnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleASnapshot.getDepth()).isEqualTo(1); + assertThat(moduleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); + + SnapshotDto subModuleASnapshot = getUnprocessedSnapshot(subModuleADto.getId()); + assertThat(subModuleASnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(subModuleASnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(subModuleASnapshot.getParentId()).isEqualTo(moduleASnapshot.getId()); + assertThat(subModuleASnapshot.getDepth()).isEqualTo(2); + assertThat(subModuleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleASnapshot.getId() + "."); + + SnapshotDto moduleBSnapshot = getUnprocessedSnapshot(moduleBDto.getId()); + assertThat(moduleBSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(moduleBSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleBSnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleBSnapshot.getDepth()).isEqualTo(1); + assertThat(moduleBSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." ); + } + + private SnapshotDto getUnprocessedSnapshot(long componentId){ + List projectSnapshots = dbClient.snapshotDao().selectSnapshotsByQuery(session, + new SnapshotQuery().setComponentId(componentId).setIsLast(false).setStatus(SnapshotDto.STATUS_UNPROCESSED)); + assertThat(projectSnapshots).hasSize(1); + return projectSnapshots.get(0); + } + +} -- 2.39.5