浏览代码

SONAR-6260 Create a PeriodsRepository

The goal is to copy behaviour of PeriodsDefinition and TimeMachineConfiguration from batch in the Compute Engin
tags/5.2-RC1
Julien Lancelot 9 年前
父节点
当前提交
5544b41c92
共有 24 个文件被更改,包括 1776 次插入23 次删除
  1. 10
    1
      server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java
  2. 123
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/period/Period.java
  3. 125
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodFinder.java
  4. 187
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodsRepository.java
  5. 24
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/period/package-info.java
  6. 42
    16
      server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java
  7. 243
    0
      server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodFinderTest.java
  8. 89
    0
      server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodTest.java
  9. 211
    0
      server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodsRepositoryTest.java
  10. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java
  11. 40
    0
      server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/select_previous_version_snapshots.xml
  12. 64
    0
      server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/select_snapshots_by_query.xml
  13. 44
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_date.xml
  14. 81
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_days.xml
  15. 23
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_previous_analysis.xml
  16. 40
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_previous_version.xml
  17. 44
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_version.xml
  18. 50
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/no_previous_version.xml
  19. 46
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/previous_version_deleted.xml
  20. 54
    0
      server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodsRepositoryTest/shared.xml
  21. 136
    0
      sonar-core/src/main/java/org/sonar/core/component/SnapshotQuery.java
  22. 4
    1
      sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java
  23. 44
    4
      sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml
  24. 51
    0
      sonar-core/src/test/java/org/sonar/core/component/SnapshotQueryTest.java

+ 10
- 1
server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java 查看文件

@@ -25,6 +25,7 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.resources.Scopes;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.component.SnapshotQuery;
import org.sonar.core.component.db.SnapshotMapper;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.DbSession;
@@ -51,7 +52,15 @@ public class SnapshotDao implements DaoComponent {
}

public List<SnapshotDto> selectSnapshotsByComponentId(DbSession session, long componentId) {
return mapper(session).selectSnapshotsByComponentId(componentId);
return mapper(session).selectSnapshotsByQuery(new SnapshotQuery().setComponentId(componentId));
}

public List<SnapshotDto> selectSnapshotsByQuery(DbSession session, SnapshotQuery query) {
return mapper(session).selectSnapshotsByQuery(query);
}

public List<SnapshotDto> selectPreviousVersionSnapshots(DbSession session, long componentId, String lastVersion) {
return mapper(session).selectPreviousVersionSnapshots(componentId, lastVersion);
}

public List<SnapshotDto> selectSnapshotAndChildrenOfProjectScope(DbSession session, long snapshotId) {

+ 123
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/period/Period.java 查看文件

@@ -0,0 +1,123 @@
/*
* 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.period;

import com.google.common.annotations.VisibleForTesting;
import java.util.Calendar;
import java.util.Date;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.component.SnapshotDto;

public class Period {

private int index;
private String mode, modeParameter;
private SnapshotDto projectSnapshot;
/**
* Date resolved from the settings of the period
* - date : the given date
* - days : nearest analysis date found
* - previous analysis : date of the last analysis
* - previous version : date of the analysis of the previous version
* - version : date of the analysis of the given version
*/
private Long targetDate = null;

public Period(String mode, @Nullable Long targetDate, SnapshotDto projectSnapshot) {
this.mode = mode;
if (targetDate != null) {
this.targetDate = targetDate;
}
this.projectSnapshot = projectSnapshot;
}

public Period setIndex(int index) {
this.index = index;
return this;
}

public int getIndex() {
return index;
}

public SnapshotDto getProjectSnapshot() {
return projectSnapshot;
}

/**
* Date of the snapshot
*/
public Long getSnapshotDate() {
return projectSnapshot != null ? projectSnapshot.getCreatedAt() : null;
}

public String getMode() {
return mode;
}

public String getModeParameter() {
return modeParameter;
}

public Period setModeParameter(String s) {
this.modeParameter = s;
return this;
}

@VisibleForTesting
Long getTargetDate() {
return targetDate;
}

@Override
public String toString() {
Date snapshotDate = new Date(getSnapshotDate());
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_VERSION)) {
String label = String.format("Compare to version %s", modeParameter);
if (targetDate != null) {
label += String.format(" (%s)", DateUtils.formatDate(snapshotDate));
}
return label;
}
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_DAYS)) {
return String.format("Compare over %s days (%s, analysis of %s)", modeParameter, formatDate(),DateUtils.formatDate(snapshotDate));
}
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS)) {
return String.format("Compare to previous analysis (%s)", DateUtils.formatDate(snapshotDate));
}
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION)) {
return String.format("Compare to previous version (%s)", DateUtils.formatDate(snapshotDate));
}
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_DATE)) {
return String.format("Compare to date %s (analysis of %s)", formatDate(), DateUtils.formatDate(snapshotDate));
}
return ReflectionToStringBuilder.toString(this);
}

private String formatDate() {
return DateUtils.formatDate(org.apache.commons.lang.time.DateUtils.truncate(new Date(targetDate), Calendar.SECOND));
}

}

+ 125
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodFinder.java 查看文件

