Browse Source

SONAR-6253 Cache of component ids do not contains anymore key and uuid

Instead, use TreeRootHolder to get component key and uuid
tags/5.2-RC1
Julien Lancelot 9 years ago
parent
commit
08f807ca75
33 changed files with 974 additions and 825 deletions
  1. 15
    11
      server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java
  2. 18
    38
      server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java
  3. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
  4. 5
    5
      server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java
  5. 9
    8
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java
  6. 5
    8
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java
  7. 5
    8
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java
  8. 11
    11
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java
  9. 73
    79
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
  10. 73
    53
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java
  11. 72
    72
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java
  12. 47
    30
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
  13. 40
    40
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java
  14. 60
    46
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java
  15. 11
    11
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
  16. 11
    10
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java
  17. 8
    8
      server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java
  18. 127
    0
      server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java
  19. 26
    9
      server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java
  20. 13
    9
      server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java
  21. 12
    15
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java
  22. 8
    14
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java
  23. 8
    12
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java
  24. 119
    115
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java
  25. 66
    43
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java
  26. 14
    18
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java
  27. 14
    20
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java
  28. 40
    46
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
  29. 10
    11
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java
  30. 22
    50
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java
  31. 7
    14
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java
  32. 13
    4
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
  33. 10
    5
      server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java

+ 15
- 11
server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java View File

@@ -33,8 +33,9 @@ import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
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.computation.step.PersistFileSourcesStep;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
@@ -49,12 +50,15 @@ public class PersistFileSourcesStepTest {
public static final int NUMBER_OF_LINES = 1000;
public static final String PROJECT_UUID = Uuids.create();

DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();

@Rule
public DbTester dbTester = new DbTester();

@Rule
public Benchmark benchmark = new Benchmark();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@@ -70,7 +74,7 @@ public class PersistFileSourcesStepTest {

long start = System.currentTimeMillis();

PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, dbComponentsRefCache, reportReader);
PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, treeRootHolder, reportReader);
step.execute();

long end = System.currentTimeMillis();
@@ -92,17 +96,17 @@ public class PersistFileSourcesStepTest {
.setRef(1)
.setType(Constants.ComponentType.PROJECT);

dbComponentsRefCache.addComponent(1, new DbComponent(1L, "PROJECT", PROJECT_UUID));

List<Component> components = new ArrayList<>();
for (int fileRef = 2; fileRef <= NUMBER_OF_FILES + 1; fileRef++) {
generateFileReport(fileRef);
components.add(generateFileReport(fileRef));
project.addChildRef(fileRef);
}
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, "PROJECT", components.toArray(new Component[components.size()])));

reportReader.putComponent(project.build());
}

