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 index 049f0649b96a..22312178d0c0 100644 --- 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 @@ -20,6 +20,7 @@ package org.sonar.server.computation.step; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; @@ -29,8 +30,12 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.server.computation.analysis.AnalysisMetadataHolder; import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.component.DbIdsRepository; import org.sonar.server.computation.component.DbIdsRepositoryImpl; import org.sonar.server.computation.component.MutableDbIdsRepository; +import org.sonar.server.computation.component.PathAwareCrawler; +import org.sonar.server.computation.component.PathAwareVisitor; +import org.sonar.server.computation.component.PathAwareVisitorAdapter; import org.sonar.server.computation.component.TreeRootHolder; import org.sonar.server.computation.period.Period; import org.sonar.server.computation.period.PeriodsHolder; @@ -62,104 +67,134 @@ public PersistSnapshotsStep(System2 system2, DbClient dbClient, TreeRootHolder t public void execute() { DbSession session = dbClient.openSession(false); try { - Component root = treeRootHolder.getRoot(); - ProcessPersistSnapshot processPersistSnapshot = new ProcessPersistSnapshot(session, analysisMetadataHolder.getAnalysisDate().getTime()); - processPersistSnapshot.process(root, null); + new PersistSnapshotsPathAwareCrawler(session, analysisMetadataHolder.getAnalysisDate().getTime(), dbIdsRepository) + .visit(treeRootHolder.getRoot()); session.commit(); } finally { - session.close(); + dbClient.closeSession(session); } } - private class ProcessPersistSnapshot { + private class PersistSnapshotsPathAwareCrawler extends PathAwareCrawler { private final DbSession dbSession; private final long analysisDate; + private final DbIdsRepository dbIdsRepository; - private long projectId; + private long rootId; - public ProcessPersistSnapshot(DbSession dbSession, long analysisDate) { + public PersistSnapshotsPathAwareCrawler(DbSession dbSession, long analysisDate, DbIdsRepository dbIdsRepository) { + super(Component.Type.FILE, Order.PRE_ORDER, SnapshotDtoHolderFactory.INSTANCE); this.dbSession = dbSession; this.analysisDate = analysisDate; + this.dbIdsRepository = dbIdsRepository; } - private void process(Component component, @Nullable SnapshotDto parentSnapshot) { - long componentId = dbIdsRepository.getComponentId(component); - - switch (component.getType()) { - case PROJECT: - this.projectId = componentId; - SnapshotDto projectSnapshot = persistSnapshot(componentId, Qualifiers.PROJECT, Scopes.PROJECT, component.getReportAttributes().getVersion(), parentSnapshot, true); - addToCache(component, projectSnapshot); - processChildren(component, projectSnapshot); - break; - case MODULE: - SnapshotDto moduleSnapshot = persistSnapshot(componentId, Qualifiers.MODULE, Scopes.PROJECT, component.getReportAttributes().getVersion(), parentSnapshot, true); - addToCache(component, moduleSnapshot); - processChildren(component, moduleSnapshot); - break; - case DIRECTORY: - SnapshotDto directorySnapshot = persistSnapshot(componentId, Qualifiers.DIRECTORY, Scopes.DIRECTORY, null, parentSnapshot, false); - addToCache(component, directorySnapshot); - processChildren(component, directorySnapshot); - break; - case FILE: - SnapshotDto fileSnapshot = persistSnapshot(componentId, getFileQualifier(component), Scopes.FILE, null, parentSnapshot, false); - addToCache(component, fileSnapshot); - break; - default: - throw new IllegalStateException(String.format("Unsupported component type '%s'", component.getType())); - } + @Override + public void visitProject(Component project, Path path) { + this.rootId = dbIdsRepository.getComponentId(project); + SnapshotDto snapshot = createSnapshot(project, path, Qualifiers.PROJECT, Scopes.PROJECT, true, true); + commonForAnyVisit(project, path, snapshot); } - private void processChildren(Component component, SnapshotDto parentSnapshot) { - for (Component child : component.getChildren()) { - process(child, parentSnapshot); - } + @Override + public void visitModule(Component module, Path path) { + SnapshotDto snapshot = createSnapshot(module, path, Qualifiers.MODULE, Scopes.PROJECT, true, true); + commonForAnyVisit(module, path, snapshot); } - private SnapshotDto persistSnapshot(long componentId, String qualifier, String scope, @Nullable String version, @Nullable SnapshotDto parentSnapshot, boolean setPeriods) { - 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 (setPeriods) { - updateSnapshotPeriods(snapshotDto); - } + @Override + public void visitDirectory(Component directory, Path path) { + SnapshotDto snapshot = createSnapshot(directory, path, Qualifiers.DIRECTORY, Scopes.DIRECTORY, false, false); + commonForAnyVisit(directory, path, snapshot); + } - 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 - // On Oracle, the path will be null - .setPath("") - .setDepth(0); - } - dbClient.snapshotDao().insert(dbSession, snapshotDto); - return snapshotDto; + @Override + public void visitFile(Component file, Path path) { + SnapshotDto snapshot = createSnapshot(file, path, getFileQualifier(file), Scopes.FILE, false, false); + commonForAnyVisit(file, path, snapshot); + } + + @Override + public void visitView(Component view, Path path) { + this.rootId = dbIdsRepository.getComponentId(view); + SnapshotDto snapshot = createSnapshot(view, path, Qualifiers.VIEW, Scopes.PROJECT, false, true); + commonForAnyVisit(view, path, snapshot); + } + + @Override + public void visitSubView(Component subView, Path path) { + SnapshotDto snapshot = createSnapshot(subView, path, Qualifiers.SUBVIEW, Scopes.PROJECT, false, true); + commonForAnyVisit(subView, path, snapshot); } - private void updateSnapshotPeriods(SnapshotDto snapshotDto) { - for (Period period : periodsHolder.getPeriods()) { - int index = period.getIndex(); - snapshotDto.setPeriodMode(index, period.getMode()); - snapshotDto.setPeriodParam(index, period.getModeParameter()); - snapshotDto.setPeriodDate(index, period.getSnapshotDate()); + @Override + public void visitProjectView(Component projectView, Path path) { + SnapshotDto snapshot = createSnapshot(projectView, path, Qualifiers.PROJECT, Scopes.FILE, false, true); + commonForAnyVisit(projectView, path, snapshot); + } + + private void commonForAnyVisit(Component project, Path path, SnapshotDto snapshot) { + persist(snapshot, dbSession); + addToCache(project, snapshot); + if (path.current() != null) { + path.current().setSnapshotDto(snapshot); } } - private void addToCache(Component component, SnapshotDto snapshotDto) { - dbIdsRepository.setSnapshotId(component, snapshotDto.getId()); + private SnapshotDto createSnapshot(Component component, PathAwareVisitor.Path path, + String qualifier, String scope, boolean setVersion, boolean setPeriods) { + return PersistSnapshotsStep.this.createSnapshot(component, path, rootId, analysisDate, qualifier, scope, setVersion, setPeriods); + } + } + + private SnapshotDto createSnapshot(Component component, PathAwareVisitor.Path path, + long rootId, long analysisDate, String qualifier, String scope, boolean setVersion, boolean setPeriods) { + long componentId = dbIdsRepository.getComponentId(component); + SnapshotDto snapshotDto = new SnapshotDto() + .setRootProjectId(rootId) + .setVersion(setVersion ? component.getReportAttributes().getVersion() : null) + .setComponentId(componentId) + .setQualifier(qualifier) + .setScope(scope) + .setLast(false) + .setStatus(SnapshotDto.STATUS_UNPROCESSED) + .setCreatedAt(analysisDate) + .setBuildDate(system2.now()); + if (setPeriods) { + updateSnapshotPeriods(snapshotDto); + } + + SnapshotDto parentSnapshot = path.isRoot() ? null : path.parent().getSnapshotDto(); + 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 + // On Oracle, the path will be null + .setPath("") + .setDepth(0); + } + return snapshotDto; + } + + private void persist(SnapshotDto snapshotDto, DbSession dbSession) { + dbClient.snapshotDao().insert(dbSession, snapshotDto); + } + + private void addToCache(Component component, SnapshotDto snapshotDto) { + dbIdsRepository.setSnapshotId(component, snapshotDto.getId()); + } + + private void updateSnapshotPeriods(SnapshotDto snapshotDto) { + for (Period period : periodsHolder.getPeriods()) { + int index = period.getIndex(); + snapshotDto.setPeriodMode(index, period.getMode()); + snapshotDto.setPeriodParam(index, period.getModeParameter()); + snapshotDto.setPeriodDate(index, period.getSnapshotDate()); } } @@ -167,6 +202,45 @@ private static String getFileQualifier(Component component) { return component.getFileAttributes().isUnitTest() ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE; } + private static final class SnapshotDtoHolder { + @CheckForNull + private SnapshotDto snapshotDto; + + @CheckForNull + public SnapshotDto getSnapshotDto() { + return snapshotDto; + } + + public void setSnapshotDto(@Nullable SnapshotDto snapshotDto) { + this.snapshotDto = snapshotDto; + } + } + + /** + * Factory of SnapshotDtoHolder. + * + * No need to create an instance for components of type FILE and PROJECT_VIEW, since they are the leaves of their + * respective trees, no one will consume the value of the holder, so we save on creating useless objects. + */ + private static class SnapshotDtoHolderFactory extends PathAwareVisitorAdapter.SimpleStackElementFactory { + public static final SnapshotDtoHolderFactory INSTANCE = new SnapshotDtoHolderFactory(); + + @Override + public SnapshotDtoHolder createForAny(Component component) { + return new SnapshotDtoHolder(); + } + + @Override + public SnapshotDtoHolder createForFile(Component file) { + return null; + } + + @Override + public SnapshotDtoHolder createForProjectView(Component projectView) { + return null; + } + } + @Override public String getDescription() { return "Persist snapshots"; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java index 961808aec3d2..6270be1184e3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java @@ -78,12 +78,14 @@ public Component getComponentByRef(int ref) { public TreeRootHolderRule setRoot(Component newRoot) { this.root = Objects.requireNonNull(newRoot); - new DepthTraversalTypeAwareCrawler(Component.Type.FILE, POST_ORDER) { - @Override - public void visitAny(Component component) { - componentsByRef.put(component.getReportAttributes().getRef(), component); - } - }.visit(root); + if (newRoot.getType().isReportType()) { + new DepthTraversalTypeAwareCrawler(Component.Type.FILE, POST_ORDER) { + @Override + public void visitAny(Component component) { + componentsByRef.put(component.getReportAttributes().getRef(), component); + } + }.visit(root); + } return this; } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportPersistSnapshotsStepTest.java similarity index 99% rename from server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotsStepTest.java rename to server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportPersistSnapshotsStepTest.java index a8772cdc84bb..e9d0ced4fd65 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistSnapshotsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportPersistSnapshotsStepTest.java @@ -51,7 +51,7 @@ import static org.mockito.Mockito.when; @Category(DbTests.class) -public class PersistSnapshotsStepTest extends BaseStepTest { +public class ReportPersistSnapshotsStepTest extends BaseStepTest { private static final String PROJECT_KEY = "PROJECT_KEY"; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsPersistSnapshotsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsPersistSnapshotsStepTest.java new file mode 100644 index 000000000000..fe258b93caab --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsPersistSnapshotsStepTest.java @@ -0,0 +1,227 @@ +/* + * 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.Date; +import java.util.List; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.CoreProperties; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.SnapshotDto; +import org.sonar.db.component.SnapshotQuery; +import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolderRule; +import org.sonar.server.computation.batch.TreeRootHolderRule; +import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.component.MapBasedDbIdsRepository; +import org.sonar.server.computation.component.ViewsComponent; +import org.sonar.server.computation.period.Period; +import org.sonar.server.computation.period.PeriodsHolderRule; +import org.sonar.test.DbTests; + +import static java.lang.String.valueOf; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.component.ComponentTesting.newProjectCopy; +import static org.sonar.db.component.ComponentTesting.newProjectDto; +import static org.sonar.db.component.ComponentTesting.newSubView; +import static org.sonar.db.component.ComponentTesting.newView; +import static org.sonar.server.component.SnapshotTesting.createForProject; +import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW; +import static org.sonar.server.computation.component.Component.Type.SUBVIEW; +import static org.sonar.server.computation.component.Component.Type.VIEW; +import static org.sonar.server.computation.component.ComponentFunctions.toKey; + +@Category(DbTests.class) +public class ViewsPersistSnapshotsStepTest extends BaseStepTest { + + private static final int PROJECT_KEY = 1; + + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + + @Rule + public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule(); + + @Rule + public PeriodsHolderRule periodsHolder = new PeriodsHolderRule(); + + System2 system2 = mock(System2.class); + + MapBasedDbIdsRepository dbIdsRepository = new MapBasedDbIdsRepository<>(toKey()); + + DbClient dbClient = dbTester.getDbClient(); + + long analysisDate; + + long now; + + PersistSnapshotsStep underTest; + + @Before + public void setup() { + dbTester.truncateTables(); + analysisDate = DateUtils.parseDateQuietly("2015-06-01").getTime(); + analysisMetadataHolder.setAnalysisDate(new Date(analysisDate)); + + now = DateUtils.parseDateQuietly("2015-06-02").getTime(); + + when(system2.now()).thenReturn(now); + + underTest = new PersistSnapshotsStep(system2, dbClient, treeRootHolder, analysisMetadataHolder, dbIdsRepository, periodsHolder); + + // initialize PeriodHolder to empty by default + periodsHolder.setPeriods(); + } + + @Override + protected ComputationStep step() { + return underTest; + } + + @Test + public void persist_snapshots() { + ComponentDto projectDto = save(newProjectDto("proj")); + ComponentDto viewDto = save(newView("ABCD").setKey(valueOf(PROJECT_KEY)).setName("Project")); + ComponentDto subViewDto = save(newSubView(viewDto, "CDEF", "MODULE_KEY:src/main/java/dir").setKey("2")); + ComponentDto projectViewDto = save(newProjectCopy("DEFG", projectDto, subViewDto).setKey("3")); + dbTester.getSession().commit(); + + Component projectView = ViewsComponent.builder(PROJECT_VIEW, 3).setUuid("DEFG").build(); + Component subView = ViewsComponent.builder(SUBVIEW, 2).setUuid("CDEF").addChildren(projectView).build(); + Component view = ViewsComponent.builder(VIEW, 1).setUuid("ABCD").addChildren(subView).build(); + treeRootHolder.setRoot(view); + + dbIdsRepository.setComponentId(view, viewDto.getId()); + dbIdsRepository.setComponentId(subView, subViewDto.getId()); + dbIdsRepository.setComponentId(projectView, projectViewDto.getId()); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(3); + + SnapshotDto projectSnapshot = getUnprocessedSnapshot(viewDto.getId()); + assertThat(projectSnapshot.getComponentId()).isEqualTo(viewDto.getId()); + assertThat(projectSnapshot.getRootProjectId()).isEqualTo(viewDto.getId()); + assertThat(projectSnapshot.getRootId()).isNull(); + assertThat(projectSnapshot.getParentId()).isNull(); + assertThat(projectSnapshot.getDepth()).isEqualTo(0); + assertThat(projectSnapshot.getPath()).isNullOrEmpty(); + assertThat(projectSnapshot.getQualifier()).isEqualTo("VW"); + assertThat(projectSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(projectSnapshot.getVersion()).isNull(); + assertThat(projectSnapshot.getLast()).isFalse(); + assertThat(projectSnapshot.getStatus()).isEqualTo("U"); + assertThat(projectSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(projectSnapshot.getBuildDate()).isEqualTo(now); + + SnapshotDto subViewSnapshot = getUnprocessedSnapshot(subViewDto.getId()); + assertThat(subViewSnapshot.getComponentId()).isEqualTo(subViewDto.getId()); + assertThat(subViewSnapshot.getRootProjectId()).isEqualTo(viewDto.getId()); + assertThat(subViewSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(subViewSnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(subViewSnapshot.getDepth()).isEqualTo(1); + assertThat(subViewSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); + assertThat(subViewSnapshot.getQualifier()).isEqualTo("SVW"); + assertThat(subViewSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(subViewSnapshot.getVersion()).isNull(); + assertThat(subViewSnapshot.getLast()).isFalse(); + assertThat(subViewSnapshot.getStatus()).isEqualTo("U"); + assertThat(subViewSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(subViewSnapshot.getBuildDate()).isEqualTo(now); + + SnapshotDto projectViewSnapshot = getUnprocessedSnapshot(projectViewDto.getId()); + assertThat(projectViewSnapshot.getComponentId()).isEqualTo(projectViewDto.getId()); + assertThat(projectViewSnapshot.getRootProjectId()).isEqualTo(viewDto.getId()); + assertThat(projectViewSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(projectViewSnapshot.getParentId()).isEqualTo(subViewSnapshot.getId()); + assertThat(projectViewSnapshot.getDepth()).isEqualTo(2); + assertThat(projectViewSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + subViewSnapshot.getId() + "."); + assertThat(projectViewSnapshot.getQualifier()).isEqualTo("TRK"); + assertThat(projectViewSnapshot.getScope()).isEqualTo("FIL"); + assertThat(projectViewSnapshot.getVersion()).isNull(); + assertThat(projectViewSnapshot.getLast()).isFalse(); + assertThat(projectViewSnapshot.getStatus()).isEqualTo("U"); + assertThat(projectViewSnapshot.getCreatedAt()).isEqualTo(analysisDate); + assertThat(projectViewSnapshot.getBuildDate()).isEqualTo(now); + + assertThat(dbIdsRepository.getSnapshotId(view)).isEqualTo(projectSnapshot.getId()); + assertThat(dbIdsRepository.getComponentId(subView)).isEqualTo(subViewDto.getId()); + assertThat(dbIdsRepository.getComponentId(projectView)).isEqualTo(projectViewDto.getId()); + } + + @Test + public void persist_snapshots_with_periods() { + ComponentDto viewDto = save(newView("ABCD").setKey(valueOf(PROJECT_KEY)).setName("Project")); + ComponentDto subViewDto = save(newSubView(viewDto, "CDEF", "MODULE_KEY:src/main/java/dir").setKey("2")); + SnapshotDto viewSnapshotDto = save(createForProject(viewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime())); + SnapshotDto subViewSnapshotDto = save(createForProject(subViewDto).setCreatedAt(DateUtils.parseDateQuietly("2015-01-01").getTime())); + dbTester.getSession().commit(); + + Component subView = ViewsComponent.builder(SUBVIEW, 2).setUuid("ABCD").build(); + Component view = ViewsComponent.builder(VIEW, PROJECT_KEY).setUuid("ABCD").addChildren(subView).build(); + treeRootHolder.setRoot(view); + dbIdsRepository.setComponentId(view, viewDto.getId()); + dbIdsRepository.setComponentId(subView, subViewDto.getId()); + + periodsHolder.setPeriods(new Period(1, CoreProperties.TIMEMACHINE_MODE_DATE, "2015-01-01", analysisDate, 123L)); + + underTest.execute(); + + SnapshotDto viewSnapshot = getUnprocessedSnapshot(viewDto.getId()); + assertThat(viewSnapshot.getPeriodMode(1)).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DATE); + assertThat(viewSnapshot.getPeriodDate(1)).isEqualTo(analysisDate); + assertThat(viewSnapshot.getPeriodModeParameter(1)).isNotNull(); + + SnapshotDto subViewSnapshot = getUnprocessedSnapshot(subViewDto.getId()); + assertThat(subViewSnapshot.getPeriodMode(1)).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DATE); + assertThat(subViewSnapshot.getPeriodDate(1)).isEqualTo(analysisDate); + assertThat(subViewSnapshot.getPeriodModeParameter(1)).isNotNull(); + } + + private ComponentDto save(ComponentDto componentDto) { + dbClient.componentDao().insert(dbTester.getSession(), componentDto); + return componentDto; + } + + private SnapshotDto save(SnapshotDto snapshotDto) { + dbClient.snapshotDao().insert(dbTester.getSession(), snapshotDto); + return snapshotDto; + } + + private SnapshotDto getUnprocessedSnapshot(long componentId) { + List projectSnapshots = dbClient.snapshotDao().selectSnapshotsByQuery(dbTester.getSession(), + new SnapshotQuery().setComponentId(componentId).setIsLast(false).setStatus(SnapshotDto.STATUS_UNPROCESSED)); + assertThat(projectSnapshots).hasSize(1); + return projectSnapshots.get(0); + } + +} diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java index 37c61a7ec80e..f492d037f43e 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java @@ -47,12 +47,22 @@ public static ComponentDto newFileDto(ComponentDto module, String fileUuid) { public static ComponentDto newDirectory(ComponentDto module, String uuid, String path) { return newChildComponent(uuid, module) - .setKey(!path.equals("/") ? module.getKey() + ":" + path : module.getKey() + ":/") - .setName(path) - .setLongName(path) - .setPath(path) - .setScope(Scopes.DIRECTORY) - .setQualifier(Qualifiers.DIRECTORY); + .setKey(!path.equals("/") ? module.getKey() + ":" + path : module.getKey() + ":/") + .setName(path) + .setLongName(path) + .setPath(path) + .setScope(Scopes.DIRECTORY) + .setQualifier(Qualifiers.DIRECTORY); + } + + public static ComponentDto newSubView(ComponentDto viewOrSubView, String uuid, String path) { + return newChildComponent(uuid, viewOrSubView) + .setKey(!path.equals("/") ? viewOrSubView.getKey() + ":" + path : viewOrSubView.getKey() + ":/") + .setName(path) + .setLongName(path) + .setPath(path) + .setScope(Scopes.PROJECT) + .setQualifier(Qualifiers.SUBVIEW); } public static ComponentDto newDirectory(ComponentDto module, String path) {