@@ -0,0 +1,125 @@
/*
* 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.period;

import com.google.common.annotations.VisibleForTesting;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.annotation.CheckForNull;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.component.SnapshotQuery;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.db.DbClient;

import static org.sonar.core.component.SnapshotQuery.SORT_FIELD.BY_DATE;
import static org.sonar.core.component.SnapshotQuery.SORT_ORDER.ASC;
import static org.sonar.core.component.SnapshotQuery.SORT_ORDER.DESC;

public class PeriodFinder {

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DateUtils.DATE_FORMAT);

private final DbClient dbClient;

public PeriodFinder(DbClient dbClient) {
this.dbClient = dbClient;
}

@CheckForNull
Period findByDate(DbSession session, Long projectId, Date date) {
SnapshotDto snapshot = findFirstSnapshot(session, createCommonQuery(projectId).setCreatedAfter(date.getTime()).setSort(BY_DATE, ASC));
if (snapshot == null) {
return null;
}
return new Period(CoreProperties.TIMEMACHINE_MODE_DATE, date.getTime(), snapshot).setModeParameter(DATE_FORMAT.format(date));
}

@CheckForNull
Period findByDays(DbSession session, Long projectId, long analysisDate, int days) {
List<SnapshotDto> snapshots = dbClient.snapshotDao().selectSnapshotsByQuery(session, createCommonQuery(projectId).setCreatedBefore(analysisDate).setSort(BY_DATE, ASC));
long targetDate = DateUtils.addDays(new Date(analysisDate), -days).getTime();
SnapshotDto snapshot = findNearestSnapshotToTargetDate(snapshots, targetDate);
if (snapshot == null) {
return null;
}
return new Period(CoreProperties.TIMEMACHINE_MODE_DAYS, targetDate, snapshot).setModeParameter(String.valueOf(days));
}

@CheckForNull
Period findByPreviousAnalysis(DbSession session, Long projectId, long analysisDate) {
SnapshotDto snapshot = findFirstSnapshot(session, createCommonQuery(projectId).setCreatedBefore(analysisDate).setIsLast(true).setSort(BY_DATE, DESC));
if (snapshot == null) {
return null;
}
return new Period(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, snapshot.getCreatedAt(), snapshot).setModeParameter(DATE_FORMAT.format(snapshot.getCreatedAt()));
}

@CheckForNull
Period findByPreviousVersion(DbSession session, Long projectId, String version) {
List<SnapshotDto> snapshotDtos = dbClient.snapshotDao().selectPreviousVersionSnapshots(session, projectId, version);
if (snapshotDtos.isEmpty()) {
return null;
}
SnapshotDto snapshotDto = snapshotDtos.get(0);
return new Period(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, snapshotDto.getCreatedAt(), snapshotDto).setModeParameter(snapshotDto.getVersion());
}

@CheckForNull
Period findByVersion(DbSession session, Long projectId, String version) {
SnapshotDto snapshot = findFirstSnapshot(session, createCommonQuery(projectId).setVersion(version).setSort(BY_DATE, DESC));
if (snapshot == null) {
return null;
}
return new Period(CoreProperties.TIMEMACHINE_MODE_VERSION, snapshot.getCreatedAt(), snapshot).setModeParameter(version);
}

@VisibleForTesting
@CheckForNull
static SnapshotDto findNearestSnapshotToTargetDate(List<SnapshotDto> snapshots, Long targetDate) {
long bestDistance = Long.MAX_VALUE;
SnapshotDto nearest = null;
for (SnapshotDto snapshot : snapshots) {
long distance = Math.abs(snapshot.getCreatedAt() - targetDate);
if (distance <= bestDistance) {
bestDistance = distance;
nearest = snapshot;
}
}
return nearest;
}

@CheckForNull
private SnapshotDto findFirstSnapshot(DbSession session, SnapshotQuery query) {
List<SnapshotDto> snapshots = dbClient.snapshotDao().selectSnapshotsByQuery(session, query);
if (snapshots.size() >= 1) {
return snapshots.get(0);
}
return null;
}

private static SnapshotQuery createCommonQuery(Long projectId) {
return new SnapshotQuery().setComponentId(projectId).setStatus(SnapshotDto.STATUS_PROCESSED);
}

}

+ 187
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/period/PeriodsRepository.java 查看文件

@@ -0,0 +1,187 @@
/*
* 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.period;

import com.google.common.base.Strings;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.component.ComponentDto;
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.TreeRootHolder;
import org.sonar.server.db.DbClient;

/**
* Repository of periods used to compute differential measures.
* Here are the steps to retrieve these periods :
* - Read the 5 period properties ${@link CoreProperties#TIMEMACHINE_PERIOD_PREFIX}
* - Try to find the matching snapshots from the properties
* - If a snapshot is found, a new period is added to the repository
*/
public class PeriodsRepository {

private static final Logger LOG = LoggerFactory.getLogger(PeriodsRepository.class);

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DateUtils.DATE_FORMAT);

private static final int NUMBER_OF_PERIODS = 5;

private final DbClient dbClient;
private final Settings settings;
private final TreeRootHolder treeRootHolder;
private final PeriodFinder periodFinder;
private final BatchReportReader batchReportReader;

private List<Period> periods = new ArrayList<>();

public PeriodsRepository(DbClient dbClient, Settings settings, TreeRootHolder treeRootHolder, PeriodFinder periodFinder, BatchReportReader batchReportReader) {
this.dbClient = dbClient;
this.settings = settings;
this.treeRootHolder = treeRootHolder;
this.periodFinder = periodFinder;
this.batchReportReader = batchReportReader;
}

public List<Period> getPeriods(){
if (periods.isEmpty()) {
initPeriods();
}
return periods;
}

private void initPeriods() {
DbSession session = dbClient.openSession(false);
try {
Component project = treeRootHolder.getRoot();
ComponentDto projectDto = dbClient.componentDao().selectNullableByKey(session, project.getKey());
// No project on first analysis, no period
if (projectDto != null) {
BatchReport.Component batchProject = batchReportReader.readComponent(project.getRef());
PeriodResolver periodResolver = new PeriodResolver(session, projectDto.getId(), batchReportReader.readMetadata().getAnalysisDate(), batchProject.getVersion(),
// TODO qualifier will be different for Views
Qualifiers.PROJECT);

for (int index = 1; index <= NUMBER_OF_PERIODS; index++) {
Period period = periodResolver.resolve(index);
// SONAR-4700 Add a past snapshot only if it exists
if (period != null) {
periods.add(period.setIndex(index));
LOG.debug(period.toString());
}
}
}
} finally {
session.close();
}
}

private class PeriodResolver {

private final DbSession session;
private final long projectId;
private final long analysisDate;
private final String currentVersion;
private final String qualifier;

public PeriodResolver(DbSession session, long projectId, long analysisDate, String currentVersion, String qualifier) {
this.session = session;
this.projectId = projectId;
this.analysisDate = analysisDate;
this.currentVersion = currentVersion;
this.qualifier = qualifier;
}

@CheckForNull
private Period resolve(int index) {
String propertyValue = getPropertyValue(qualifier, settings, index);
Period period = resolve(index, propertyValue);
if (period == null && StringUtils.isNotBlank(propertyValue)) {
LOG.debug("Property " + CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + " is not valid: " + propertyValue);
}
return period;
}

@CheckForNull
private Period resolve(int index, String property) {
if (StringUtils.isBlank(property)) {
return null;
}

Integer days = tryToResolveByDays(property);
if (days != null) {
return periodFinder.findByDays(session, projectId, analysisDate, days);
}
Date date = tryToResolveByDate(property);
if (date != null) {
return periodFinder.findByDate(session, projectId, date);
}
if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, property)) {
return periodFinder.findByPreviousAnalysis(session, projectId, analysisDate);
}
if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, property)) {
return periodFinder.findByPreviousVersion(session, projectId, currentVersion);
}
return periodFinder.findByVersion(session, projectId, property);
}