private void generateFileReport(int fileRef) throws IOException {
private Component generateFileReport(int fileRef) throws IOException {
LineData lineData = new LineData();
for (int line = 1; line <= NUMBER_OF_LINES; line++) {
lineData.generateLineData(line);
@@ -113,14 +117,14 @@ public class PersistFileSourcesStepTest {
.setLines(NUMBER_OF_LINES)
.build());

dbComponentsRefCache.addComponent(fileRef, new DbComponent((long) fileRef, "PROJECT:" + fileRef, Uuids.create()));

reportReader.putFileSourceLines(fileRef, lineData.lines);
reportReader.putCoverage(fileRef, lineData.coverages);
reportReader.putChangesets(lineData.changesetsBuilder.setComponentRef(fileRef).build());
reportReader.putSyntaxHighlighting(fileRef, lineData.highlightings);
reportReader.putSymbols(fileRef, lineData.symbols);
reportReader.putDuplications(fileRef, lineData.duplications);

return new DumbComponent(Component.Type.FILE, fileRef, Uuids.create(), "PROJECT:" + fileRef);
}

private static class LineData {

server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java → server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java View File

@@ -24,53 +24,33 @@ import java.util.HashMap;
import java.util.Map;

/**
* Cache of components (id, uuid and key) that can be used in the persistence steps
* Snapshot id will also be added in this cache
* Cache of persisted component (component id) that can be used in the persistence steps
*/
public class DbComponentsRefCache {
public class DbIdsRepository {

private final Map<Integer, DbComponent> componentsByRef;
private final Map<Integer, Long> componentIdsByRef;

public DbComponentsRefCache() {
componentsByRef = new HashMap<>();
public DbIdsRepository() {
componentIdsByRef = new HashMap<>();
}

public DbComponentsRefCache addComponent(Integer ref, DbComponent component) {
componentsByRef.put(ref, component);
public DbIdsRepository setComponentId(Component component, long componentId) {
int ref = component.getRef();
Long existingComponentId = componentIdsByRef.get(ref);
if (existingComponentId != null) {
throw new IllegalArgumentException(String.format("Component ref '%s' has already a component id", ref));
}
componentIdsByRef.put(ref, componentId);
return this;
}

public DbComponent getByRef(Integer ref) {
DbComponent component = componentsByRef.get(ref);
if (component == null) {
throw new IllegalArgumentException(String.format("Component ref '%s' does not exists", ref));
public long getComponentId(Component component) {
int ref = component.getRef();
Long componentId = componentIdsByRef.get(ref);
if (componentId == null) {
throw new IllegalArgumentException(String.format("Component ref '%s' has no component id", ref));
}
return componentsByRef.get(ref);
return componentId;
}

public static class DbComponent {

private Long id;
private String uuid;
private String key;

public DbComponent(Long id, String key, String uuid) {
this.id = id;
this.key = key;
this.uuid = uuid;
}

public Long getId() {
return id;
}

public String getKey() {
return key;
}

public String getUuid() {
return uuid;
}

}
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java View File

@@ -36,7 +36,7 @@ import org.sonar.server.computation.ReportQueue;
import org.sonar.server.computation.activity.ActivityManager;
import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl;
import org.sonar.server.computation.batch.BatchReportReaderImpl;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.ProjectSettingsRepository;
import org.sonar.server.computation.component.TreeRootHolderImpl;
import org.sonar.server.computation.event.EventRepositoryImpl;
@@ -126,7 +126,7 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co
ProjectSettingsRepository.class,

// component caches
DbComponentsRefCache.class,
DbIdsRepository.class,

// issues
ScmAccountCacheLoader.class,

+ 5
- 5
server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java View File

@@ -24,7 +24,7 @@ import org.sonar.api.resources.Qualifiers;
import org.sonar.core.permission.PermissionFacade;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;
import org.sonar.server.issue.index.IssueAuthorizationIndexer;
@@ -35,15 +35,15 @@ import org.sonar.server.issue.index.IssueAuthorizationIndexer;
public class ApplyPermissionsStep implements ComputationStep {

private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;
private final DbIdsRepository dbIdsRepository;
private final IssueAuthorizationIndexer indexer;
private final PermissionFacade permissionFacade;
private final TreeRootHolder treeRootHolder;

public ApplyPermissionsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, IssueAuthorizationIndexer indexer,
public ApplyPermissionsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, IssueAuthorizationIndexer indexer,
PermissionFacade permissionFacade, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
this.dbIdsRepository = dbIdsRepository;
this.indexer = indexer;
this.permissionFacade = permissionFacade;
this.treeRootHolder = treeRootHolder;
@@ -53,7 +53,7 @@ public class ApplyPermissionsStep implements ComputationStep {
public void execute() {
DbSession session = dbClient.openSession(false);
try {
long projectId = dbComponentsRefCache.getByRef(treeRootHolder.getRoot().getRef()).getId();
long projectId = dbIdsRepository.getComponentId(treeRootHolder.getRoot());
if (permissionFacade.countComponentPermissions(session, projectId) == 0) {
permissionFacade.grantDefaultRoles(session, projectId, Qualifiers.PROJECT);
session.commit();

+ 9
- 8
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java View File

@@ -21,26 +21,27 @@
package org.sonar.server.computation.step;

import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.TreeRootHolder;

/**
* Components are currently indexed in db table RESOURCE_INDEX, not in Elasticsearch
*/
public class IndexComponentsStep implements ComputationStep {

private final ResourceIndexerDao resourceIndexerDao;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final DbIdsRepository dbIdsRepository;
private final TreeRootHolder treeRootHolder;

public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder) {
this.resourceIndexerDao = resourceIndexerDao;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute() {
resourceIndexerDao.indexProject(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getId());
resourceIndexerDao.indexProject(dbIdsRepository.getComponentId(treeRootHolder.getRoot()));
}

@Override

+ 5
- 8
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java View File

@@ -19,25 +19,22 @@
*/
package org.sonar.server.computation.step;

import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.source.index.SourceLineIndexer;

public class IndexSourceLinesStep implements ComputationStep {

private final SourceLineIndexer indexer;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public IndexSourceLinesStep(SourceLineIndexer indexer, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public IndexSourceLinesStep(SourceLineIndexer indexer, TreeRootHolder treeRootHolder) {
this.indexer = indexer;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute() {
indexer.index(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getUuid());
indexer.index(treeRootHolder.getRoot().getUuid());
}

@Override

+ 5
- 8
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java View File

@@ -20,25 +20,22 @@

package org.sonar.server.computation.step;

import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.test.index.TestIndexer;

public class IndexTestsStep implements ComputationStep {

private final TestIndexer indexer;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public IndexTestsStep(TestIndexer indexer, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public IndexTestsStep(TestIndexer indexer, TreeRootHolder treeRootHolder) {
this.indexer = indexer;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute() {
indexer.index(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getUuid());
indexer.index(treeRootHolder.getRoot().getUuid());
}

@Override

+ 11
- 11
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java View File

@@ -34,20 +34,20 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.util.NonNullInputFunction;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

public class PersistComponentsStep implements ComputationStep {

private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;
private final DbIdsRepository dbIdsRepository;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
public PersistComponentsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
this.dbIdsRepository = dbIdsRepository;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}
@@ -109,7 +109,7 @@ public class PersistComponentsStep implements ComputationStep {
componentDto.setProjectUuid(componentDto.uuid());
componentDto.setModuleUuidPath(ComponentDto.MODULE_UUID_PATH_SEP + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP);

return persistComponent(project.getRef(), componentDto, componentContext);
return persistComponent(project, componentDto, componentContext);
}

public ComponentDto processModule(Component module, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -130,7 +130,7 @@ public class PersistComponentsStep implements ComputationStep {
componentDto.setModuleUuid(lastModule.uuid());
componentDto.setModuleUuidPath((lastModule.moduleUuidPath() + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP));

return persistComponent(module.getRef(), componentDto, componentContext);
return persistComponent(module, componentDto, componentContext);
}

public void processDirectory(Component directory, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -149,7 +149,7 @@ public class PersistComponentsStep implements ComputationStep {
componentDto.setModuleUuid(lastModule.uuid());
componentDto.setModuleUuidPath(lastModule.moduleUuidPath());

persistComponent(directory.getRef(), componentDto, componentContext);
persistComponent(directory, componentDto, componentContext);
}

public void processFile(Component file, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -171,7 +171,7 @@ public class PersistComponentsStep implements ComputationStep {
componentDto.setModuleUuid(lastModule.uuid());
componentDto.setModuleUuidPath(lastModule.moduleUuidPath());

persistComponent(file.getRef(), componentDto, componentContext);
persistComponent(file, componentDto, componentContext);
}

private ComponentDto createComponentDto(Component component) {
@@ -186,17 +186,17 @@ public class PersistComponentsStep implements ComputationStep {
return componentDto;
}

private ComponentDto persistComponent(int componentRef, ComponentDto componentDto, ComponentContext componentContext) {
private ComponentDto persistComponent(Component component, ComponentDto componentDto, ComponentContext componentContext) {
ComponentDto existingComponent = componentContext.componentDtosByKey.get(componentDto.getKey());
if (existingComponent == null) {
dbClient.componentDao().insert(componentContext.dbSession, componentDto);
dbComponentsRefCache.addComponent(componentRef, new DbComponentsRefCache.DbComponent(componentDto.getId(), componentDto.getKey(), componentDto.uuid()));
dbIdsRepository.setComponentId(component, componentDto.getId());
return componentDto;
} else {
if (updateComponent(existingComponent, componentDto)) {
dbClient.componentDao().update(componentContext.dbSession, existingComponent);
}
dbComponentsRefCache.addComponent(componentRef, new DbComponentsRefCache.DbComponent(existingComponent.getId(), existingComponent.getKey(), existingComponent.uuid()));
dbIdsRepository.setComponentId(component, existingComponent.getId());
return existingComponent;
}
}

+ 73
- 79
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java View File

@@ -30,21 +30,28 @@ import org.sonar.core.metric.db.MetricDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

/**
* Persist duplications into
*/
public class PersistDuplicationsStep implements ComputationStep {

private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;
private final DbIdsRepository dbIdsRepository;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

public PersistDuplicationsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@@ -52,102 +59,89 @@ public class PersistDuplicationsStep implements ComputationStep {
public void execute() {
DbSession session = dbClient.openSession(true);
try {
MetricDto duplicationMetric = dbClient.metricDao().selectNullableByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
DuplicationContext duplicationContext = new DuplicationContext(duplicationMetric, session);
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
recursivelyProcessComponent(duplicationContext, rootComponentRef);
MetricDto duplicationMetric = dbClient.metricDao().selectByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
new DuplicationVisitor(session, duplicationMetric).visit(treeRootHolder.getRoot());
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
}

private void recursivelyProcessComponent(DuplicationContext duplicationContext, int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
List<BatchReport.Duplication> duplications = reportReader.readComponentDuplications(componentRef);
if (!duplications.isEmpty()) {
saveDuplications(duplicationContext, component, duplications);
}
private class DuplicationVisitor extends DepthTraversalTypeAwareVisitor {

private final DbSession session;
private final MetricDto duplicationMetric;

for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(duplicationContext, childRef);
private DuplicationVisitor(DbSession session, MetricDto duplicationMetric) {
super(Component.Type.FILE, PRE_ORDER);
this.session = session;
this.duplicationMetric = duplicationMetric;
}
}

private void saveDuplications(DuplicationContext duplicationContext, BatchReport.Component component, List<BatchReport.Duplication> duplications) {
@Override
public void visitFile(Component file) {
visitComponent(file);
}

DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(component.getRef());
String duplicationXml = createXmlDuplications(duplicationContext, dbComponent.getKey(), duplications);
MeasureDto measureDto = new MeasureDto()
.setMetricId(duplicationContext.metric().getId())
.setData(duplicationXml)
.setComponentId(dbComponent.getId())
.setSnapshotId(component.getSnapshotId());
dbClient.measureDao().insert(duplicationContext.session(), measureDto);
}
private void visitComponent(Component component) {
List<BatchReport.Duplication> duplications = reportReader.readComponentDuplications(component.getRef());
if (!duplications.isEmpty()) {
BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
saveDuplications(batchComponent, component, duplications);
}
}

private String createXmlDuplications(DuplicationContext duplicationContext, String componentKey, Iterable<BatchReport.Duplication> duplications) {
private void saveDuplications(BatchReport.Component batchComponent, Component component, List<BatchReport.Duplication> duplications) {
String duplicationXml = createXmlDuplications(component.getKey(), duplications);
MeasureDto measureDto = new MeasureDto()
.setMetricId(duplicationMetric.getId())
.setData(duplicationXml)
.setComponentId(dbIdsRepository.getComponentId(component))
.setSnapshotId(batchComponent.getSnapshotId());
dbClient.measureDao().insert(session, measureDto);
}

StringBuilder xml = new StringBuilder();
xml.append("<duplications>");
for (BatchReport.Duplication duplication : duplications) {
xml.append("<g>");
appendDuplication(xml, componentKey, duplication.getOriginPosition());
for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) {
processDuplicationBlock(duplicationContext, xml, duplicationBlock, componentKey);
private String createXmlDuplications(String componentKey, Iterable<BatchReport.Duplication> duplications) {
StringBuilder xml = new StringBuilder();
xml.append("<duplications>");
for (BatchReport.Duplication duplication : duplications) {
xml.append("<g>");
appendDuplication(xml, componentKey, duplication.getOriginPosition());
for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) {
processDuplicationBlock(xml, duplicationBlock, componentKey);
}
xml.append("</g>");
}
xml.append("</g>");
xml.append("</duplications>");
return xml.toString();
}
xml.append("</duplications>");
return xml.toString();
}

private void processDuplicationBlock(DuplicationContext duplicationContext, StringBuilder xml, BatchReport.Duplicate duplicate, String componentKey) {

if (duplicate.hasOtherFileKey()) {
// componentKey is only set for cross project duplications
String crossProjectComponentKey = duplicate.getOtherFileKey();
appendDuplication(xml, crossProjectComponentKey, duplicate);
} else {
if (duplicate.hasOtherFileRef()) {
// Duplication is on a different file
BatchReport.Component duplicationComponent = reportReader.readComponent(duplicate.getOtherFileRef());
DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(duplicationComponent.getRef());
appendDuplication(xml, dbComponent.getKey(), duplicate);
private void processDuplicationBlock(StringBuilder xml, BatchReport.Duplicate duplicate, String componentKey) {
if (duplicate.hasOtherFileKey()) {
// componentKey is only set for cross project duplications
String crossProjectComponentKey = duplicate.getOtherFileKey();
appendDuplication(xml, crossProjectComponentKey, duplicate);
} else {
// Duplication is on a the same file
appendDuplication(xml, componentKey, duplicate);
if (duplicate.hasOtherFileRef()) {
// Duplication is on a different file
appendDuplication(xml, treeRootHolder.getComponentByRef(duplicate.getOtherFileRef()).getKey(), duplicate);
} else {
// Duplication is on a the same file
appendDuplication(xml, componentKey, duplicate);
}
}
}
}

private static void appendDuplication(StringBuilder xml, String componentKey, BatchReport.Duplicate duplicate) {
appendDuplication(xml, componentKey, duplicate.getRange());
}

private static void appendDuplication(StringBuilder xml, String componentKey, Range range) {
int length = range.getEndLine() - range.getStartLine() + 1;
xml.append("<b s=\"").append(range.getStartLine())
.append("\" l=\"").append(length)
.append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
.append("\"/>");
}

private static class DuplicationContext {
private DbSession session;
private MetricDto duplicationMetric;

DuplicationContext(MetricDto duplicationMetric, DbSession session) {
this.duplicationMetric = duplicationMetric;
this.session = session;
}

public MetricDto metric() {
return duplicationMetric;
private void appendDuplication(StringBuilder xml, String componentKey, BatchReport.Duplicate duplicate) {
appendDuplication(xml, componentKey, duplicate.getRange());
}

public DbSession session() {
return session;
private void appendDuplication(StringBuilder xml, String componentKey, Range range) {
int length = range.getEndLine() - range.getStartLine() + 1;
xml.append("<b s=\"").append(range.getStartLine())
.append("\" l=\"").append(length)
.append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
.append("\"/>");
}
}


+ 73
- 53
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java View File

@@ -28,20 +28,24 @@ import org.sonar.core.event.EventDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

public class PersistEventsStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system2;
private final DbComponentsRefCache dbComponentsRefCache;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

public PersistEventsStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistEventsStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.system2 = system2;
this.dbComponentsRefCache = dbComponentsRefCache;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@@ -49,73 +53,89 @@ public class PersistEventsStep implements ComputationStep {
public void execute() {
DbSession session = dbClient.openSession(false);
try {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
recursivelyProcessComponent(session, rootComponentRef);
new EventVisitor(session, reportReader.readMetadata().getAnalysisDate()).visit(treeRootHolder.getRoot());
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
}

private void recursivelyProcessComponent(DbSession session, int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
long analysisDate = reportReader.readMetadata().getAnalysisDate();
processEvents(session, component, analysisDate);
saveVersionEvent(session, component, analysisDate);
private class EventVisitor extends DepthTraversalTypeAwareVisitor {

private final DbSession session;
private final long analysisDate;

for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(session, childRef);
private EventVisitor(DbSession session, long analysisDate) {
super(Component.Type.FILE, PRE_ORDER);
this.session = session;
this.analysisDate = analysisDate;
}
}

private void processEvents(DbSession session, BatchReport.Component component, Long analysisDate) {
List<BatchReport.Event> events = component.getEventList();
if (!events.isEmpty()) {
for (BatchReport.Event event : component.getEventList()) {
dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
.setName(event.getName())
.setCategory(convertCategory(event.getCategory()))
.setDescription(event.hasDescription() ? event.getDescription() : null)
.setData(event.hasEventData() ? event.getEventData() : null)
);
@Override
public void visitModule(Component module) {
visitProjectOrModule(module);
}

@Override
public void visitProject(Component project) {
visitProjectOrModule(project);
}

private void visitProjectOrModule(Component component) {
BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
processEvents(batchComponent, component);
saveVersionEvent(batchComponent, component);
}

private void processEvents(BatchReport.Component batchComponent, Component component) {
List<BatchReport.Event> events = batchComponent.getEventList();
if (!events.isEmpty()) {
for (BatchReport.Event event : events) {
dbClient.eventDao().insert(session, newBaseEvent(component, batchComponent.getSnapshotId())
.setName(event.getName())
.setCategory(convertCategory(event.getCategory()))
.setDescription(event.hasDescription() ? event.getDescription() : null)
.setData(event.hasEventData() ? event.getEventData() : null)
);
}
}
}
}

private void saveVersionEvent(DbSession session, BatchReport.Component component, Long analysisDate) {
if (component.hasVersion()) {
deletePreviousEventsHavingSameVersion(session, component);
dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
.setName(component.getVersion())
.setCategory(EventDto.CATEGORY_VERSION)
);
private void saveVersionEvent(BatchReport.Component batchComponent, Component component) {
if (batchComponent.hasVersion()) {
deletePreviousEventsHavingSameVersion(batchComponent, component);
dbClient.eventDao().insert(session, newBaseEvent(component, batchComponent.getSnapshotId())
.setName(batchComponent.getVersion())
.setCategory(EventDto.CATEGORY_VERSION)
);
}
}
}

private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component) {
for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, dbComponentsRefCache.getByRef(component.getRef()).getUuid())) {
if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(component.getVersion())) {
dbClient.eventDao().delete(session, dto.getId());
private void deletePreviousEventsHavingSameVersion(BatchReport.Component batchComponent, Component component) {
for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) {
if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(batchComponent.getVersion())) {
dbClient.eventDao().delete(session, dto.getId());
}
}
}
}

private EventDto newBaseEvent(BatchReport.Component component, Long analysisDate) {
return new EventDto()
.setComponentUuid(dbComponentsRefCache.getByRef(component.getRef()).getUuid())
.setSnapshotId(component.getSnapshotId())
.setCreatedAt(system2.now())
.setDate(analysisDate);
}
private EventDto newBaseEvent(Component component, long snapshotId) {
return new EventDto()
.setComponentUuid(component.getUuid())
.setSnapshotId(snapshotId)
.setCreatedAt(system2.now())
.setDate(analysisDate);
}

private static String convertCategory(Constants.EventCategory category) {
switch (category) {
case ALERT:
return EventDto.CATEGORY_ALERT;
case PROFILE:
return EventDto.CATEGORY_PROFILE;
default:
throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
private String convertCategory(Constants.EventCategory category) {
switch (category) {
case ALERT:
return EventDto.CATEGORY_ALERT;
case PROFILE:
return EventDto.CATEGORY_PROFILE;
default:
throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
}
}
}


+ 72
- 72
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java View File

@@ -29,14 +29,15 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.utils.System2;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.source.db.FileSourceDto;
import org.sonar.core.source.db.FileSourceDto.Type;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.source.ComputeFileSourceData;
import org.sonar.server.computation.source.CoverageLineReader;
import org.sonar.server.computation.source.DuplicationLineReader;
@@ -48,28 +49,48 @@ import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDb;
import org.sonar.server.util.CloseableIterator;

import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

public class PersistFileSourcesStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system2;
private final DbComponentsRefCache dbComponentsRefCache;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

public PersistFileSourcesStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistFileSourcesStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.system2 = system2;
this.dbComponentsRefCache = dbComponentsRefCache;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@Override
public void execute() {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
// Don't use batch insert for file_sources since keeping all data in memory can produce OOM for big files
DbSession session = dbClient.openSession(false);
try {
final Map<String, FileSourceDto> previousFileSourcesByUuid = new HashMap<>();
String projectUuid = dbComponentsRefCache.getByRef(rootComponentRef).getUuid();
new FileSourceVisitor(session).visit(treeRootHolder.getRoot());
} finally {
MyBatis.closeQuietly(session);
}
}

private class FileSourceVisitor extends DepthTraversalTypeAwareVisitor {

private final DbSession session;

private Map<String, FileSourceDto> previousFileSourcesByUuid = new HashMap<>();
private String projectUuid;

private FileSourceVisitor(DbSession session) {
super(Component.Type.FILE, PRE_ORDER);
this.session = session;
}

@Override
public void visitProject(Component project) {
this.projectUuid = project.getUuid();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject", ImmutableMap.of("projectUuid", projectUuid, "dataType", Type.SOURCE),
new ResultHandler() {
@Override
@@ -78,90 +99,69 @@ public class PersistFileSourcesStep implements ComputationStep {
previousFileSourcesByUuid.put(dto.getFileUuid(), dto);
}
});

recursivelyProcessComponent(new FileSourcesContext(session, previousFileSourcesByUuid, projectUuid), rootComponentRef);
} finally {
MyBatis.closeQuietly(session);
}
}

private void recursivelyProcessComponent(FileSourcesContext fileSourcesContext, int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
if (component.getType().equals(Constants.ComponentType.FILE)) {
CloseableIterator<String> linesIterator = reportReader.readFileSource(componentRef);
LineReaders lineReaders = new LineReaders(reportReader, componentRef);
@Override
public void visitFile(Component file) {
int fileRef = file.getRef();
BatchReport.Component component = reportReader.readComponent(fileRef);
CloseableIterator<String> linesIterator = reportReader.readFileSource(fileRef);
LineReaders lineReaders = new LineReaders(reportReader, fileRef);
try {
ComputeFileSourceData computeFileSourceData = new ComputeFileSourceData(linesIterator, lineReaders.readers(), component.getLines());
ComputeFileSourceData.Data fileSourceData = computeFileSourceData.compute();
persistSource(fileSourcesContext, fileSourceData, component);
persistSource(fileSourceData, file.getUuid());
} catch (Exception e) {
throw new IllegalStateException(String.format("Cannot persist sources of %s", component.getPath()), e);
throw new IllegalStateException(String.format("Cannot persist sources of %s", file.getKey()), e);
} finally {
linesIterator.close();
lineReaders.close();
}
}

for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(fileSourcesContext, childRef);
}
}
private void persistSource(ComputeFileSourceData.Data fileSourceData, String componentUuid) {
FileSourceDb.Data fileData = fileSourceData.getFileSourceData();

private void persistSource(FileSourcesContext fileSourcesContext, ComputeFileSourceData.Data fileSourceData, BatchReport.Component component) {
FileSourceDb.Data fileData = fileSourceData.getFileSourceData();

byte[] data = FileSourceDto.encodeSourceData(fileData);
String dataHash = DigestUtils.md5Hex(data);
String srcHash = fileSourceData.getSrcHash();
String lineHashes = fileSourceData.getLineHashes();
String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
FileSourceDto previousDto = fileSourcesContext.previousFileSourcesByUuid.get(componentUuid);

if (previousDto == null) {
FileSourceDto dto = new FileSourceDto()
.setProjectUuid(fileSourcesContext.projectUuid)
.setFileUuid(componentUuid)
.setDataType(Type.SOURCE)
.setBinaryData(data)
.setSrcHash(srcHash)
.setDataHash(dataHash)
.setLineHashes(lineHashes)
.setCreatedAt(system2.now())
.setUpdatedAt(system2.now());
dbClient.fileSourceDao().insert(fileSourcesContext.session, dto);
fileSourcesContext.session.commit();
} else {
// Update only if data_hash has changed or if src_hash is missing (progressive migration)
boolean binaryDataUpdated = !dataHash.equals(previousDto.getDataHash());
boolean srcHashUpdated = !srcHash.equals(previousDto.getSrcHash());
if (binaryDataUpdated || srcHashUpdated) {
previousDto
byte[] data = FileSourceDto.encodeSourceData(fileData);
String dataHash = DigestUtils.md5Hex(data);
String srcHash = fileSourceData.getSrcHash();
String lineHashes = fileSourceData.getLineHashes();
FileSourceDto previousDto = previousFileSourcesByUuid.get(componentUuid);

if (previousDto == null) {
FileSourceDto dto = new FileSourceDto()
.setProjectUuid(projectUuid)
.setFileUuid(componentUuid)
.setDataType(Type.SOURCE)
.setBinaryData(data)
.setDataHash(dataHash)
.setSrcHash(srcHash)
.setLineHashes(lineHashes);
// Optimization only change updated at when updating binary data to avoid unnecessary indexation by E/S
if (binaryDataUpdated) {
previousDto.setUpdatedAt(system2.now());
.setDataHash(dataHash)
.setLineHashes(lineHashes)
.setCreatedAt(system2.now())
.setUpdatedAt(system2.now());
dbClient.fileSourceDao().insert(session, dto);
session.commit();
} else {
// Update only if data_hash has changed or if src_hash is missing (progressive migration)
boolean binaryDataUpdated = !dataHash.equals(previousDto.getDataHash());
boolean srcHashUpdated = !srcHash.equals(previousDto.getSrcHash());
if (binaryDataUpdated || srcHashUpdated) {
previousDto
.setBinaryData(data)
.setDataHash(dataHash)
.setSrcHash(srcHash)
.setLineHashes(lineHashes);
// Optimization only change updated at when updating binary data to avoid unnecessary indexation by E/S
if (binaryDataUpdated) {
previousDto.setUpdatedAt(system2.now());
}
dbClient.fileSourceDao().update(previousDto);
session.commit();
}
dbClient.fileSourceDao().update(previousDto);
fileSourcesContext.session.commit();
}
}
}

private static class FileSourcesContext {
DbSession session;
Map<String, FileSourceDto> previousFileSourcesByUuid;
String projectUuid;

public FileSourcesContext(DbSession session, Map<String, FileSourceDto> previousFileSourcesByUuid, String projectUuid) {
this.previousFileSourcesByUuid = previousFileSourcesByUuid;
this.session = session;
this.projectUuid = projectUuid;
}
}

private static class LineReaders {
private final List<LineReader> readers = new ArrayList<>();
private final List<CloseableIterator<?>> iterators = new ArrayList<>();

+ 47
- 30
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java View File

@@ -29,12 +29,16 @@ import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;

import static com.google.common.collect.Lists.newArrayList;
import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

public class PersistMeasuresStep implements ComputationStep {

@@ -46,15 +50,17 @@ public class PersistMeasuresStep implements ComputationStep {
private final DbClient dbClient;
private final RuleCache ruleCache;
private final MetricCache metricCache;
private final DbComponentsRefCache dbComponentsRefCache;
private final DbIdsRepository dbIdsRepository;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache,
DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.ruleCache = ruleCache;
this.metricCache = metricCache;
this.dbComponentsRefCache = dbComponentsRefCache;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@@ -65,33 +71,45 @@ public class PersistMeasuresStep implements ComputationStep {

@Override
public void execute() {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
try (DbSession dbSession = dbClient.openSession(true)) {
recursivelyProcessComponent(dbSession, rootComponentRef);
DbSession dbSession = dbClient.openSession(true);
try {
new MeasureVisitor(dbSession).visit(treeRootHolder.getRoot());
dbSession.commit();
} finally {
dbSession.close();
}
}

private void recursivelyProcessComponent(DbSession dbSession, int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
List<BatchReport.Measure> measures = reportReader.readComponentMeasures(componentRef);
persistMeasures(dbSession, measures, component);
for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(dbSession, childRef);
private class MeasureVisitor extends DepthTraversalTypeAwareVisitor {

private final DbSession session;

private MeasureVisitor(DbSession session) {
super(Component.Type.FILE, PRE_ORDER);
this.session = session;
}

@Override
protected void visitAny(Component component) {
int componentRef = component.getRef();
BatchReport.Component batchComponent = reportReader.readComponent(componentRef);
List<BatchReport.Measure> measures = reportReader.readComponentMeasures(componentRef);
persistMeasures(measures, dbIdsRepository.getComponentId(component), batchComponent.getSnapshotId());

}
}

private void persistMeasures(DbSession dbSession, List<BatchReport.Measure> batchReportMeasures, final BatchReport.Component component) {
for (BatchReport.Measure measure : batchReportMeasures) {
if (FORBIDDEN_METRIC_KEYS.contains(measure.getMetricKey())) {
throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", measure.getMetricKey()));
private void persistMeasures(List<BatchReport.Measure> batchReportMeasures, long componentId, long snapshotId) {
for (BatchReport.Measure measure : batchReportMeasures) {
if (FORBIDDEN_METRIC_KEYS.contains(measure.getMetricKey())) {
throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", measure.getMetricKey()));
}
dbClient.measureDao().insert(session, toMeasureDto(measure, componentId, snapshotId));
}
dbClient.measureDao().insert(dbSession, toMeasureDto(measure, component));
}
}

@VisibleForTesting
MeasureDto toMeasureDto(BatchReport.Measure in, BatchReport.Component component) {
MeasureDto toMeasureDto(BatchReport.Measure in, long componentId, long snapshotId) {
if (!in.hasValueType()) {
throw new IllegalStateException(String.format("Measure %s does not have value type", in));
}
@@ -109,8 +127,8 @@ public class PersistMeasuresStep implements ComputationStep {
out.setAlertText(in.hasAlertText() ? in.getAlertText() : null);
out.setDescription(in.hasDescription() ? in.getDescription() : null);
out.setSeverity(in.hasSeverity() ? in.getSeverity().name() : null);
out.setComponentId(dbComponentsRefCache.getByRef(component.getRef()).getId());
out.setSnapshotId(component.getSnapshotId());
out.setComponentId(componentId);
out.setSnapshotId(snapshotId);
out.setMetricId(metricCache.get(in.getMetricKey()).getId());
out.setRuleId(in.hasRuleKey() ? ruleCache.get(RuleKey.parse(in.getRuleKey())).getId() : null);
out.setCharacteristicId(in.hasCharactericId() ? in.getCharactericId() : null);
@@ -120,6 +138,13 @@ public class PersistMeasuresStep implements ComputationStep {
return out;
}

private MeasureDto setData(BatchReport.Measure in, MeasureDto out) {
if (in.hasStringValue()) {
out.setData(in.getStringValue());
}
return out;
}

/**
* return the numerical value as a double. It's the type used in db.
* Returns null if no numerical value found
@@ -139,12 +164,4 @@ public class PersistMeasuresStep implements ComputationStep {
return null;
}
}

private MeasureDto setData(BatchReport.Measure in, MeasureDto out) {
if (in.hasStringValue()) {
out.setData(in.getStringValue());
}

return out;
}
}

+ 40
- 40
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java View File

@@ -30,13 +30,15 @@ import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.index.SourceLineIndex;

import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {

@@ -46,18 +48,16 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
private final SourceLineIndex sourceLineIndex;
private final MetricCache metricCache;
private final System2 system;
private final DbComponentsRefCache dbComponentsRefCache;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

private long lastCommitTimestamp = 0L;

public PersistNumberOfDaysSinceLastCommitStep(System2 system, DbClient dbClient, SourceLineIndex sourceLineIndex, MetricCache metricCache,
DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.sourceLineIndex = sourceLineIndex;
this.metricCache = metricCache;
this.system = system;
this.dbComponentsRefCache = dbComponentsRefCache;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@@ -68,38 +68,17 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {

@Override
public void execute() {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
recursivelyProcessComponent(rootComponentRef);
NumberOfDaysSinceLastCommitVisitor visitor = new NumberOfDaysSinceLastCommitVisitor();
visitor.visit(treeRootHolder.getRoot());

if (!commitFound()) {
Long lastCommitFromIndex = lastCommitFromIndex(dbComponentsRefCache.getByRef(rootComponentRef).getUuid());
long lastCommitTimestamp = visitor.lastCommitTimestampFromReport;
if (lastCommitTimestamp == 0L) {
Long lastCommitFromIndex = lastCommitFromIndex(treeRootHolder.getRoot().getUuid());
lastCommitTimestamp = firstNonNull(lastCommitFromIndex, lastCommitTimestamp);
}

if (commitFound()) {
persistNumberOfDaysSinceLastCommit();
}
}

private void recursivelyProcessComponent(int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
BatchReport.Changesets scm = reportReader.readChangesets(componentRef);
processScm(scm);

for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(childRef);
}
}

private void processScm(@Nullable BatchReport.Changesets scm) {
if (scm == null) {
return;
}

for (BatchReport.Changesets.Changeset changeset : scm.getChangesetList()) {
if (changeset.hasDate() && changeset.getDate() > lastCommitTimestamp) {
lastCommitTimestamp = changeset.getDate();
}
if (lastCommitTimestamp != 0L) {
persistNumberOfDaysSinceLastCommit(lastCommitTimestamp);
}
}

@@ -109,9 +88,7 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
return lastCommitDate == null ? null : lastCommitDate.getTime();
}

private void persistNumberOfDaysSinceLastCommit() {
checkState(commitFound(), "The last commit time should exist");

private void persistNumberOfDaysSinceLastCommit(long lastCommitTimestamp) {
long numberOfDaysSinceLastCommit = (system.now() - lastCommitTimestamp) / MILLISECONDS_PER_DAY;
DbSession dbSession = dbClient.openSession(true);
try {
@@ -125,7 +102,30 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
}
}

private boolean commitFound() {
return lastCommitTimestamp != 0L;
private class NumberOfDaysSinceLastCommitVisitor extends DepthTraversalTypeAwareVisitor {

private long lastCommitTimestampFromReport = 0L;

private NumberOfDaysSinceLastCommitVisitor() {
super(Component.Type.FILE, PRE_ORDER);
}

@Override
public void visitFile(Component component) {
BatchReport.Changesets scm = reportReader.readChangesets(component.getRef());
processScm(scm);
}

private void processScm(@Nullable BatchReport.Changesets scm) {
if (scm == null) {
return;
}

for (BatchReport.Changesets.Changeset changeset : scm.getChangesetList()) {
if (changeset.hasDate() && changeset.getDate() > lastCommitTimestampFromReport) {
lastCommitTimestampFromReport = changeset.getDate();
}
}
}
}
}

+ 60
- 46
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java View File

@@ -35,10 +35,13 @@ import org.sonar.core.component.ComponentLinkDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

import static com.google.common.collect.Sets.newHashSet;
import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;

/**
* Persist project and module links
@@ -47,7 +50,7 @@ public class PersistProjectLinksStep implements ComputationStep {

private final DbClient dbClient;
private final I18n i18n;
private final DbComponentsRefCache dbComponentsRefCache;
private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;

private static final Map<Constants.ComponentLinkType, String> typesConverter = ImmutableMap.of(
@@ -58,10 +61,10 @@ public class PersistProjectLinksStep implements ComputationStep {
Constants.ComponentLinkType.ISSUE, ComponentLinkDto.TYPE_ISSUE_TRACKER
);

public PersistProjectLinksStep(DbClient dbClient, I18n i18n, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistProjectLinksStep(DbClient dbClient, I18n i18n, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
this.dbClient = dbClient;
this.i18n = i18n;
this.dbComponentsRefCache = dbComponentsRefCache;
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
}

@@ -69,65 +72,76 @@ public class PersistProjectLinksStep implements ComputationStep {
public void execute() {
DbSession session = dbClient.openSession(false);
try {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
recursivelyProcessComponent(session, rootComponentRef);
new PorjectLinkVisitor(session).visit(treeRootHolder.getRoot());
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
}

private void recursivelyProcessComponent(DbSession session, int componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
processLinks(session, component);
private class PorjectLinkVisitor extends DepthTraversalTypeAwareVisitor {

for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(session, childRef);
private final DbSession session;

private PorjectLinkVisitor(DbSession session) {
super(Component.Type.FILE, PRE_ORDER);
this.session = session;
}

@Override
public void visitProject(Component project) {
processComponent(project);
}
}

private void processLinks(DbSession session, BatchReport.Component component) {
if (component.getType().equals(Constants.ComponentType.PROJECT) || component.getType().equals(Constants.ComponentType.MODULE)) {
List<BatchReport.ComponentLink> links = component.getLinkList();
String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
@Override
public void visitModule(Component module) {
processComponent(module);
}

private void processComponent(Component component) {
BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
processLinks(component.getUuid(), batchComponent.getLinkList());
}

private void processLinks(String componentUuid, List<BatchReport.ComponentLink> links) {
List<ComponentLinkDto> previousLinks = dbClient.componentLinkDao().selectByComponentUuid(session, componentUuid);
mergeLinks(session, componentUuid, links, previousLinks);
}
}

private void mergeLinks(DbSession session, String componentUuid, List<BatchReport.ComponentLink> links, List<ComponentLinkDto> previousLinks) {
Set<String> linkType = newHashSet();
for (final BatchReport.ComponentLink link : links) {
String type = convertType(link.getType());
if (!linkType.contains(type)) {
linkType.add(type);
} else {
throw new IllegalArgumentException(String.format("Link of type '%s' has already been declared on component '%s'", type, componentUuid));
}
private void mergeLinks(DbSession session, String componentUuid, List<BatchReport.ComponentLink> links, List<ComponentLinkDto> previousLinks) {
Set<String> linkType = newHashSet();
for (final BatchReport.ComponentLink link : links) {
String type = convertType(link.getType());
if (!linkType.contains(type)) {
linkType.add(type);
} else {
throw new IllegalArgumentException(String.format("Link of type '%s' has already been declared on component '%s'", type, componentUuid));
}

ComponentLinkDto previousLink = Iterables.find(previousLinks, new Predicate<ComponentLinkDto>() {
@Override
public boolean apply(@Nullable ComponentLinkDto input) {
return input != null && input.getType().equals(convertType(link.getType()));
ComponentLinkDto previousLink = Iterables.find(previousLinks, new Predicate<ComponentLinkDto>() {
@Override
public boolean apply(@Nullable ComponentLinkDto input) {
return input != null && input.getType().equals(convertType(link.getType()));
}
}, null);
if (previousLink == null) {
dbClient.componentLinkDao().insert(session,
new ComponentLinkDto()
.setComponentUuid(componentUuid)
.setType(type)
.setName(i18n.message(Locale.ENGLISH, "project_links." + type, null))
.setHref(link.getHref())
);
} else {
previousLink.setHref(link.getHref());
dbClient.componentLinkDao().update(session, previousLink);
}
}, null);
if (previousLink == null) {
dbClient.componentLinkDao().insert(session,
new ComponentLinkDto()
.setComponentUuid(componentUuid)
.setType(type)
.setName(i18n.message(Locale.ENGLISH, "project_links." + type, null))
.setHref(link.getHref())
);
} else {
previousLink.setHref(link.getHref());
dbClient.componentLinkDao().update(session, previousLink);
}
}

for (ComponentLinkDto dto : previousLinks) {
if (!linkType.contains(dto.getType()) && ComponentLinkDto.PROVIDED_TYPES.contains(dto.getType())) {
dbClient.componentLinkDao().delete(session, dto.getId());
for (ComponentLinkDto dto : previousLinks) {
if (!linkType.contains(dto.getType()) && ComponentLinkDto.PROVIDED_TYPES.contains(dto.getType())) {
dbClient.componentLinkDao().delete(session, dto.getId());
}
}
}
}

+ 11
- 11
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java View File

@@ -46,7 +46,6 @@ import org.sonar.core.source.db.FileSourceDto;
import org.sonar.core.source.db.FileSourceDto.Type;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;
@@ -60,14 +59,12 @@ public class PersistTestsStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.system = system;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}
@@ -76,12 +73,11 @@ public class PersistTestsStep implements ComputationStep {
public void execute() {
DbSession session = dbClient.openSession(true);
try {
TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(session, dbComponentsRefCache);
TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(session);
visitor.visit(treeRootHolder.getRoot());
session.commit();
if (visitor.hasUnprocessedCoverageDetails) {
String projectKey = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getKey();
LOG.warn("Some coverage tests are not taken into account during analysis of project '{}'", projectKey);
LOG.warn("Some coverage tests are not taken into account during analysis of project '{}'", visitor.getProjectKey());
}
} finally {
MyBatis.closeQuietly(session);
@@ -95,17 +91,17 @@ public class PersistTestsStep implements ComputationStep {

private class TestDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
final DbSession session;
final DbComponentsRefCache dbComponentsRefCache;
final Map<String, FileSourceDto> existingFileSourcesByUuid;
final String projectUuid;
final String projectKey;
boolean hasUnprocessedCoverageDetails = false;

public TestDepthTraversalTypeAwareVisitor(DbSession session, DbComponentsRefCache dbComponentsRefCache) {
public TestDepthTraversalTypeAwareVisitor(DbSession session) {
super(Component.Type.FILE, Order.PRE_ORDER);
this.session = session;
this.dbComponentsRefCache = dbComponentsRefCache;
this.existingFileSourcesByUuid = new HashMap<>();
this.projectUuid = treeRootHolder.getRoot().getUuid();
this.projectKey = treeRootHolder.getRoot().getKey();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject",
ImmutableMap.of("projectUuid", treeRootHolder.getRoot().getUuid(), "dataType", Type.TEST),
new ResultHandler() {
@@ -247,7 +243,11 @@ public class PersistTestsStep implements ComputationStep {
}

private String getUuid(int fileRef) {
return dbComponentsRefCache.getByRef(fileRef).getUuid();
return treeRootHolder.getComponentByRef(fileRef).getUuid();
}

public String getProjectKey() {
return projectKey;
}
}


+ 11
- 10
server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java View File

@@ -24,34 +24,35 @@ import org.sonar.core.computation.dbcleaner.ProjectCleaner;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.purge.IdUuidPair;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.ProjectSettingsRepository;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

public class PurgeDatastoresStep implements ComputationStep {

private final ProjectCleaner projectCleaner;
private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;
private final DbIdsRepository dbIdsRepository;
private final TreeRootHolder treeRootHolder;
private final ProjectSettingsRepository projectSettingsRepository;
private final BatchReportReader reportReader;

public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbComponentsRefCache dbComponentsRefCache,
ProjectSettingsRepository projectSettingsRepository, BatchReportReader reportReader) {
public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
ProjectSettingsRepository projectSettingsRepository) {
this.projectCleaner = projectCleaner;
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
this.projectSettingsRepository = projectSettingsRepository;
this.reportReader = reportReader;
}

@Override
public void execute() {
DbSession session = dbClient.openSession(true);
try {
DbComponentsRefCache.DbComponent project = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef());
projectCleaner.purge(session, new IdUuidPair(project.getId(), project.getUuid()), projectSettingsRepository.getProjectSettings(project.getKey()));
Component project = treeRootHolder.getRoot();
projectCleaner.purge(session, new IdUuidPair(dbIdsRepository.getComponentId(project), project.getUuid()), projectSettingsRepository.getProjectSettings(project.getKey()));
session.commit();
} finally {
MyBatis.closeQuietly(session);

+ 8
- 8
server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java View File

@@ -25,8 +25,8 @@ import java.util.Map;
import java.util.Set;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.issue.IssueCache;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.issue.notification.IssueChangeNotification;
@@ -50,16 +50,16 @@ public class SendIssueNotificationsStep implements ComputationStep {

private final IssueCache issueCache;
private final RuleCache rules;
private final DbComponentsRefCache dbComponentsRefCache;
private final TreeRootHolder treeRootHolder;
private final NotificationService service;
private final BatchReportReader reportReader;
private NewIssuesNotificationFactory newIssuesNotificationFactory;

public SendIssueNotificationsStep(IssueCache issueCache, RuleCache rules, DbComponentsRefCache dbComponentsRefCache, NotificationService service,
public SendIssueNotificationsStep(IssueCache issueCache, RuleCache rules, TreeRootHolder treeRootHolder, NotificationService service,
BatchReportReader reportReader, NewIssuesNotificationFactory newIssuesNotificationFactory) {
this.issueCache = issueCache;
this.rules = rules;
this.dbComponentsRefCache = dbComponentsRefCache;
this.treeRootHolder = treeRootHolder;
this.service = service;
this.reportReader = reportReader;
this.newIssuesNotificationFactory = newIssuesNotificationFactory;
@@ -67,13 +67,13 @@ public class SendIssueNotificationsStep implements ComputationStep {

@Override
public void execute() {
DbComponent project = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef());
Component project = treeRootHolder.getRoot();
if (service.hasProjectSubscribersForTypes(project.getUuid(), NOTIF_TYPES)) {
doExecute(project);
}
}

private void doExecute(DbComponent project) {
private void doExecute(Component project) {
NewIssuesStatistics newIssuesStats = new NewIssuesStatistics();
CloseableIterator<DefaultIssue> issues = issueCache.traverse();
String projectName = reportReader.readComponent(reportReader.readMetadata().getRootComponentRef()).getName();
@@ -97,7 +97,7 @@ public class SendIssueNotificationsStep implements ComputationStep {
sendNewIssuesStatistics(newIssuesStats, project, projectName);
}

private void sendNewIssuesStatistics(NewIssuesStatistics statistics, DbComponent project, String projectName) {
private void sendNewIssuesStatistics(NewIssuesStatistics statistics, Component project, String projectName) {
if (statistics.hasIssues()) {
NewIssuesStatistics.Stats globalStatistics = statistics.globalStatistics();
long analysisDate = reportReader.readMetadata().getAnalysisDate();

+ 127
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java View File

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

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import java.util.Objects;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentImpl;
import org.sonar.server.computation.component.DumbComponent;

public class ComponentTreeRule implements TestRule {

@CheckForNull
private final BatchReportReader batchReportReader;
private final BUILD_OPTIONS buildOptions;

private Component root;

private ComponentTreeRule(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
this.batchReportReader = batchReportReader;
this.buildOptions = buildOptions;
}

public static ComponentTreeRule from(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), buildOptions);
}

public static ComponentTreeRule from(BatchReportReader batchReportReader) {
return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), BUILD_OPTIONS.NONE);
}

@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
statement.evaluate();
} finally {
clear();
}
}
};
}

private void clear() {
this.root = null;
}

public enum BUILD_OPTIONS {
NONE(false, false), KEY(false, true), UUID(true, false), KEY_AND_UUID(true, true);
private final boolean uuid;
private final boolean key;

BUILD_OPTIONS(boolean uuid, boolean key) {
this.uuid = uuid;
this.key = key;
}
}

public Component getRoot() {
if (root == null) {
buildComponentRoot(buildOptions);
}
return this.root;
}

private Component buildComponentRoot(BUILD_OPTIONS build_options) {
int rootComponentRef = batchReportReader.readMetadata().getRootComponentRef();
return newComponent(batchReportReader.readComponent(rootComponentRef), build_options);
}

private DumbComponent newComponent(BatchReport.Component component, BUILD_OPTIONS build_options) {
return new DumbComponent(
ComponentImpl.convertType(component.getType()),
component.getRef(),
build_options.uuid ? uuidOf(component.getRef()) : null,
build_options.key ? keyOf(component.getRef()) : null,
buildChildren(component, build_options));
}

private Component[] buildChildren(BatchReport.Component component, final BUILD_OPTIONS build_options) {
return Iterables.toArray(
Iterables.transform(
component.getChildRefList(),
new Function<Integer, Component>() {
@Override
public Component apply(@Nonnull Integer componentRef) {
return newComponent(batchReportReader.readComponent(componentRef), build_options);
}
}
), Component.class);
}

public String keyOf(int ref) {
return "key_" + ref;
}

public String uuidOf(int ref) {
return "uuid_" + ref;
}
}

server/sonar-server/src/test/java/org/sonar/server/computation/component/DbComponentsRefCacheTest.java → server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java View File

@@ -20,26 +20,43 @@

package org.sonar.server.computation.component;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

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

public class DbComponentsRefCacheTest {
public class DbIdsRepositoryTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

Component component = DumbComponent.DUMB_PROJECT;

@Test
public void add_and_get_component() throws Exception {
DbComponentsRefCache cache = new DbComponentsRefCache();
cache.addComponent(1, new DbComponentsRefCache.DbComponent(10L, "Key", "Uuid"));
DbIdsRepository cache = new DbIdsRepository();
cache.setComponentId(component, 10L);

assertThat(cache.getByRef(1)).isNotNull();
assertThat(cache.getByRef(1).getId()).isEqualTo(10L);
assertThat(cache.getByRef(1).getKey()).isEqualTo("Key");
assertThat(cache.getByRef(1).getUuid()).isEqualTo("Uuid");
assertThat(cache.getComponentId(component)).isEqualTo(10L);
}

@Test(expected = IllegalArgumentException.class)
@Test
public void fail_on_unknown_ref() throws Exception {
new DbComponentsRefCache().getByRef(1);
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Component ref '" + component.getRef() + "' has no component id");

new DbIdsRepository().getComponentId(DumbComponent.DUMB_PROJECT);
}

@Test
public void fail_if_component_id_already_set() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Component ref '" + component.getRef() + "' has already a component id");

DbIdsRepository cache = new DbIdsRepository();
cache.setComponentId(component, 10L);
cache.setComponentId(component, 11L);
}

}

+ 13
- 9
server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java View File

@@ -45,7 +45,7 @@ import org.sonar.server.component.ComponentTesting;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.es.EsTester;
@@ -63,8 +63,10 @@ public class ApplyPermissionsStepTest extends BaseStepTest {

@ClassRule
public static EsTester esTester = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()));

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

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@@ -74,7 +76,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {

Settings settings;

DbComponentsRefCache dbComponentsRefCache;
DbIdsRepository dbIdsRepository;

IssueAuthorizationIndexer issueAuthorizationIndexer;
ApplyPermissionsStep step;
@@ -94,10 +96,10 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
issueAuthorizationIndexer = new IssueAuthorizationIndexer(dbClient, esTester.client());
issueAuthorizationIndexer.setEnabled(true);

dbComponentsRefCache = new DbComponentsRefCache();
dbIdsRepository = new DbIdsRepository();

step = new ApplyPermissionsStep(dbClient, dbComponentsRefCache, issueAuthorizationIndexer, new PermissionFacade(roleDao, null,
new ResourceDao(dbTester.myBatis(), System2.INSTANCE), permissionTemplateDao, settings), treeRootHolder);
step = new ApplyPermissionsStep(dbClient, dbIdsRepository, issueAuthorizationIndexer, new PermissionFacade(roleDao, null,
new ResourceDao(dbTester.myBatis(), System2.INSTANCE), permissionTemplateDao, settings), treeRootHolder);
}

@After
@@ -116,8 +118,9 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
dbClient.permissionTemplateDao().addGroupPermission(permissionTemplateDto.getId(), null, UserRole.USER);
dbSession.commit();

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(projectDto.getId(), PROJECT_KEY, PROJECT_UUID));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_KEY, PROJECT_UUID));
Component project = new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY);
dbIdsRepository.setComponentId(project, projectDto.getId());
treeRootHolder.setRoot(project);

step.execute();
dbSession.commit();
@@ -143,8 +146,9 @@ public class ApplyPermissionsStepTest extends BaseStepTest {

dbSession.commit();

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(projectDto.getId(), PROJECT_KEY, PROJECT_UUID));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_KEY, PROJECT_UUID));
Component project = new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY);
dbIdsRepository.setComponentId(project, projectDto.getId());
treeRootHolder.setRoot(project);

step.execute();
dbSession.commit();

+ 12
- 15
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java View File

@@ -23,38 +23,35 @@ package org.sonar.server.computation.step;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class IndexComponentsStepTest extends BaseStepTest {

private static final String PROJECT_KEY = "PROJECT_KEY";

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

ResourceIndexerDao resourceIndexerDao = mock(ResourceIndexerDao.class);
DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao, dbComponentsRefCache, reportReader);
DbIdsRepository dbIdsRepository = new DbIdsRepository();
IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao, dbIdsRepository, treeRootHolder);

@Test
public void call_indexProject_of_dao() throws IOException {
dbComponentsRefCache.addComponent(1, new DbComponent(123L, PROJECT_KEY, "PROJECT_UUID"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

ComponentDto project = mock(ComponentDto.class);
when(project.getId()).thenReturn(123L);
Component project = new DumbComponent(Component.Type.PROJECT, 1, "PROJECT_UUID", PROJECT_KEY);
dbIdsRepository.setComponentId(project, 123L);
treeRootHolder.setRoot(project);

sut.execute();


+ 8
- 14
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java View File

@@ -27,10 +27,10 @@ import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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.server.es.EsTester;
import org.sonar.server.source.db.FileSourceDao;
@@ -43,43 +43,37 @@ import static org.assertj.core.api.Assertions.assertThat;

public class IndexSourceLinesStepTest extends BaseStepTest {

private static final String PROJECT_KEY = "PROJECT_KEY";

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

@ClassRule
public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings()));

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

DbClient dbClient;
DbComponentsRefCache dbComponentsRefCache;

@Before
public void setUp() {
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new FileSourceDao(null));
dbComponentsRefCache = new DbComponentsRefCache();
}

@Override
protected ComputationStep step() {
SourceLineIndexer sourceLineIndexer = new SourceLineIndexer(dbClient, esTester.client());
sourceLineIndexer.setEnabled(true);
return new IndexSourceLinesStep(sourceLineIndexer, dbComponentsRefCache, reportReader);
return new IndexSourceLinesStep(sourceLineIndexer, treeRootHolder);
}

@Test
public void index_source() throws Exception {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

dbTester.prepareDbUnit(getClass(), "index_source.xml");
Connection connection = dbTester.openConnection();
FileSourceTesting.updateDataColumn(connection, "FILE1_UUID", FileSourceTesting.newRandomData(1).build());
connection.close();

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", "PROJECT_KEY"));

step().execute();


+ 8
- 12
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java View File

@@ -28,10 +28,10 @@ import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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.server.es.EsTester;
import org.sonar.server.source.db.FileSourceDao;
@@ -46,40 +46,36 @@ public class IndexTestsStepTest extends BaseStepTest {

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

@ClassRule
public static EsTester esTester = new EsTester().addDefinitions(new TestIndexDefinition(new Settings()));

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

DbClient dbClient;
DbComponentsRefCache dbComponentsRefCache;

@Before
public void setUp() {
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new FileSourceDao(null));
esTester.truncateIndices();
dbComponentsRefCache = new DbComponentsRefCache();
}

@Override
protected ComputationStep step() {
TestIndexer testIndexer = new TestIndexer(dbClient, esTester.client());
testIndexer.setEnabled(true);
return new IndexTestsStep(testIndexer, dbComponentsRefCache, reportReader);
return new IndexTestsStep(testIndexer, treeRootHolder);
}

@Test
public void index_test() throws Exception {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, "PROJECT_KEY", "ABCD"));

dbTester.prepareDbUnit(getClass(), "index_source.xml");
Connection connection = dbTester.openConnection();
TestTesting.updateDataColumn(connection, "FILE1_UUID", TestTesting.newRandomTests(1));
connection.close();

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", "PROJECT_KEY"));

step().execute();


+ 119
- 115
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java View File

@@ -36,13 +36,12 @@ import org.sonar.server.component.db.ComponentDao;
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.DbComponentsRefCache;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

@Category(DbTests.class)
public class PersistComponentsStepTest extends BaseStepTest {
@@ -51,14 +50,17 @@ public class PersistComponentsStepTest extends BaseStepTest {

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

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

DbIdsRepository dbIdsRepository;

DbSession session;
DbClient dbClient;
DbComponentsRefCache dbComponentsRefCache;

PersistComponentsStep sut;

@@ -68,8 +70,8 @@ public class PersistComponentsStepTest extends BaseStepTest {
session = dbTester.myBatis().openSession(false);
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());

dbComponentsRefCache = new DbComponentsRefCache();
sut = new PersistComponentsStep(dbClient, dbComponentsRefCache, reportReader, treeRootHolder);
dbIdsRepository = new DbIdsRepository();
sut = new PersistComponentsStep(dbClient, dbIdsRepository, reportReader, treeRootHolder);
}

@Override
@@ -118,71 +120,73 @@ public class PersistComponentsStepTest extends BaseStepTest {
.setLanguage("java")
.build());

treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir",
new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java")))));
Component file = new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java");
Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir", file);
Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", directory);
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module);
treeRootHolder.setRoot(project);

sut.execute();

assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);

ComponentDto project = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY);
assertThat(project).isNotNull();
assertThat(project.name()).isEqualTo("Project");
assertThat(project.description()).isEqualTo("Project description");
assertThat(project.path()).isNull();
assertThat(project.uuid()).isEqualTo("ABCD");
assertThat(project.moduleUuid()).isNull();
assertThat(project.moduleUuidPath()).isEqualTo("." + project.uuid() + ".");
assertThat(project.projectUuid()).isEqualTo(project.uuid());
assertThat(project.qualifier()).isEqualTo("TRK");
assertThat(project.scope()).isEqualTo("PRJ");
assertThat(project.parentProjectId()).isNull();
ComponentDto module = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
assertThat(module).isNotNull();
assertThat(module.name()).isEqualTo("Module");
assertThat(module.description()).isEqualTo("Module description");
assertThat(module.path()).isEqualTo("module");
assertThat(module.uuid()).isEqualTo("BCDE");
assertThat(module.moduleUuid()).isEqualTo(project.uuid());
assertThat(module.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + module.uuid() + ".");
assertThat(module.projectUuid()).isEqualTo(project.uuid());
assertThat(module.qualifier()).isEqualTo("BRC");
assertThat(module.scope()).isEqualTo("PRJ");
assertThat(module.parentProjectId()).isEqualTo(project.getId());
ComponentDto directory = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
assertThat(directory).isNotNull();
assertThat(directory.name()).isEqualTo("src/main/java/dir");
assertThat(directory.description()).isNull();
assertThat(directory.path()).isEqualTo("src/main/java/dir");
assertThat(directory.uuid()).isEqualTo("CDEF");
assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
assertThat(directory.projectUuid()).isEqualTo(project.uuid());
assertThat(directory.qualifier()).isEqualTo("DIR");
assertThat(directory.scope()).isEqualTo("DIR");
assertThat(directory.parentProjectId()).isEqualTo(module.getId());
ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
assertThat(file).isNotNull();
assertThat(file.name()).isEqualTo("Foo.java");
assertThat(file.description()).isNull();
assertThat(file.path()).isEqualTo("src/main/java/dir/Foo.java");
assertThat(file.language()).isEqualTo("java");
assertThat(file.uuid()).isEqualTo("DEFG");
assertThat(file.moduleUuid()).isEqualTo(module.uuid());
assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
assertThat(file.projectUuid()).isEqualTo(project.uuid());
assertThat(file.qualifier()).isEqualTo("FIL");
assertThat(file.scope()).isEqualTo("FIL");
assertThat(file.parentProjectId()).isEqualTo(module.getId());
assertThat(dbComponentsRefCache.getByRef(1).getId()).isEqualTo(project.getId());
assertThat(dbComponentsRefCache.getByRef(2).getId()).isEqualTo(module.getId());
assertThat(dbComponentsRefCache.getByRef(3).getId()).isEqualTo(directory.getId());
assertThat(dbComponentsRefCache.getByRef(4).getId()).isEqualTo(file.getId());
ComponentDto projectDto = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY);
assertThat(projectDto).isNotNull();
assertThat(projectDto.name()).isEqualTo("Project");
assertThat(projectDto.description()).isEqualTo("Project description");
assertThat(projectDto.path()).isNull();
assertThat(projectDto.uuid()).isEqualTo("ABCD");
assertThat(projectDto.moduleUuid()).isNull();
assertThat(projectDto.moduleUuidPath()).isEqualTo("." + projectDto.uuid() + ".");
assertThat(projectDto.projectUuid()).isEqualTo(projectDto.uuid());
assertThat(projectDto.qualifier()).isEqualTo("TRK");
assertThat(projectDto.scope()).isEqualTo("PRJ");
assertThat(projectDto.parentProjectId()).isNull();
ComponentDto moduleDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
assertThat(moduleDto).isNotNull();
assertThat(moduleDto.name()).isEqualTo("Module");
assertThat(moduleDto.description()).isEqualTo("Module description");
assertThat(moduleDto.path()).isEqualTo("module");
assertThat(moduleDto.uuid()).isEqualTo("BCDE");
assertThat(moduleDto.moduleUuid()).isEqualTo(projectDto.uuid());
assertThat(moduleDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath() + moduleDto.uuid() + ".");
assertThat(moduleDto.projectUuid()).isEqualTo(projectDto.uuid());
assertThat(moduleDto.qualifier()).isEqualTo("BRC");
assertThat(moduleDto.scope()).isEqualTo("PRJ");
assertThat(moduleDto.parentProjectId()).isEqualTo(projectDto.getId());
ComponentDto directoryDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
assertThat(directoryDto).isNotNull();
assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
assertThat(directoryDto.description()).isNull();
assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
assertThat(directoryDto.uuid()).isEqualTo("CDEF");
assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
assertThat(directoryDto.projectUuid()).isEqualTo(projectDto.uuid());
assertThat(directoryDto.qualifier()).isEqualTo("DIR");
assertThat(directoryDto.scope()).isEqualTo("DIR");
assertThat(directoryDto.parentProjectId()).isEqualTo(moduleDto.getId());
ComponentDto fileDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
assertThat(fileDto).isNotNull();
assertThat(fileDto.name()).isEqualTo("Foo.java");
assertThat(fileDto.description()).isNull();
assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
assertThat(fileDto.language()).isEqualTo("java");
assertThat(fileDto.uuid()).isEqualTo("DEFG");
assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
assertThat(fileDto.projectUuid()).isEqualTo(projectDto.uuid());
assertThat(fileDto.qualifier()).isEqualTo("FIL");
assertThat(fileDto.scope()).isEqualTo("FIL");
assertThat(fileDto.parentProjectId()).isEqualTo(moduleDto.getId());
assertThat(dbIdsRepository.getComponentId(project)).isEqualTo(projectDto.getId());
assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId());
assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId());
assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
}

@Test
@@ -286,23 +290,23 @@ public class PersistComponentsStepTest extends BaseStepTest {
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
@@ -488,16 +492,16 @@ public class PersistComponentsStepTest extends BaseStepTest {
session.commit();

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
.setRootComponentRef(1)
.build());

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setName("Project")
.addChildRef(2)
.build());
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setName("Project")
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
@@ -506,16 +510,16 @@ public class PersistComponentsStepTest extends BaseStepTest {
.addChildRef(3)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
@@ -575,23 +579,23 @@ public class PersistComponentsStepTest extends BaseStepTest {
session.commit();

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setName("New project name")
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("New module name")
.setPath("New path")
.build());
.setRootComponentRef(1)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setName("New project name")
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("New module name")
.setPath("New path")
.build());

treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY")));

+ 66
- 43
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java View File

@@ -27,7 +27,6 @@ import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
@@ -36,9 +35,10 @@ import org.sonar.core.metric.db.MetricDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.computation.language.LanguageRepository;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.metric.persistence.MetricDao;
@@ -46,7 +46,6 @@ import org.sonar.test.DbTests;

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

@Category(DbTests.class)
public class PersistDuplicationsStepTest extends BaseStepTest {
@@ -59,14 +58,14 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

DbSession session;
@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

DbClient dbClient;
DbIdsRepository dbIdsRepository = new DbIdsRepository();

Settings projectSettings;
LanguageRepository languageRepository;
DbSession session;

DbComponentsRefCache dbComponentsRefCache;
DbClient dbClient;

PersistDuplicationsStep sut;

@@ -76,10 +75,7 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
session = dbTester.myBatis().openSession(false);
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new MetricDao());

projectSettings = new Settings();
dbComponentsRefCache = new DbComponentsRefCache();
languageRepository = mock(LanguageRepository.class);
sut = new PersistDuplicationsStep(dbClient, dbComponentsRefCache, reportReader);
sut = new PersistDuplicationsStep(dbClient, dbIdsRepository, treeRootHolder, reportReader);
}

@Override
@@ -135,16 +131,18 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

@Test
public void persist_duplications_on_same_file_linked_on_a_module() throws Exception {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "BCDE"));
dbComponentsRefCache.addComponent(3, new DbComponent(3L, "MODULE_KEY:file", "CDEF"));
Component file = new DumbComponent(Component.Type.FILE, 3, "CDEF", "MODULE_KEY:file");
Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", file);
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module);
treeRootHolder.setRoot(project);

saveDuplicationMetric();
dbIdsRepository.setComponentId(project, 1);
dbIdsRepository.setComponentId(module, 3);
dbIdsRepository.setComponentId(file, 2);

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
saveDuplicationMetric();

// TODO remove this when snapshot id will come from the DbIdsRepo
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
@@ -192,17 +190,18 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

@Test
public void persist_duplications_on_same_file_linked_on_a_folder() {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:dir", "BCDE"));
dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:file", "CDEF"));
Component file = new DumbComponent(Component.Type.FILE, 3, "CDEF", "PROJECT_KEY:file");
Component directory = new DumbComponent(Component.Type.DIRECTORY, 2, "BCDE", "PROJECT_KEY:dir", file);
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, directory);
treeRootHolder.setRoot(project);

dbIdsRepository.setComponentId(project, 1);
dbIdsRepository.setComponentId(directory, 3);
dbIdsRepository.setComponentId(file, 2);

saveDuplicationMetric();

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

// TODO remove this when snapshot id will come from the DbIdsRepo
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
@@ -250,17 +249,20 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

@Test
public void persist_duplications_on_same_file_linked_on_sub_folder() {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:dir", "BCDE"));
dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:dir", "CDEF"));
dbComponentsRefCache.addComponent(10, new DbComponent(10L, "PROJECT_KEY:file", "DEFG"));
Component file = new DumbComponent(Component.Type.FILE, 10, "DEFG", "PROJECT_KEY:file");
Component directory1 = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "PROJECT_KEY:dir1", file);
Component directory2 = new DumbComponent(Component.Type.DIRECTORY, 2, "BCDE", "PROJECT_KEY:dir2", directory1);
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, directory2);
treeRootHolder.setRoot(project);

saveDuplicationMetric();
dbIdsRepository.setComponentId(project, 1);
dbIdsRepository.setComponentId(directory1, 2);
dbIdsRepository.setComponentId(directory2, 3);
dbIdsRepository.setComponentId(file, 10);

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
saveDuplicationMetric();

// TODO remove this when snapshot id will come from the DbIdsRepo
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
@@ -314,10 +316,30 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

@Test
public void persist_duplications_on_different_files() {
dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:file2", "CDEF"));
saveDuplicationMetric();
initReportWithProjectAndFile();

Component file2 = new DumbComponent(Component.Type.FILE, 3, "CDEF", "PROJECT_KEY:file2");
Component file = new DumbComponent(Component.Type.FILE, 2, "BCDE", "PROJECT_KEY:file");
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file, file2);
treeRootHolder.setRoot(project);

dbIdsRepository.setComponentId(project, 1);
dbIdsRepository.setComponentId(file, 2);

// TODO remove this when snapshot id will come from the DbIdsRepo
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey(PROJECT_KEY)
.setSnapshotId(10L)
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.FILE)
.setSnapshotId(11L)
.setPath("file")
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.FILE)
@@ -379,13 +401,14 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
}

private void initReportWithProjectAndFile() {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:file", "BCDE"));
Component file = new DumbComponent(Component.Type.FILE, 2, "BCDE", "PROJECT_KEY:file");
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file);
treeRootHolder.setRoot(project);

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());
dbIdsRepository.setComponentId(project, 1);
dbIdsRepository.setComponentId(file, 2);

// TODO remove this when snapshot id will come from the DbIdsRepo
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)

+ 14
- 18
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java View File

@@ -32,8 +32,9 @@ import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
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.server.event.db.EventDao;
import org.sonar.test.DbTests;
@@ -44,15 +45,16 @@ import static org.mockito.Mockito.when;
@Category(DbTests.class)
public class PersistEventsStepTest extends BaseStepTest {

private static final String PROJECT_KEY = "PROJECT_KEY";

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

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

DbSession session;
DbComponentsRefCache dbComponentsRefCache;
PersistEventsStep step;

@Before
@@ -63,8 +65,7 @@ public class PersistEventsStepTest extends BaseStepTest {
System2 system2 = mock(System2.class);
when(system2.now()).thenReturn(1225630680000L);

dbComponentsRefCache = new DbComponentsRefCache();
step = new PersistEventsStep(dbClient, system2, dbComponentsRefCache, reportReader);
step = new PersistEventsStep(dbClient, system2, treeRootHolder, reportReader);
}

@Override
@@ -81,11 +82,10 @@ public class PersistEventsStepTest extends BaseStepTest {
public void nothing_to_do_when_no_events_in_report() throws Exception {
dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_no_events_in_report.xml");

dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());

@@ -103,11 +103,10 @@ public class PersistEventsStepTest extends BaseStepTest {
public void persist_report_events() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());

@@ -138,12 +137,11 @@ public class PersistEventsStepTest extends BaseStepTest {
public void persist_report_events_with_component_children() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "BCDE"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", null)));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());

@@ -179,11 +177,10 @@ public class PersistEventsStepTest extends BaseStepTest {
public void create_version_event() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());

@@ -203,11 +200,10 @@ public class PersistEventsStepTest extends BaseStepTest {
public void keep_one_event_by_version() throws Exception {
dbTester.prepareDbUnit(getClass(), "keep_one_event_by_version.xml");

dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());


+ 14
- 20
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java View File

@@ -39,7 +39,9 @@ import org.sonar.core.persistence.DbTester;
import org.sonar.core.source.db.FileSourceDto;
import org.sonar.core.source.db.FileSourceDto.Type;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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.computation.language.LanguageRepository;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
@@ -63,6 +65,10 @@ public class PersistFileSourcesStepTest extends BaseStepTest {

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

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@@ -71,7 +77,6 @@ public class PersistFileSourcesStepTest extends BaseStepTest {

DbSession session;
DbClient dbClient;
DbComponentsRefCache dbComponentsRefCache;
PersistFileSourcesStep sut;

long now = 123456789L;
@@ -84,8 +89,7 @@ public class PersistFileSourcesStepTest extends BaseStepTest {

System2 system2 = mock(System2.class);
when(system2.now()).thenReturn(now);
dbComponentsRefCache = new DbComponentsRefCache();
sut = new PersistFileSourcesStep(dbClient, system2, dbComponentsRefCache, reportReader);
sut = new PersistFileSourcesStep(dbClient, system2, treeRootHolder, reportReader);
}

@Override
@@ -124,13 +128,9 @@ public class PersistFileSourcesStepTest extends BaseStepTest {

@Test
public void persist_last_line() throws Exception {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
dbComponentsRefCache.addComponent(FILE_REF, new DbComponentsRefCache.DbComponent(2L, "PROJECT_KEY:file", FILE_UUID));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY,
new DumbComponent(Component.Type.FILE, FILE_REF, FILE_UUID, "PROJECT_KEY:file")));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
@@ -428,19 +428,14 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
sut.execute();
failBecauseExceptionWasNotThrown(IllegalStateException.class);
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Cannot persist sources of src/Foo.java").hasCauseInstanceOf(IllegalArgumentException.class);
assertThat(e).hasMessage("Cannot persist sources of MODULE_KEY:src/Foo.java").hasCauseInstanceOf(IllegalArgumentException.class);
}
}

private void initBasicReport(int numberOfLines) throws IOException {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "MODULE_KEY", "MODULE"));
dbComponentsRefCache.addComponent(FILE_REF, new DbComponentsRefCache.DbComponent(3L, "MODULE_KEY:src/Foo.java", FILE_UUID));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY,
new DumbComponent(Component.Type.MODULE, 2, "MODULE", "MODULE_KEY",
new DumbComponent(Component.Type.FILE, FILE_REF, FILE_UUID, "MODULE_KEY:src/Foo.java"))));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
@@ -455,7 +450,6 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(FILE_REF)
.setType(Constants.ComponentType.FILE)
.setPath("src/Foo.java")
.setLines(numberOfLines)
.build());


+ 40
- 46
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java View File

@@ -45,7 +45,10 @@ import org.sonar.core.persistence.DbTester;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.computation.issue.RuleCacheLoader;
import org.sonar.server.computation.measure.MetricCache;
@@ -65,14 +68,21 @@ public class PersistMeasuresStepTest extends BaseStepTest {
private static final String METRIC_KEY = "metric-key";
private static final RuleKey RULE_KEY = RuleKey.of("repo", "rule-key");

private static final long FILE_COMPONENT_ID = 3L;
private static final long FILE_SNAPSHOT_ID = 3L;

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

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

DbClient dbClient;
DbSession session;
DbComponentsRefCache dbComponentsRefCache;
DbIdsRepository dbIdsRepository = new DbIdsRepository();
MetricDto metric;
RuleDto rule;

@@ -82,8 +92,6 @@ public class PersistMeasuresStepTest extends BaseStepTest {
public void setUp() {
dbTester.truncateTables();

dbComponentsRefCache = new DbComponentsRefCache();

dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new ComponentDao(), new MetricDao(), new RuleDao(System2.INSTANCE));
session = dbClient.openSession(false);

@@ -97,7 +105,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
MetricCache metricCache = new MetricCache(dbClient);
session.commit();

sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbComponentsRefCache, reportReader);
sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbIdsRepository, treeRootHolder, reportReader);
}

@After
@@ -107,8 +115,15 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void insert_measures_from_report() throws Exception {
ComponentDto project = addComponent(1, "project-key");
ComponentDto file = addComponent(2, "file-key");
ComponentDto projectDto = addComponent(1, "project-key");
ComponentDto fileDto = addComponent(2, "file-key");

Component file = new DumbComponent(Component.Type.FILE, 2, "CDEF", "MODULE_KEY:file");
Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file);
treeRootHolder.setRoot(project);

dbIdsRepository.setComponentId(project, projectDto.getId());
dbIdsRepository.setComponentId(file, fileDto.getId());

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setAnalysisDate(new Date().getTime())
@@ -172,7 +187,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {

Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isNotNull();
assertThat(dto.get("componentId")).isEqualTo(project.getId());
assertThat(dto.get("componentId")).isEqualTo(projectDto.getId());
assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
assertThat(dto.get("textValue")).isEqualTo("measure-data");
@@ -180,7 +195,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {

dto = dtos.get(1);
assertThat(dto.get("snapshotId")).isNotNull();
assertThat(dto.get("componentId")).isEqualTo(file.getId());
assertThat(dto.get("componentId")).isEqualTo(fileDto.getId());
assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
assertThat(dto.get("value")).isEqualTo(123.123d);
@@ -210,7 +225,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setPersonId(5432)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);

assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
.setComponentId(componentDto.getId())
@@ -241,11 +256,11 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);

assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
.setComponentId(componentDto.getId())
.setSnapshotId(3L)
.setSnapshotId(FILE_SNAPSHOT_ID)
.setMetricId(metric.getId()));
}

@@ -260,7 +275,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isEqualTo(1.0);

@@ -270,7 +285,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isEqualTo(0.0);

@@ -279,7 +294,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isNull();
}
@@ -295,7 +310,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isEqualTo(3.2);

@@ -304,7 +319,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isNull();
}
@@ -320,7 +335,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isEqualTo(3.0);

@@ -329,7 +344,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isNull();
}
@@ -345,7 +360,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isEqualTo(3.0);

@@ -354,7 +369,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);

assertThat(measure.getValue()).isNull();
}
@@ -368,7 +383,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
}

@Test(expected = IllegalStateException.class)
@@ -379,7 +394,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
}

@Test(expected = IllegalStateException.class)
@@ -390,40 +405,19 @@ public class PersistMeasuresStepTest extends BaseStepTest {
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
}

private MeasureDto expectedFullMeasure() {
return new MeasureDto()
.setComponentId(2L)
.setSnapshotId(3L)
.setCharacteristicId(123456)
.setPersonId(5432)
.setValue(123.123d)
.setVariation(1, 1.1d)
.setVariation(2, 2.2d)
.setVariation(3, 3.3d)
.setVariation(4, 4.4d)
.setVariation(5, 5.5d)
.setAlertStatus("WARN")
.setAlertText("Open issues > 0")
.setDescription("measure-description")
.setSeverity(Severity.CRITICAL)
.setMetricId(metric.getId())
.setRuleId(rule.getId());
sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
}

private BatchReport.Component.Builder defaultComponent() {
return BatchReport.Component.newBuilder()
.setRef(1)
.setSnapshotId(3);
.setSnapshotId(FILE_SNAPSHOT_ID);
}

private ComponentDto addComponent(int ref, String key) {
ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(Uuids.create());
dbClient.componentDao().insert(session, componentDto);
session.commit();
dbComponentsRefCache.addComponent(ref, new DbComponentsRefCache.DbComponent(componentDto.getId(), key, componentDto.uuid()));
return componentDto;
}


+ 10
- 11
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java View File

@@ -33,7 +33,9 @@ import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.metric.db.MetricDto;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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.computation.language.LanguageRepository;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
@@ -48,6 +50,10 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {

@ClassRule
public static DbTester db = new DbTester();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@@ -59,8 +65,6 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
Settings projectSettings;
LanguageRepository languageRepository;

DbComponentsRefCache dbComponentsRefCache;

@Before
public void setUp() throws Exception {
db.truncateTables();
@@ -70,9 +74,8 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
projectSettings = new Settings();
languageRepository = mock(LanguageRepository.class);
when(metricCache.get(anyString())).thenReturn(new MetricDto().setId(10));
dbComponentsRefCache = new DbComponentsRefCache();

sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, dbComponentsRefCache, reportReader);
sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, treeRootHolder, reportReader);
}

@Override
@@ -120,25 +123,21 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
}

private void initReportWithProjectAndFile() {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, "PROJECT_KEY", "project-uuid"));
dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "PROJECT_KEY:file", "file-uuid"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "project-uuid", null,
new DumbComponent(Component.Type.FILE, 2, "file-uuid", null)));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setSnapshotId(1000)
.build());

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setSnapshotId(10L)
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.FILE)
.setSnapshotId(11L)
.build());
}
}

+ 22
- 50
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java View File

@@ -34,7 +34,9 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.db.ComponentLinkDao;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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;

@@ -46,15 +48,16 @@ import static org.mockito.Mockito.when;
@Category(DbTests.class)
public class PersistProjectLinksStepTest extends BaseStepTest {

private static final String PROJECT_KEY = "PROJECT_KEY";

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

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

DbSession session;
DbComponentsRefCache dbComponentsRefCache;

PersistProjectLinksStep step;

@@ -70,8 +73,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
when(i18n.message(Locale.ENGLISH, "project_links.ci", null)).thenReturn("Continuous integration");
when(i18n.message(Locale.ENGLISH, "project_links.issue", null)).thenReturn("Issues");

dbComponentsRefCache = new DbComponentsRefCache();
step = new PersistProjectLinksStep(dbClient, i18n, dbComponentsRefCache, reportReader);
step = new PersistProjectLinksStep(dbClient, i18n, treeRootHolder, reportReader);
}

@Override
@@ -88,16 +90,10 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void add_links_on_project_and_module() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "MODULE_KEY", "BCDE"));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
new DumbComponent(Component.Type.MODULE, 2, "BCDE", null)));

// project and 1 module
reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.setAnalysisDate(150000000L)
.build());

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
@@ -123,12 +119,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void nothing_to_do_when_link_already_exists() throws Exception {
dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
@@ -145,15 +136,16 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void do_not_add_links_on_file() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
new DumbComponent(Component.Type.FILE, 2, "BCDE", null)));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.addChildRef(2)
.build());
reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.FILE)
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.build());
@@ -167,12 +159,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void update_link() throws Exception {
dbTester.prepareDbUnit(getClass(), "update_link.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
@@ -189,12 +176,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void delete_link() throws Exception {
dbTester.prepareDbUnit(getClass(), "delete_link.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
@@ -210,12 +192,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void not_delete_custom_link() throws Exception {
dbTester.prepareDbUnit(getClass(), "not_delete_custom_link.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)
@@ -231,12 +208,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
public void fail_when_trying_to_add_same_link_type_multiple_times() throws Exception {
dbTester.prepareDbUnit(getClass(), "empty.xml");

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)
.build());
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));

reportReader.putComponent(BatchReport.Component.newBuilder()
.setRef(1)

+ 7
- 14
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java View File

@@ -40,8 +40,6 @@ import org.sonar.core.source.db.FileSourceDto;
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.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
@@ -53,6 +51,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class PersistTestsStepTest extends BaseStepTest {

private static final String PROJECT_UUID = "PROJECT";
private static final String PROJECT_KEY = "PROJECT_KEY";
private static final int TEST_FILE_REF_1 = 3;
@@ -68,16 +67,18 @@ public class PersistTestsStepTest extends BaseStepTest {

@ClassRule
public static DbTester db = new DbTester();

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public LogTester log = new LogTester();

DbSession session;
DbClient dbClient;
DbComponentsRefCache dbComponentsRefCache;
Component root;

PersistTestsStep sut;
@@ -93,8 +94,7 @@ public class PersistTestsStepTest extends BaseStepTest {
System2 system2 = mock(System2.class);
when(system2.now()).thenReturn(now);

dbComponentsRefCache = new DbComponentsRefCache();
sut = new PersistTestsStep(dbClient, system2, dbComponentsRefCache, reportReader, treeRootHolder);
sut = new PersistTestsStep(dbClient, system2, reportReader, treeRootHolder);

initBasicReport();

@@ -218,8 +218,8 @@ public class PersistTestsStepTest extends BaseStepTest {
public void aggregate_coverage_details() {
reportReader.putTests(TEST_FILE_REF_1, Arrays.asList(newTest(1)));
reportReader.putCoverageDetails(TEST_FILE_REF_1, Arrays.asList(
newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3),
newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4)));
newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3),
newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4)));

sut.execute();

@@ -300,13 +300,6 @@ public class PersistTestsStepTest extends BaseStepTest {
}

private void initBasicReport() {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, "PROJECT_KEY", PROJECT_UUID));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "MODULE"));
dbComponentsRefCache.addComponent(3, new DbComponent(3L, "TEST_FILE1_KEY", TEST_FILE_UUID_1));
dbComponentsRefCache.addComponent(4, new DbComponent(4L, "TEST_FILE2_KEY", TEST_FILE_UUID_2));
dbComponentsRefCache.addComponent(5, new DbComponent(5L, "MAIN_FILE1_KEY", MAIN_FILE_UUID_1));
dbComponentsRefCache.addComponent(6, new DbComponent(6L, "MAIN_FILE2_KEY", MAIN_FILE_UUID_2));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey(PROJECT_KEY)

+ 13
- 4
server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java View File

@@ -32,7 +32,10 @@ import org.sonar.core.computation.dbcleaner.ProjectCleaner;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.purge.IdUuidPair;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DumbComponent;
import org.sonar.server.computation.component.ProjectSettingsRepository;
import org.sonar.server.db.DbClient;

@@ -49,11 +52,15 @@ public class PurgeDatastoresStepTest extends BaseStepTest {
@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

DbIdsRepository dbIdsRepository = new DbIdsRepository();

ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
ProjectSettingsRepository projectSettingsRepository = mock(ProjectSettingsRepository.class);

PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbComponentsRefCache, projectSettingsRepository, reportReader);
PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbIdsRepository, treeRootHolder, projectSettingsRepository);

@Before
public void setUp() throws Exception {
@@ -62,7 +69,9 @@ public class PurgeDatastoresStepTest extends BaseStepTest {

@Test
public void call_purge_method_of_the_purge_task() throws IOException {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(123L, PROJECT_KEY, "UUID-1234"));
Component project = new DumbComponent(Component.Type.PROJECT, 1, "UUID-1234", PROJECT_KEY);
treeRootHolder.setRoot(project);
dbIdsRepository.setComponentId(project, 123L);

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)

+ 10
- 5
server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java View File

@@ -32,7 +32,9 @@ import org.sonar.api.utils.System2;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.server.computation.batch.BatchReportReaderRule;
import org.sonar.server.computation.component.DbComponentsRefCache;
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.computation.issue.IssueCache;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.issue.notification.IssueChangeNotification;
@@ -54,6 +56,10 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {

@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@@ -64,11 +70,10 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {
@Before
public void setUp() throws Exception {
issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
NewIssuesNotificationFactory newIssuesNotificationFactory = mock(NewIssuesNotificationFactory.class, Mockito.RETURNS_DEEP_STUBS);
sut = new SendIssueNotificationsStep(issueCache, mock(RuleCache.class), dbComponentsRefCache, notifService, reportReader, newIssuesNotificationFactory);
sut = new SendIssueNotificationsStep(issueCache, mock(RuleCache.class), treeRootHolder, notifService, reportReader, newIssuesNotificationFactory);

dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY));

reportReader.setMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
@@ -93,7 +98,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {
@Test
public void send_notifications_if_subscribers() {
issueCache.newAppender().append(new DefaultIssue()
.setSeverity(Severity.BLOCKER)).close();
.setSeverity(Severity.BLOCKER)).close();

when(notifService.hasProjectSubscribersForTypes(PROJECT_UUID, SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);


Loading…
Cancel
Save