import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
BatchReportDirectoryHolderImpl batchReportDirectoryHolder = new BatchReportDirectoryHolderImpl();
batchReportDirectoryHolder.setDirectory(reportDir);
org.sonar.server.computation.batch.BatchReportReader batchReportReader = new BatchReportReaderImpl(batchReportDirectoryHolder);
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(null);
SourceLinesRepositoryImpl sourceLinesRepository = new SourceLinesRepositoryImpl(batchReportReader);
SourceHashRepositoryImpl sourceHashRepository = new SourceHashRepositoryImpl(sourceLinesRepository);
ScmInfoRepositoryImpl scmInfoRepository = new ScmInfoRepositoryImpl(batchReportReader, analysisMetadataHolder, dbClient, sourceHashRepository);
package org.sonar.server.computation.analysis;
import java.util.Date;
+import javax.annotation.CheckForNull;
+import org.sonar.server.computation.snapshot.Snapshot;
public interface AnalysisMetadataHolder {
/**
Date getAnalysisDate();
/**
- * @throws IllegalStateException if isFirstAnalysis has not been set
+ * Convenience method equivalent to calling {@link #getBaseProjectSnapshot() == null}
+ *
+ * @throws IllegalStateException if baseProjectSnapshot has not been set
*/
boolean isFirstAnalysis();
+
+ /**
+ * Return the last snapshot of the project.
+ * If it's the first analysis, it will return null.
+ *
+ * @throws IllegalStateException if baseProjectSnapshot has not been set
+ */
+ @CheckForNull
+ Snapshot getBaseProjectSnapshot();
+
}
import java.util.Date;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.server.computation.snapshot.Snapshot;
import static com.google.common.base.Preconditions.checkState;
@CheckForNull
private Long analysisDate;
+ private boolean baseProjectSnapshotInitialized = false;
+
@CheckForNull
- private Boolean firstAnalysis;
+ private Snapshot baseProjectSnapshot;
@Override
public void setAnalysisDate(Date date) {
}
@Override
- public void setIsFirstAnalysis(boolean firstAnalysis) {
- checkState(this.firstAnalysis == null, "firstAnalysis flag has already been set");
- this.firstAnalysis = firstAnalysis;
+ public boolean isFirstAnalysis() {
+ return getBaseProjectSnapshot() == null;
}
@Override
- public boolean isFirstAnalysis() {
- checkState(firstAnalysis != null, "firstAnalysis flag has not been set");
- return firstAnalysis;
+ public void setBaseProjectSnapshot(@Nullable Snapshot baseProjectSnapshot) {
+ checkState(!baseProjectSnapshotInitialized, "Base project snapshot has already been set");
+ this.baseProjectSnapshot = baseProjectSnapshot;
+ this.baseProjectSnapshotInitialized = true;
+ }
+
+ @Override
+ @CheckForNull
+ public Snapshot getBaseProjectSnapshot() {
+ checkState(baseProjectSnapshotInitialized, "Base project snapshot has not been set");
+ return baseProjectSnapshot;
}
+
}
package org.sonar.server.computation.analysis;
import java.util.Date;
+import javax.annotation.Nullable;
+import org.sonar.server.computation.snapshot.Snapshot;
public interface MutableAnalysisMetadataHolder extends AnalysisMetadataHolder {
void setAnalysisDate(Date date);
/**
- * @throws IllegalStateException if isFirstAnalysis has already been set
+ * @throws IllegalStateException if baseProjectSnapshot has already been set
*/
- void setIsFirstAnalysis(boolean isFirstAnalysis);
+ void setBaseProjectSnapshot(@Nullable Snapshot baseProjectSnapshot);
+
}
package org.sonar.server.computation.period;
import java.util.List;
-import org.sonar.api.CoreProperties;
/**
* 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}
+ * - Read the 5 period properties ${@link org.sonar.core.config.CorePropertyDefinitions#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
*/
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.computation.snapshot;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Immutable
+public class Snapshot {
+
+ private long id;
+ private long createdAt;
+
+ private Snapshot(Builder builder) {
+ this.id = builder.id;
+ this.createdAt = builder.createdAt;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public long getCreatedAt() {
+ return createdAt;
+ }
+
+ public static final class Builder {
+ @CheckForNull
+ private Long id;
+ @CheckForNull
+ private Long createdAt;
+
+ public Builder setId(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder setCreatedAt(long createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ public Snapshot build() {
+ checkNotNull(id, "id cannot be null");
+ checkNotNull(createdAt, "createdAt cannot be null");
+ return new Snapshot(this);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Snapshot snapshot = (Snapshot) o;
+ return id == snapshot.id;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (id ^ (id >>> 32));
+ }
+
+ @Override
+ public String toString() {
+ return "SnapshotImpl{" +
+ "id=" + id +
+ ", createdAt=" + createdAt +
+ '}';
+ }
+}
import org.sonar.core.component.ComponentKeys;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.db.component.SnapshotDto;
+import org.sonar.db.component.SnapshotQuery;
import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolder;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentImpl;
import org.sonar.server.computation.component.MutableTreeRootHolder;
import org.sonar.server.computation.component.UuidFactory;
+import org.sonar.server.computation.snapshot.Snapshot;
import static com.google.common.collect.Iterables.toArray;
import static org.sonar.server.computation.component.ComponentImpl.builder;
UuidFactory uuidFactory = new UuidFactory(dbClient, moduleKey(reportProject, branch));
Component project = new ComponentRootBuilder(reportProject, uuidFactory, branch).build();
treeRootHolder.setRoot(project);
- setIsFirstAnalysis(project.getUuid());
+ setBaseProjectSnapshot(project.getUuid());
}
- private void setIsFirstAnalysis(String projectUuid){
+ private void setBaseProjectSnapshot(String projectUuid) {
DbSession dbSession = dbClient.openSession(false);
try {
- analysisMetadataHolder.setIsFirstAnalysis(!dbClient.snapshotDao().hasLastSnapshotByComponentUuid(dbSession, projectUuid));
+ SnapshotDto snapshotDto = dbClient.snapshotDao().selectSnapshotByQuery(dbSession,
+ new SnapshotQuery()
+ .setComponentUuid(projectUuid)
+ .setIsLast(true));
+ analysisMetadataHolder.setBaseProjectSnapshot(toSnapshot(snapshotDto));
} finally {
dbClient.closeSession(dbSession);
}
}
+ @CheckForNull
+ private static Snapshot toSnapshot(@Nullable SnapshotDto snapshotDto) {
+ return snapshotDto == null ? null :
+ new Snapshot.Builder()
+ .setId(snapshotDto.getId())
+ .setCreatedAt(snapshotDto.getCreatedAt())
+ .build();
+ }
+
private class ComponentRootBuilder {
private final BatchReport.Component reportProject;
}
}
- private ComponentImpl buildComponent(BatchReport.Component reportComponent, String componentKey, String latestModuleKey){
+ private ComponentImpl buildComponent(BatchReport.Component reportComponent, String componentKey, String latestModuleKey) {
return builder(reportComponent)
.addChildren(toArray(buildChildren(reportComponent, latestModuleKey), Component.class))
.setKey(componentKey)
return buildComponent(reportReader.readComponent(componentRef), latestModuleKey);
}
}
- );
+ );
}
}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.server.computation.snapshot.Snapshot;
import static org.assertj.core.api.Assertions.assertThat;
public class AnalysisMetadataHolderImplTest {
+
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private Date someDate = new Date();
+ static Snapshot BASE_PROJECT_SNAPSHOT = new Snapshot.Builder()
+ .setId(1)
+ .setCreatedAt(123456789L)
+ .build();
+
+ static Date SOME_DATE = new Date();
@Test
public void getAnalysisDate_returns_date_with_same_time_as_the_one_set_with_setAnalysisDate() throws InterruptedException {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
- underTest.setAnalysisDate(someDate);
+ underTest.setAnalysisDate(SOME_DATE);
Thread.sleep(10);
Date analysisDate = underTest.getAnalysisDate();
- assertThat(analysisDate.getTime()).isEqualTo(someDate.getTime());
- assertThat(analysisDate).isNotSameAs(someDate);
+ assertThat(analysisDate.getTime()).isEqualTo(SOME_DATE.getTime());
+ assertThat(analysisDate).isNotSameAs(SOME_DATE);
}
@Test
@Test
public void setAnalysisDate_throws_ISE_when_called_twice() {
+ AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+ underTest.setAnalysisDate(SOME_DATE);
+
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Analysis date has already been set");
- AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
-
- underTest.setAnalysisDate(someDate);
- underTest.setAnalysisDate(someDate);
+ underTest.setAnalysisDate(SOME_DATE);
}
@Test
public void isFirstAnalysis_return_true() throws Exception {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
- underTest.setIsFirstAnalysis(true);
+ underTest.setBaseProjectSnapshot(null);
assertThat(underTest.isFirstAnalysis()).isTrue();
}
public void isFirstAnalysis_return_false() throws Exception {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
- underTest.setIsFirstAnalysis(false);
+ underTest.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
assertThat(underTest.isFirstAnalysis()).isFalse();
}
@Test
- public void isFirstAnalysis_throws_ISE_when_holder_is_not_initialized() {
+ public void isFirstAnalysis_throws_ISE_when_base_project_snapshot_is_not_set() {
expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("firstAnalysis flag has not been set");
+ expectedException.expectMessage("Base project snapshot has not been set");
new AnalysisMetadataHolderImpl().isFirstAnalysis();
}
@Test
- public void setIsFirstAnalysis_throws_ISE_when_called_twice() {
+ public void baseProjectSnapshot_throws_ISE_when_base_project_snapshot_is_not_set() {
expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("firstAnalysis flag has already been set");
+ expectedException.expectMessage("Base project snapshot has not been set");
+
+ new AnalysisMetadataHolderImpl().getBaseProjectSnapshot();
+ }
+ @Test
+ public void setBaseProjectSnapshot_throws_ISE_when_called_twice() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+ underTest.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
- underTest.setIsFirstAnalysis(true);
- underTest.setIsFirstAnalysis(true);
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Base project snapshot has already been set");
+ underTest.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
}
}
package org.sonar.server.computation.analysis;
import java.util.Date;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.junit.rules.ExternalResource;
+import org.sonar.server.computation.snapshot.Snapshot;
public class MutableAnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder {
+
private AnalysisMetadataHolderImpl delegate = new AnalysisMetadataHolderImpl();
@Override
}
@Override
- public void setIsFirstAnalysis(boolean isFirstAnalysis) {
- delegate.setIsFirstAnalysis(isFirstAnalysis);
+ @CheckForNull
+ public Snapshot getBaseProjectSnapshot() {
+ return delegate.getBaseProjectSnapshot();
+ }
+
+ @Override
+ public void setBaseProjectSnapshot(@Nullable Snapshot baseProjectSnapshot) {
+ delegate.setBaseProjectSnapshot(baseProjectSnapshot);
}
}
return metadata;
}
- public void setMetadata(BatchReport.Metadata metadata) {
+ public BatchReportReaderRule setMetadata(BatchReport.Metadata metadata) {
this.metadata = metadata;
+ return this;
}
@Override
return CloseableIterator.from(scannerLogs.iterator());
}
- public void setScannerLogs(@Nullable List<String> logs) {
+ public BatchReportReaderRule setScannerLogs(@Nullable List<String> logs) {
this.scannerLogs = logs;
+ return this;
}
@Override
return CloseableIterator.from(activeRules.iterator());
}
- public void putActiveRules(List<BatchReport.ActiveRule> activeRules) {
+ public BatchReportReaderRule putActiveRules(List<BatchReport.ActiveRule> activeRules) {
this.activeRules = activeRules;
+ return this;
}
@Override
return CloseableIterator.from(res.iterator());
}
- public void putMeasures(int componentRef, List<BatchReport.Measure> measures) {
+ public BatchReportReaderRule putMeasures(int componentRef, List<BatchReport.Measure> measures) {
this.measures.put(componentRef, measures);
+ return this;
}
@Override
return changesets.get(componentRef);
}
- public void putChangesets(BatchReport.Changesets changesets) {
+ public BatchReportReaderRule putChangesets(BatchReport.Changesets changesets) {
this.changesets.put(changesets.getComponentRef(), changesets);
+ return this;
}
@Override
return components.get(componentRef);
}
- public void putComponent(BatchReport.Component component) {
+ public BatchReportReaderRule putComponent(BatchReport.Component component) {
this.components.put(component.getRef(), component);
+ return this;
}
@Override
return closeableIterator(issues.get(componentRef));
}
- public void putIssues(int componentRef, List<BatchReport.Issue> issue) {
+ public BatchReportReaderRule putIssues(int componentRef, List<BatchReport.Issue> issue) {
this.issues.put(componentRef, issue);
+ return this;
}
@Override
return closeableIterator(this.duplications.get(componentRef));
}
- public void putDuplications(int componentRef, BatchReport.Duplication... duplications) {
+ public BatchReportReaderRule putDuplications(int componentRef, BatchReport.Duplication... duplications) {
this.duplications.put(componentRef, Arrays.asList(duplications));
+ return this;
}
@Override
return closeableIterator(this.duplicationBlocks.get(componentRef));
}
- public void putDuplicationBlocks(int componentRef, List<BatchReport.DuplicationBlock> duplicationBlocks) {
+ public BatchReportReaderRule putDuplicationBlocks(int componentRef, List<BatchReport.DuplicationBlock> duplicationBlocks) {
this.duplicationBlocks.put(componentRef, duplicationBlocks);
+ return this;
}
@Override
return list == null ? CloseableIterator.<T>emptyCloseableIterator() : CloseableIterator.from(list.iterator());
}
- public void putSymbols(int componentRef, List<BatchReport.Symbol> symbols) {
+ public BatchReportReaderRule putSymbols(int componentRef, List<BatchReport.Symbol> symbols) {
this.symbols.put(componentRef, symbols);
+ return this;
}
@Override
return CloseableIterator.from(res.iterator());
}
- public void putSyntaxHighlighting(int fileRef, List<BatchReport.SyntaxHighlighting> syntaxHighlightings) {
+ public BatchReportReaderRule putSyntaxHighlighting(int fileRef, List<BatchReport.SyntaxHighlighting> syntaxHighlightings) {
this.syntaxHighlightings.put(fileRef, syntaxHighlightings);
+ return this;
}
@Override
return CloseableIterator.from(res.iterator());
}
- public void putCoverage(int fileRef, List<BatchReport.Coverage> coverages) {
+ public BatchReportReaderRule putCoverage(int fileRef, List<BatchReport.Coverage> coverages) {
this.coverages.put(fileRef, coverages);
+ return this;
}
@Override
return Optional.of(CloseableIterator.from(lines.iterator()));
}
- public void putFileSourceLines(int fileRef, @Nullable String... lines) {
+ public BatchReportReaderRule putFileSourceLines(int fileRef, @Nullable String... lines) {
Preconditions.checkNotNull(lines);
this.fileSources.put(fileRef, Arrays.asList(lines));
+ return this;
}
- public void putFileSourceLines(int fileRef, List<String> lines) {
+ public BatchReportReaderRule putFileSourceLines(int fileRef, List<String> lines) {
this.fileSources.put(fileRef, lines);
+ return this;
}
@Override
return CloseableIterator.from(res.iterator());
}
- public void putTests(int testFileRed, List<BatchReport.Test> tests) {
+ public BatchReportReaderRule putTests(int testFileRed, List<BatchReport.Test> tests) {
this.tests.put(testFileRed, tests);
+ return this;
}
@Override
return CloseableIterator.from(res.iterator());
}
- public void putCoverageDetails(int testFileRef, List<BatchReport.CoverageDetail> coverageDetails) {
+ public BatchReportReaderRule putCoverageDetails(int testFileRef, List<BatchReport.CoverageDetail> coverageDetails) {
this.coverageDetails.put(testFileRef, coverageDetails);
+ return this;
}
}
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.core.hash.SourceHashComputer;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.protobuf.DbFileSources;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ReportComponent;
import org.sonar.server.computation.component.ViewsComponent;
-import org.sonar.core.hash.SourceHashComputer;
+import org.sonar.server.computation.snapshot.Snapshot;
import org.sonar.server.computation.source.SourceHashRepository;
import org.sonar.server.computation.source.SourceHashRepositoryImpl;
import org.sonar.server.computation.source.SourceLinesRepositoryImpl;
@RunWith(DataProviderRunner.class)
public class ScmInfoRepositoryImplTest {
- private static final int FILE_REF = 1;
- private static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();
- private static final long DATE_1 = 123456789L;
- private static final long DATE_2 = 1234567810L;
+ static final int FILE_REF = 1;
+ static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();
+ static final long DATE_1 = 123456789L;
+ static final long DATE_2 = 1234567810L;
+
+ static Snapshot BASE_PROJECT_SNAPSHOT = new Snapshot.Builder()
+ .setId(1)
+ .setCreatedAt(123456789L)
+ .build();
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void read_from_report() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addChangesetInReport("john", DATE_1, "rev-1");
ScmInfo scmInfo = underTest.getScmInfo(FILE).get();
@Test
public void getScmInfo_returns_ScmInfo_from_DB_if_hashes_are_the_same() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1));
addFileSourceInReport(1);
@Test
public void getScmInfo_returns_absent_if_hash_from_db_does_not_match() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1) + "_different");
addFileSourceInReport(1);
@Test
public void read_from_report_even_if_data_in_db_exists() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1));
addChangesetInReport("john", DATE_2, "rev-2");
@Test
public void return_nothing_when_no_data_in_report_and_db() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
assertThat(underTest.getScmInfo(FILE)).isAbsent();
}
@Test
public void return_nothing_when_nothing_in_report_and_db_has_no_scm() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addFileSourceInDb(null, null, null, "don't care");
addFileSourceInReport(1);
@Test
public void fail_with_NPE_when_component_is_null() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
thrown.expect(NullPointerException.class);
thrown.expectMessage("Component cannot be bull");
@Test
public void load_scm_info_from_cache_when_already_read() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(false);
+ analysisMetadataHolder.setBaseProjectSnapshot(BASE_PROJECT_SNAPSHOT);
addChangesetInReport("john", DATE_1, "rev-1");
ScmInfo scmInfo = underTest.getScmInfo(FILE).get();
assertThat(scmInfo.getAllChangesets()).hasSize(1);
@Test
public void not_read_in_db_on_first_analysis() throws Exception {
- analysisMetadataHolder.setIsFirstAnalysis(true);
+ analysisMetadataHolder.setBaseProjectSnapshot(null);
addFileSourceInDb("henry", DATE_1, "rev-1", "don't care");
addFileSourceInReport(1);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.computation.snapshot;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SnapshotImplTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ static final long ID = 10;
+ static final long CREATED_AT = 123456789L;
+
+ @Test
+ public void build_snapshot() throws Exception {
+ Snapshot snapshot = new Snapshot.Builder()
+ .setId(ID)
+ .setCreatedAt(CREATED_AT)
+ .build();
+
+ assertThat(snapshot.getId()).isEqualTo(ID);
+ assertThat(snapshot.getCreatedAt()).isEqualTo(CREATED_AT);
+ }
+
+ @Test
+ public void fail_with_NPE_when_building_snapshot_without_id() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("id cannot be null");
+
+ new Snapshot.Builder()
+ .setCreatedAt(CREATED_AT)
+ .build();
+ }
+
+ @Test
+ public void fail_with_NPE_when_building_snapshot_without_created_at() throws Exception {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("createdAt cannot be null");
+
+ new Snapshot.Builder()
+ .setId(ID)
+ .build();
+ }
+
+ @Test
+ public void test_toString() throws Exception {
+ assertThat(new Snapshot.Builder()
+ .setId(ID)
+ .setCreatedAt(CREATED_AT)
+ .build().toString())
+ .isEqualTo("SnapshotImpl{id=10, createdAt=123456789}");
+ }
+
+ @Test
+ public void test_equals_and_hascode() throws Exception {
+ Snapshot snapshot = new Snapshot.Builder()
+ .setId(ID)
+ .setCreatedAt(CREATED_AT)
+ .build();
+ Snapshot sameSnapshot = new Snapshot.Builder()
+ .setId(ID)
+ .setCreatedAt(CREATED_AT)
+ .build();
+ Snapshot otherSnapshot = new Snapshot.Builder()
+ .setId(11L)
+ .setCreatedAt(CREATED_AT)
+ .build();
+
+ assertThat(snapshot).isEqualTo(snapshot);
+ assertThat(snapshot).isEqualTo(sameSnapshot);
+ assertThat(snapshot).isNotEqualTo(otherSnapshot);
+ assertThat(snapshot).isNotEqualTo(null);
+
+ assertThat(snapshot.hashCode()).isEqualTo(snapshot.hashCode());
+ assertThat(snapshot.hashCode()).isEqualTo(sameSnapshot.hashCode());
+ assertThat(snapshot.hashCode()).isNotEqualTo(otherSnapshot.hashCode());
+ }
+}
}
@Test
- public void set_first_analysis_to_true_when_no_snapshot() throws Exception {
+ public void set_no_base_project_snapshot_when_no_snapshot() throws Exception {
reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY));
underTest.execute();
}
@Test
- public void set_first_analysis_to_true_when_no_last_snapshot() throws Exception {
+ public void set_no_base_project_snapshot_when_no_last_snapshot() throws Exception {
ComponentDto project = insertComponent(newProjectDto("ABCD").setKey(REPORT_PROJECT_KEY));
insertSnapshot(newSnapshotForProject(project).setLast(false));
}
@Test
- public void set_first_analysis_to_false_when_last_snapshot_exist() throws Exception {
+ public void set_base_project_snapshot_when_last_snapshot_exist() throws Exception {
ComponentDto project = insertComponent(newProjectDto("ABCD").setKey(REPORT_PROJECT_KEY));
insertSnapshot(newSnapshotForProject(project).setLast(true));