@CheckForNull
private Integer tryToResolveByDays(String property){
try {
return Integer.parseInt(property);
} catch (NumberFormatException e) {
return null;
}
}

@CheckForNull
private Date tryToResolveByDate(String property){
try {
return DATE_FORMAT.parse(property);
} catch (ParseException e) {
return null;
}
}
}

private static String getPropertyValue(@Nullable String qualifier, Settings settings, int index) {
String value = settings.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index);
// For periods 4 and 5 we're also searching for a property prefixed by the qualifier
if (index > 3 && Strings.isNullOrEmpty(value)) {
value = settings.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + "." + qualifier);
}
return value;
}

}

+ 24
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/period/package-info.java 查看文件

@@ -0,0 +1,24 @@
/*
* 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.
*/

@ParametersAreNonnullByDefault
package org.sonar.server.computation.period;

import javax.annotation.ParametersAreNonnullByDefault;

+ 42
- 16
server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java 查看文件

@@ -27,10 +27,14 @@ import org.junit.Before;
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.component.SnapshotQuery;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.component.SnapshotQuery.SORT_FIELD.BY_DATE;
import static org.sonar.core.component.SnapshotQuery.SORT_ORDER.ASC;
import static org.sonar.core.component.SnapshotQuery.SORT_ORDER.DESC;

public class SnapshotDaoTest extends AbstractDaoTestCase {

@@ -91,19 +95,6 @@ public class SnapshotDaoTest extends AbstractDaoTestCase {
assertThat(sut.selectNullableById(session, 999L)).isNull();
}

@Test
public void insert() {
setupData("empty");

SnapshotDto dto = defaultSnapshot().setCreatedAt(1403042400000L);

sut.insert(session, dto);
session.commit();

assertThat(dto.getId()).isNotNull();
checkTables("insert", new String[] {"id"}, "snapshots");
}

@Test
public void lastSnapshot_returns_null_when_no_last_snapshot() {
setupData("empty");
@@ -151,13 +142,48 @@ public class SnapshotDaoTest extends AbstractDaoTestCase {
assertThat(snapshots).hasSize(3);
}

@Test
public void select_snapshots_by_query() {
setupData("select_snapshots_by_query");

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery())).hasSize(6);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L))).hasSize(3);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setVersion("2.2-SNAPSHOT"))).extracting("id").containsOnly(3L);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setIsLast(true))).extracting("id").containsOnly(1L);
assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setIsLast(false))).extracting("id").containsOnly(2L, 3L);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setCreatedAfter(1228172400002L))).extracting("id").containsOnly(2L, 3L);
assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setCreatedBefore(1228172400002L))).extracting("id").containsOnly(1L);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(2L).setStatus("P"))).hasSize(1);
assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(2L).setStatus("U"))).hasSize(1);

assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setSort(BY_DATE, ASC)).get(0).getId()).isEqualTo(1L);
assertThat(sut.selectSnapshotsByQuery(session, new SnapshotQuery().setComponentId(1L).setSort(BY_DATE, DESC)).get(0).getId()).isEqualTo(3L);
}

@Test
public void select_previous_version_snapshots() throws Exception {
setupData("select_previous_version_snapshots");

List<SnapshotDto> snapshots = sut.selectPreviousVersionSnapshots(session, 1L, "1.2-SNAPSHOT");
assertThat(snapshots).hasSize(2);

SnapshotDto firstSnapshot = snapshots.get(0);
assertThat(firstSnapshot.getVersion()).isEqualTo("1.1");

// All snapshots are returned on an unknown version
assertThat(sut.selectPreviousVersionSnapshots(session, 1L, "UNKNOWN")).hasSize(3);
}

@Test
public void insert() {
setupData("empty");

when(system2.now()).thenReturn(1403042400000L);

SnapshotDto dto = defaultSnapshot();
SnapshotDto dto = defaultSnapshot().setCreatedAt(1403042400000L);

sut.insert(session, dto);
session.commit();

+ 243
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodFinderTest.java 查看文件

@@ -0,0 +1,243 @@
/*
* 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.period;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.time.DateUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sonar.api.CoreProperties;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.db.SnapshotDao;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

import static org.assertj.core.api.Assertions.assertThat;

@Category(DbTests.class)
public class PeriodFinderTest {

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

@ClassRule
public static final DbTester dbTester = new DbTester();

DbClient dbClient;

DbSession dbSession;

PeriodFinder periodFinder;

@Before
public void setUp() throws Exception {
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new SnapshotDao());
dbSession = dbClient.openSession(false);
periodFinder = new PeriodFinder(dbClient);
}

@After
public void tearDown() throws Exception {
dbSession.close();
}

@Test
public void find_by_date() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_date.xml");
String textDate = "2008-11-22";
Date date = DATE_FORMAT.parse(textDate);

Period result = periodFinder.findByDate(dbSession, 1L, date);

// Return analysis from given date 2008-11-22
assertThat(result.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DATE);
assertThat(result.getModeParameter()).isEqualTo(textDate);
assertThat(result.getSnapshotDate()).isEqualTo(1227358680000L);
assertThat(result.getTargetDate()).isEqualTo(date.getTime());
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1006L);
}

@Test
public void find_by_date_search_for_nearest_later_analysis() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_date.xml");
String date = "2008-11-24";

Period result = periodFinder.findByDate(dbSession, 1L, DATE_FORMAT.parse(date));

// No analysis have been done at this date, it should return the one from the date after (2008-11-25)
assertThat(result.getSnapshotDate()).isEqualTo(1227617880000L);
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1009L);
}

@Test
public void not_find_by_date() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_date.xml");
String date = "2008-11-22";

// No analysis for this project
assertThat(periodFinder.findByDate(dbSession, 123L, DATE_FORMAT.parse(date))).isNull();
}

@Test
public void find_by_days() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_days.xml");

Period result = periodFinder.findByDays(dbSession, 1L, DATE_FORMAT.parse("2008-11-16").getTime(), 50);

// Return analysis from the 2008-11-01
assertThat(result.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DAYS);
assertThat(result.getModeParameter()).isEqualTo("50");
assertThat(result.getSnapshotDate()).isEqualTo(1225544280000L);
assertThat(result.getTargetDate()).isBetween(DATE_FORMAT.parse("2008-09-26").getTime(), DATE_FORMAT.parse("2008-09-27").getTime());
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1000L);
}

@Test
public void ignore_unprocessed_snapshots() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_days.xml");

Period result = periodFinder.findByDays(dbSession, 1L, DATE_FORMAT.parse("2008-11-16").getTime(), 7);

// Return analysis from the 2008-11-13, the matching one from 2008-11-12 should be ignored
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1006L);
}

@Test
public void not_find_by_days() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_days.xml");

// No analysis for this project
assertThat(periodFinder.findByDays(dbSession, 123L, DATE_FORMAT.parse("2008-11-16").getTime(), 7)).isNull();
}

@Test
public void locate_nearest_snapshot_before() throws ParseException {
Date current = DATE_FORMAT.parse("2010-10-20");
// distance: 15 => target is 2010-10-05

List<SnapshotDto> snapshots = Arrays.asList(
new SnapshotDto().setId(1L).setCreatedAt(DATE_FORMAT.parse("2010-09-30").getTime()),
new SnapshotDto().setId(2L).setCreatedAt(DATE_FORMAT.parse("2010-10-03").getTime()), // -2 days
new SnapshotDto().setId(3L).setCreatedAt(DATE_FORMAT.parse("2010-10-08").getTime()), // +3 days
new SnapshotDto().setId(4L).setCreatedAt(DATE_FORMAT.parse("2010-10-12").getTime()) // +7 days
);
assertThat(PeriodFinder.findNearestSnapshotToTargetDate(snapshots, DateUtils.addDays(current, -15).getTime()).getId()).isEqualTo(2);
}

@Test
public void locate_nearest_snapshot_after() throws ParseException {
Date current = DATE_FORMAT.parse("2010-10-20");
// distance: 15 => target is 2010-10-05

List<SnapshotDto> snapshots = Arrays.asList(
new SnapshotDto().setId(1L).setCreatedAt(DATE_FORMAT.parse("2010-09-30").getTime()),
new SnapshotDto().setId(2L).setCreatedAt(DATE_FORMAT.parse("2010-10-01").getTime()), // -4 days
new SnapshotDto().setId(3L).setCreatedAt(DATE_FORMAT.parse("2010-10-08").getTime()), // +3 days
new SnapshotDto().setId(4L).setCreatedAt(DATE_FORMAT.parse("2010-10-12").getTime()) // +7 days
);
assertThat(PeriodFinder.findNearestSnapshotToTargetDate(snapshots, DateUtils.addDays(current, -15).getTime()).getId()).isEqualTo(3);
}

@Test
public void find_by_previous_analysis() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_previous_analysis.xml");

Period result = periodFinder.findByPreviousAnalysis(dbSession, 1L, DATE_FORMAT.parse("2008-11-27").getTime());

// Return analysis from given date 2008-11-22
assertThat(result.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
assertThat(result.getModeParameter()).isEqualTo(DATE_FORMAT.format(new Date(1227617880000L)));
assertThat(result.getSnapshotDate()).isEqualTo(1227617880000L);
assertThat(result.getTargetDate()).isEqualTo(1227617880000L);
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1009L);
}

@Test
public void not_find_by_previous_analysis() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_previous_analysis.xml");

// No analysis for this project
assertThat(periodFinder.findByPreviousAnalysis(dbSession, 2L, DATE_FORMAT.parse("2008-11-27").getTime())).isNull();
}

@Test
public void find_by_previous_version() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_previous_version.xml");

Period result = periodFinder.findByPreviousVersion(dbSession, 1L, "1.2-SNAPSHOT");

// Return analysis from given date 2008-11-22
assertThat(result.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION);
assertThat(result.getModeParameter()).isEqualTo("1.1");
assertThat(result.getSnapshotDate()).isEqualTo(1225803480000L);
assertThat(result.getTargetDate()).isEqualTo(1225803480000L);
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1001L);
}

@Test
public void find_by_previous_version_when_previous_version_deleted() throws Exception {
dbTester.prepareDbUnit(getClass(), "previous_version_deleted.xml");

Period result = periodFinder.findByPreviousVersion(dbSession, 1L, "1.2-SNAPSHOT");

// Return analysis from given date 2008-11-22
assertThat(result.getModeParameter()).isEqualTo("1.0");
assertThat(result.getSnapshotDate()).isEqualTo(1225630680000L);
assertThat(result.getTargetDate()).isEqualTo(1225630680000L);
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1000L);
}

@Test
public void not_find_previous_version() throws Exception {
dbTester.prepareDbUnit(getClass(), "no_previous_version.xml");

assertThat(periodFinder.findByPreviousVersion(dbSession, 1L, "1.2-SNAPSHOT")).isNull();
}

@Test
public void find_by_version() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_version.xml");

Period result = periodFinder.findByVersion(dbSession, 1L, "1.1");

assertThat(result.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_VERSION);
assertThat(result.getModeParameter()).isEqualTo("1.1");
assertThat(result.getSnapshotDate()).isEqualTo(1225803480000L);
assertThat(result.getTargetDate()).isEqualTo(1225803480000L);
assertThat(result.getProjectSnapshot().getId()).isEqualTo(1009L);
}

@Test
public void not_find_by_version() throws Exception {
dbTester.prepareDbUnit(getClass(), "find_by_version.xml");

assertThat(periodFinder.findByVersion(dbSession, 1L, "1.0")).isNull();
}

}

+ 89
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodTest.java 查看文件

@@ -0,0 +1,89 @@
/*
* 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.period;

import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.core.component.SnapshotDto;

import static org.assertj.core.api.Assertions.assertThat;

public class PeriodTest {

@Test
public void test_some_setters_and_getters() {
Long date = System.currentTimeMillis();
SnapshotDto snapshotDto = new SnapshotDto().setCreatedAt(date);
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_VERSION, 1000L, snapshotDto)
.setModeParameter("2.3")
.setIndex(1);

assertThat(period.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_VERSION);
assertThat(period.getModeParameter()).isEqualTo("2.3");
assertThat(period.getIndex()).isEqualTo(1);
assertThat(period.getProjectSnapshot()).isEqualTo(snapshotDto);
assertThat(period.getSnapshotDate()).isEqualTo(date);
assertThat(period.getTargetDate()).isEqualTo(1000L);
}

@Test
public void to_string_for_version() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_VERSION, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis())).setModeParameter("2.3");
assertThat(period.toString()).startsWith("Compare to version 2.3");
}

@Test
public void to_string_for_version_without_date() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_VERSION, null, new SnapshotDto().setCreatedAt(System.currentTimeMillis())).setModeParameter("2.3");
assertThat(period.toString()).isEqualTo("Compare to version 2.3");
}

@Test
public void to_string_for_number_of_days() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_DAYS, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis())).setModeParameter("30");
assertThat(period.toString()).startsWith("Compare over 30 days (");
}

@Test
public void to_string_for_number_of_days_with_snapshot() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_DAYS, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis())).setModeParameter("30");
assertThat(period.toString()).startsWith("Compare over 30 days (");
}

@Test
public void to_string_for_date() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_DATE, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis()));
assertThat(period.toString()).startsWith("Compare to date ");
}

@Test
public void to_string_for_date_with_snapshot() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_DATE, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis()));
assertThat(period.toString()).startsWith("Compare to date ");
}

@Test
public void to_string_for_previous_analysis() {
Period period = new Period(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, 1000L, new SnapshotDto().setCreatedAt(System.currentTimeMillis()));
assertThat(period.toString()).startsWith("Compare to previous analysis ");
}

}

+ 211
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/period/PeriodsRepositoryTest.java 查看文件

@@ -0,0 +1,211 @@
/*
* 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.period;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import java.text.SimpleDateFormat;
import java.util.Date;
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.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
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.DumbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;

@Category(DbTests.class)
public class PeriodsRepositoryTest {

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private static final String PROJECT_KEY = "PROJECT_KEY";

@ClassRule
public static final DbTester dbTester = new DbTester();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

DbClient dbClient;

DbSession dbSession;

Settings settings = new Settings();

PeriodsRepository periodsRepository;

@Before
public void setUp() throws Exception {
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao());
dbSession = dbClient.openSession(false);

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setAnalysisDate(DATE_FORMAT.parse("2008-11-30").getTime())
.build());

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setVersion("1.1")
.build());

Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY);
treeRootHolder.setRoot(project);

periodsRepository = new PeriodsRepository(dbClient, settings, treeRootHolder, new PeriodFinder(dbClient), reportReader);
}

@After
public void tearDown() throws Exception {
dbSession.close();
}

@Test
public void no_period_on_first_analysis() throws Exception {
// No project, no snapshot

assertThat(periodsRepository.getPeriods()).isEmpty();
}

@Test
public void get_one_period() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

String textDate = "2008-11-22";
Date date = DATE_FORMAT.parse(textDate);
settings.setProperty("sonar.timemachine.period1", textDate);

List<Period> periods = periodsRepository.getPeriods();
assertThat(periods).hasSize(1);

Period period = periods.get(0);
assertThat(period.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DATE);
assertThat(period.getModeParameter()).isEqualTo(textDate);
assertThat(period.getSnapshotDate()).isEqualTo(1227358680000L);
assertThat(period.getTargetDate()).isEqualTo(date.getTime());
assertThat(period.getProjectSnapshot().getId()).isEqualTo(1003L);
}

@Test
public void no_period_when_settings_match_no_analysis() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

settings.setProperty("sonar.timemachine.period1", "UNKNWOWN VERSION");

assertThat(periodsRepository.getPeriods()).isEmpty();
}

@Test
public void no_period_when_settings_is_empty() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

settings.setProperty("sonar.timemachine.period1", "");

assertThat(periodsRepository.getPeriods()).isEmpty();
}

@Test
public void get_five_different_periods() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

settings.setProperty("sonar.timemachine.period1", "2008-11-22"); // Analysis from 2008-11-22 should be returned
settings.setProperty("sonar.timemachine.period2", "10"); // Analysis from 2008-11-20 should be returned
settings.setProperty("sonar.timemachine.period3", "previous_analysis"); // Analysis from 2008-11-29 should be returned
settings.setProperty("sonar.timemachine.period4", "previous_version"); // Analysis from 2008-11-12 should be returned
settings.setProperty("sonar.timemachine.period5", "0.9"); // Anaylsis from 2008-11-11

List<Period> periods = periodsRepository.getPeriods();
List<String> periodModes = newArrayList(Iterables.transform(periods, new Function<Period, String>() {
@Override
public String apply(Period input) {
return input.getMode();
}
}));
assertThat(periodModes).containsOnly(CoreProperties.TIMEMACHINE_MODE_DATE, CoreProperties.TIMEMACHINE_MODE_DAYS, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS,
CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, CoreProperties.TIMEMACHINE_MODE_VERSION);

assertThat(periods.get(0).getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DATE);
assertThat(periods.get(0).getIndex()).isEqualTo(1);
assertThat(periods.get(0).getProjectSnapshot().getId()).isEqualTo(1003L);

assertThat(periods.get(1).getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_DAYS);
assertThat(periods.get(1).getIndex()).isEqualTo(2);
assertThat(periods.get(1).getProjectSnapshot().getId()).isEqualTo(1002L);

assertThat(periods.get(2).getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
assertThat(periods.get(2).getIndex()).isEqualTo(3);
assertThat(periods.get(2).getProjectSnapshot().getId()).isEqualTo(1004L);

assertThat(periods.get(3).getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION);
assertThat(periods.get(3).getIndex()).isEqualTo(4);
assertThat(periods.get(3).getProjectSnapshot().getId()).isEqualTo(1001L);

assertThat(periods.get(4).getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_VERSION);
assertThat(periods.get(4).getIndex()).isEqualTo(5);
assertThat(periods.get(4).getProjectSnapshot().getId()).isEqualTo(1000L);
}

@Test
public void can_use_qualifier_in_settings() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

settings.setProperty("sonar.timemachine.period4.TRK", "2008-11-22");
settings.setProperty("sonar.timemachine.period5.TRK", "previous_analysis");

assertThat(periodsRepository.getPeriods()).hasSize(2);
}

@Test
public void only_load_periods_on_first_call_of_get_periods() throws Exception {
dbTester.prepareDbUnit(getClass(), "shared.xml");

settings.setProperty("sonar.timemachine.period1", "2008-11-22");

// First call, periods are loaded
assertThat(periodsRepository.getPeriods()).hasSize(1);

// Second call, set project without key to check that it won't fail with a NPE
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, null, null));
assertThat(periodsRepository.getPeriods()).hasSize(1);
}

}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java 查看文件

@@ -79,7 +79,7 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest {
public void setup() throws Exception {
dbTester.truncateTables();
session = dbTester.myBatis().openSession(false);
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao(system2));
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao());
reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setAnalysisDate(ANALYSIS_DATE)
.build());

+ 40
- 0
server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/select_previous_version_snapshots.xml 查看文件

@@ -0,0 +1,40 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]" uuid="ABCD"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- version 1.0 -->
<snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.0" path=""
status="P" islast="false" depth="0" />

<!-- version 1.1 -->
<snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path=""
status="P" islast="false" depth="0" />

<!-- version 1.2-SNAPSHOT -->
<snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225976280000" build_date="1225976280000" version="1.2-SNAPSHOT" path=""
status="P" islast="false" depth="0" />

<!-- version 1.2-SNAPSHOT, current analysis -->
<snapshots id="1003" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226235480000" build_date="1226235480000" version="1.2-SNAPSHOT" path=""
status="U" islast="true" depth="0" />

<events id="1" name="1.0" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/>
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" event_data="[null]"/>
<events id="3" name="1.1" component_uuid="ABCD" snapshot_id="1001" category="Version" event_date="1225803480000" created_at="1225803480000" description="" event_data="[null]"/>
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" event_data="[null]"/>
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" event_data="[null]"/>
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description="" event_data="[null]"/>

</dataset>

+ 64
- 0
server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/select_snapshots_by_query.xml 查看文件

@@ -0,0 +1,64 @@
<dataset>

<!-- PROJECT_ID = 1 -->
<snapshots id="1" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
status="P" islast="[true]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="PRJ" qualifier="PAC" created_at="1228172400001" build_date="1317247200000"
version="2.0-SNAPSHOT" path="1.2."/>
<snapshots id="2" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3"
status="P" islast="[false]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="DIR" qualifier="PAC" created_at="1228172400002" build_date="1317247200000"
version="2.1-SNAPSHOT" path="1.2."/>
<snapshots id="3" project_id="1" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3"
status="P" islast="[false]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="DIR" qualifier="PAC" created_at="1228172400003" build_date="1317247200000"
version="2.2-SNAPSHOT" path="1.2."/>

<!-- PROJECT_ID = 2 -->
<snapshots id="4" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3"
status="P" islast="[true]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000"
version="2.1-SNAPSHOT" path="1.2."/>
<!-- Unprocessed snapshot -->
<snapshots id="5" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3"
status="U" islast="[true]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000"
version="2.1-SNAPSHOT" path="1.2."/>

<!-- PROJECT_ID = 3 - no last snapshot -->
<snapshots id="6" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="3"
status="P" islast="[false]" purge_status="1"
period1_mode="days1" period1_param="30" period1_date="1316815200000"
period2_mode="days2" period2_param="31" period2_date="1316901600000"
period3_mode="days3" period3_param="32" period3_date="1316988000000"
period4_mode="days4" period4_param="33" period4_date="1317074400000"
period5_mode="days5" period5_param="34" period5_date="1317160800000"
depth="1" scope="DIR" qualifier="PAC" created_at="1228172400000" build_date="1317247200000"
version="2.1-SNAPSHOT" path="1.2."/>

</dataset>

+ 44
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_date.xml 查看文件

@@ -0,0 +1,44 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- 2008-11-01 -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1000"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="1.1-SNAPSHOT" path=""
status="P" islast="false" depth="0"/>


<!-- 2008-11-12 -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1003"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226494680000" build_date="1226494680000" version="1.1-SNAPSHOT" path=""
status="P" islast="true" depth="0"/>


<!-- 2008-11-22 -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1006"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227358680000" build_date="1227358680000" version="1.1" path=""
status="P" islast="false" depth="0"/>


<!-- 2008-11-25-->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1009"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227617880000" build_date="1227617880000" version="1.1" path=""
status="P" islast="false" depth="0"/>

</dataset>

+ 81
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_days.xml 查看文件

@@ -0,0 +1,81 @@
<dataset>

<!-- project -->
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>

<!-- package -->
<projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
root_id="1"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>

<!-- file -->
<projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
name="Bar" root_id="[null]"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- first analysis : 2008-11-01-->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path=""
status="P" islast="false" depth="0"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
scope="DIR" qualifier="PAC" created_at="1225544280000" build_date="1225544280000" version="[null]" path="1000."
status="P" islast="false" depth="1"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
scope="FIL" qualifier="CLA" created_at="1225544280000" build_date="1225544280000" version="[null]" path="1000.1001."
status="P" islast="false" depth="2"/>


<!-- second unprocessed analysis - to ignore: 2008-11-12 -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1003" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226494680000" build_date="1226494680000" version="[null]" path=""
status="U" islast="false" depth="0"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1004" project_id="2" parent_snapshot_id="1003" root_project_id="1" root_snapshot_id="1003"
scope="DIR" qualifier="PAC" created_at="1226494680000" build_date="1226494680000" version="[null]" path="1003."
status="U" islast="false" depth="1"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1005" project_id="3" parent_snapshot_id="1004" root_project_id="1" root_snapshot_id="1003"
scope="FIL" qualifier="CLA" created_at="1226494680000" build_date="1226494680000" version="[null]" path="1003.1004."
status="U" islast="false" depth="2"/>


<!-- second analysis : 2008-11-13-->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1006" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226581080000" build_date="1226581080000" version="[null]" path=""
status="P" islast="true" depth="0"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1007" project_id="2" parent_snapshot_id="1006" root_project_id="1" root_snapshot_id="1006"
scope="DIR" qualifier="PAC" created_at="1226581080000" build_date="1226581080000" version="[null]" path="1006."
status="P" islast="true" depth="1"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1008" project_id="3" parent_snapshot_id="1007" root_project_id="1" root_snapshot_id="1006"
scope="FIL" qualifier="CLA" created_at="1226581080000" build_date="1226581080000" version="[null]" path="1006.1007."
status="P" islast="true" depth="2"/>

</dataset>

+ 23
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_previous_analysis.xml 查看文件

@@ -0,0 +1,23 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>

<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1006"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227358680000" build_date="1227358680000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- last analysis -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1009"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227617880000" build_date="1227617880000" version="1.1" path=""
status="P" islast="true" depth="0"/>

</dataset>

+ 40
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_previous_version.xml 查看文件

@@ -0,0 +1,40 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]" uuid="ABCD"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>

<!-- version 1.0 -->
<snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.0" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.1 -->
<snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.2-SNAPSHOT -->
<snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225976280000" build_date="1225976280000" version="1.2-SNAPSHOT" path=""
status="P" islast="false" depth="0"/>

<events id="1" name="1.0" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/>
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description="" event_data="[null]"/>
<events id="3" name="1.1" component_uuid="ABCD" snapshot_id="1001" category="Version" event_date="1225803480000" created_at="1225803480000" description="" event_data="[null]"/>
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description="" event_data="[null]"/>
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description="" event_data="[null]"/>
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1225976280000" created_at="1225976280000" description=""
event_data="[null]"/>

</dataset>

+ 44
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/find_by_version.xml 查看文件

@@ -0,0 +1,44 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- version 1.1-SNAPSHOT -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1000"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="1.1-SNAPSHOT" path=""
status="P" islast="false" depth="0"/>


<!-- version 1.1-SNAPSHOT -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1003"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.1-SNAPSHOT" path=""
status="P" islast="true" depth="0"/>


<!-- unprocessed version 1.1 (to ignore) -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1006"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225717080000" build_date="1225717080000" version="1.1" path=""
status="U" islast="false" depth="0"/>


<!-- version 1.1 -->
<snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" id="1009"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path=""
status="P" islast="false" depth="0"/>

</dataset>

+ 50
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/no_previous_version.xml 查看文件

@@ -0,0 +1,50 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]" uuid="ABCD"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- version 1.0 -->
<snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.0" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.1 -->
<snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.2-SNAPSHOT -->
<snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225976280000" build_date="1225976280000" version="1.2-SNAPSHOT" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.2-SNAPSHOT, current analysis -->
<snapshots id="1003" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226235480000" build_date="1226235480000" version="1.2-SNAPSHOT" path=""
status="U" islast="true" depth="0"/>

<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description=""
event_data="[null]"/>
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description=""
event_data="[null]"/>
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description=""
event_data="[null]"/>
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description=""
event_data="[null]"/>

</dataset>

+ 46
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodFinderTest/previous_version_deleted.xml 查看文件

@@ -0,0 +1,46 @@
<dataset>

<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
root_id="[null]" uuid="ABCD"
description="[null]"
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>


<!-- version 1.0 -->
<snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225630680000" build_date="1225630680000" version="1.0" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.1 -->
<snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225803480000" build_date="1225803480000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- version 1.2-SNAPSHOT -->
<snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1225976280000" build_date="1225976280000" version="1.2-SNAPSHOT" path=""
status="P" islast="false" depth="0"/>

<events id="1" name="1.0" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1225630680000" created_at="1225630680000" description=""
event_data="[null]"/>
<events id="2" name="Foo" component_uuid="ABCD" snapshot_id="1000" category="Other" event_date="1225717080000" created_at="1225717080000" description=""
event_data="[null]"/>
<!-- The "1.1" version was deleted from the history : -->
<!-- events id="3" name="1.1" component_uuid="ABCD" snapshot_id="1001" category="Version" event_date="2008-11-04 13:58:00.00" created_at="2008-11-04 13:58:00.00" description=""/-->
<events id="4" name="Bar" component_uuid="ABCD" snapshot_id="1001" category="Other" event_date="1225889880000" created_at="1225889880000" description=""
event_data="[null]"/>
<events id="5" name="Uhh" component_uuid="ABCD" snapshot_id="1002" category="Other" event_date="1226062680000" created_at="1226062680000" description=""
event_data="[null]"/>
<events id="6" name="1.2-SNAPSHOT" component_uuid="ABCD" snapshot_id="1003" category="Version" event_date="1226235480000" created_at="1226235480000" description=""
event_data="[null]"/>

</dataset>

+ 54
- 0
server/sonar-server/src/test/resources/org/sonar/server/computation/period/PeriodsRepositoryTest/shared.xml 查看文件

@@ -0,0 +1,54 @@
<dataset>

<projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="PROJECT_KEY" name="project" long_name="[null]" description="[null]"
uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD."
enabled="true" language="java" copy_resource_id="[null]" person_id="[null]"/>

<!-- 2008-11-11 -->
<!-- Version 0.9 -->
<snapshots id="1000" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226379600000" build_date="1226379600000" version="0.9" path=""
status="P" islast="false" depth="0"/>

<!-- 2008-11-12 -->
<!-- Version 1.0 -->
<snapshots id="1001" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1226494680000" build_date="1226494680000" version="1.0" path=""
status="P" islast="false" depth="0"/>

<!-- 2008-11-20 -->
<!-- First version 1.1 -->
<snapshots id="1002" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227157200000" build_date="1227157200000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- 2008-11-22 -->
<snapshots id="1003" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]"
project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227358680000" build_date="1227358680000" version="1.1" path=""
status="P" islast="false" depth="0"/>

<!-- 2008-11-29 -->
<!-- Last version 1.1 -->
<snapshots id="1004" purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]"
period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]"
period5_param="[null]" period5_date="[null]" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
scope="PRJ" qualifier="TRK" created_at="1227934800000" build_date="1227934800000" version="1.1" path=""
status="P" islast="true" depth="0"/>


<events id="1" name="0.9" component_uuid="ABCD" snapshot_id="1000" category="Version" event_date="1226379600000" created_at="1226379600000" description="" event_data="[null]"/>
<events id="2" name="1.0" component_uuid="ABCD" snapshot_id="1001" category="Version" event_date="1226494680000" created_at="1226494680000" description="" event_data="[null]"/>
<events id="3" name="1.1" component_uuid="ABCD" snapshot_id="1004" category="Version" event_date="1227934800000" created_at="1227934800000" description="" event_data="[null]"/>

</dataset>

+ 136
- 0
sonar-core/src/main/java/org/sonar/core/component/SnapshotQuery.java 查看文件

@@ -0,0 +1,136 @@
/*
* 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.core.component;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

public final class SnapshotQuery {

public enum SORT_FIELD {
BY_DATE("created_at");
final String fieldName;

SORT_FIELD(String fieldName) {
this.fieldName = fieldName;
}
}

public enum SORT_ORDER {
ASC("asc"), DESC("desc");
final String order;

SORT_ORDER(String order) {
this.order = order;
}
}

private Long componentId;
private Long createdAfter;
private Long createdBefore;
private String status;
private String version;
private Boolean isLast;
private String sortField;
private String sortOrder;

/**
* filter to return snapshots created at or after a given date
*/
@CheckForNull
public Long getCreatedAfter() {
return createdAfter;
}

public SnapshotQuery setCreatedAfter(@Nullable Long createdAfter) {
this.createdAfter = createdAfter;
return this;
}

/**
* filter to return snapshots created before a given date
*/
@CheckForNull
public Long getCreatedBefore() {
return createdBefore;
}

public SnapshotQuery setCreatedBefore(@Nullable Long createdBefore) {
this.createdBefore = createdBefore;
return this;
}

@CheckForNull
public Boolean getIsLast() {
return isLast;
}

public SnapshotQuery setIsLast(@Nullable Boolean isLast) {
this.isLast = isLast;
return this;
}

@CheckForNull
public Long getComponentId() {
return componentId;
}

public SnapshotQuery setComponentId(@Nullable Long componentId) {
this.componentId = componentId;
return this;
}

@CheckForNull
public String getStatus() {
return status;
}

public SnapshotQuery setStatus(@Nullable String status) {
this.status = status;
return this;
}

@CheckForNull
public String getVersion() {
return version;
}

public SnapshotQuery setVersion(@Nullable String version) {
this.version = version;
return this;
}

public SnapshotQuery setSort(SORT_FIELD sortField, SORT_ORDER sortOrder){
this.sortField = sortField.fieldName;
this.sortOrder = sortOrder.order;
return this;
}

@CheckForNull
public String getSortField() {
return sortField;
}

@CheckForNull
public String getSortOrder() {
return sortOrder;
}
}

+ 4
- 1
sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java 查看文件

@@ -24,6 +24,7 @@ import java.util.List;
import javax.annotation.CheckForNull;
import org.apache.ibatis.annotations.Param;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.component.SnapshotQuery;

public interface SnapshotMapper {

@@ -35,7 +36,9 @@ public interface SnapshotMapper {
@CheckForNull
SnapshotDto selectLastSnapshot(Long resourceId);

List<SnapshotDto> selectSnapshotsByComponentId(Long resourceId);
List<SnapshotDto> selectSnapshotsByQuery(@Param("query") SnapshotQuery query);

List<SnapshotDto> selectPreviousVersionSnapshots(@Param(value = "componentId") Long componentId, @Param(value = "lastVersion") String lastVersion);

List<SnapshotDto> selectSnapshotAndChildrenOfScope(@Param(value = "snapshot") Long resourceId, @Param(value = "scope") String scope);


+ 44
- 4
sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml 查看文件

@@ -51,11 +51,51 @@
where s.islast=${_true} and s.project_id = #{resource}
</select>

<select id="selectSnapshotsByComponentId" resultType="Snapshot">
select
<select id="selectSnapshotsByQuery" parameterType="map" resultType="Snapshot">
SELECT
<include refid="snapshotColumns"/>
from snapshots s
where s.project_id = #{resource}
FROM snapshots s
<where>
<if test="query.componentId != null">
AND s.project_id=#{query.componentId}
</if>
<if test="query.status != null">
AND status=#{query.status}
</if>
<if test="query.version != null">
AND version=#{query.version}
</if>
<if test="query.isLast != null">
AND islast=#{query.isLast}
</if>
<if test="query.createdAfter != null">
AND created_at>=#{query.createdAfter}
</if>
<if test="query.createdBefore != null">
AND created_at&lt;#{query.createdBefore}
</if>
</where>
<if test="query.sortField != null">
ORDER BY
<if test="query.sortField == 'created_at'">
created_at
</if>
<if test="query.sortOrder == 'asc'">
asc
</if>
<if test="query.sortOrder == 'desc'">
desc
</if>
</if>
</select>

<select id="selectPreviousVersionSnapshots" parameterType="map" resultType="Snapshot">
SELECT
<include refid="snapshotColumns"/>
FROM snapshots s
INNER JOIN events e ON s.id = e.snapshot_id AND e.name &lt;&gt; #{lastVersion} AND e.category='Version'
INNER JOIN projects p ON p.uuid=e.component_uuid AND p.id=#{componentId}
ORDER BY e.event_date DESC
</select>

<select id="selectSnapshotAndChildrenOfScope" parameterType="map" resultType="Snapshot">

+ 51
- 0
sonar-core/src/test/java/org/sonar/core/component/SnapshotQueryTest.java 查看文件

@@ -0,0 +1,51 @@
/*
* 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.core.component;

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.component.SnapshotQuery.SORT_FIELD.BY_DATE;
import static org.sonar.core.component.SnapshotQuery.SORT_ORDER.ASC;

public class SnapshotQueryTest {

@Test
public void test_setters_and_getters() throws Exception {
SnapshotQuery query = new SnapshotQuery()
.setComponentId(1L)
.setIsLast(true)
.setStatus("P")
.setVersion("1.0")
.setCreatedAfter(10L)
.setCreatedBefore(20L)
.setSort(BY_DATE, ASC);

assertThat(query.getComponentId()).isEqualTo(1L);
assertThat(query.getIsLast()).isTrue();
assertThat(query.getStatus()).isEqualTo("P");
assertThat(query.getVersion()).isEqualTo("1.0");
assertThat(query.getCreatedAfter()).isEqualTo(10L);
assertThat(query.getCreatedBefore()).isEqualTo(20L);
assertThat(query.getSortField()).isEqualTo("created_at");
assertThat(query.getSortOrder()).isEqualTo("asc");
}
}

正在加载...
取消
保存