Browse Source

SONAR-6259 Use component caches to get id or uuid

tags/5.2-RC1
Julien Lancelot 9 years ago
parent
commit
db30e4ece3
50 changed files with 4071 additions and 5942 deletions
  1. 10
    4
      server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java
  2. 3
    3
      server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
  3. 6
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java
  4. 0
    55
      server/sonar-server/src/main/java/org/sonar/server/computation/component/Component.java
  5. 68
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/component/ComputeComponentsRefCache.java
  6. 76
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java
  7. 6
    5
      server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java
  8. 0
    56
      server/sonar-server/src/main/java/org/sonar/server/computation/step/ComponentUuidsCache.java
  9. 0
    44
      server/sonar-server/src/main/java/org/sonar/server/computation/step/ComponentsCache.java
  10. 3
    0
      server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
  11. 20
    23
      server/sonar-server/src/main/java/org/sonar/server/computation/step/FeedComponentsCacheStep.java
  12. 5
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java
  13. 5
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java
  14. 5
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java
  15. 9
    3
      server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java
  16. 17
    17
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java
  17. 19
    24
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
  18. 6
    3
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java
  19. 14
    7
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java
  20. 5
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
  21. 6
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java
  22. 7
    3
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java
  23. 14
    10
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
  24. 6
    2
      server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java
  25. 2
    2
      server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
  26. 4
    2
      server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java
  27. 0
    60
      server/sonar-server/src/test/java/org/sonar/server/computation/step/ComponentUuidsCacheTest.java
  28. 7
    5
      server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java
  29. 220
    0
      server/sonar-server/src/test/java/org/sonar/server/computation/step/FeedComponentsCacheStepTest.java
  30. 27
    4
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java
  31. 22
    3
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java
  32. 22
    3
      server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java
  33. 12
    8
      server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java
  34. 56
    104
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java
  35. 24
    51
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java
  36. 17
    7
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java
  37. 12
    6
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java
  38. 154
    70
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
  39. 9
    3
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java
  40. 20
    15
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java
  41. 18
    9
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java
  42. 28
    8
      server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
  43. 3079
    5287
      sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java
  44. 7
    9
      sonar-batch-protocol/src/main/protobuf/batch_report.proto
  45. 0
    2
      sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/output/BatchReportWriterTest.java
  46. 2
    5
      sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java
  47. 1
    2
      sonar-core/src/main/java/org/sonar/core/component/ComponentDto.java
  48. 1
    1
      sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
  49. 3
    3
      sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
  50. 14
    4
      sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java

+ 10
- 4
server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java View File

@@ -35,6 +35,8 @@ import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.computation.step.PersistFileSourcesStep;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
@@ -54,6 +56,8 @@ 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 TemporaryFolder temp = new TemporaryFolder();

@@ -75,7 +79,7 @@ public class PersistFileSourcesStepTest {

long start = System.currentTimeMillis();

PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE);
PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, dbComponentsRefCache);
step.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto(PROJECT_UUID)));

long end = System.currentTimeMillis();
@@ -97,8 +101,9 @@ public class PersistFileSourcesStepTest {
.build());
BatchReport.Component.Builder project = BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid(PROJECT_UUID);
.setType(Constants.ComponentType.PROJECT);

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

for (int fileRef = 2; fileRef <= NUMBER_OF_FILES + 1; fileRef++) {
generateFileReport(writer, fileRef);
@@ -118,10 +123,11 @@ public class PersistFileSourcesStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(fileRef)
.setType(Constants.ComponentType.FILE)
.setUuid(Uuids.create())
.setLines(NUMBER_OF_LINES)
.build());

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

FileUtils.writeLines(writer.getSourceFile(fileRef), lineData.lines);
writer.writeComponentCoverage(fileRef, lineData.coverages);
writer.writeComponentChangesets(lineData.changesetsBuilder.setComponentRef(fileRef).build());

+ 3
- 3
server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java View File

@@ -23,9 +23,9 @@ package org.sonar.server.component.db;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import org.apache.ibatis.session.RowBounds;
import org.sonar.api.server.ServerSide;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.server.ServerSide;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.FilePathWithHashDto;
import org.sonar.core.component.UuidWithProjectUuidDto;
@@ -136,8 +136,8 @@ public class ComponentDao implements DaoComponent {
});
}

public List<ComponentDto> selectComponentsFromProjectUuid(DbSession session, String projectKey) {
return mapper(session).selectComponentsFromProjectUuid(projectKey);
public List<ComponentDto> selectComponentsFromProjectKey(DbSession session, String projectKey) {
return mapper(session).selectComponentsFromProjectKey(projectKey);
}

public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) {

+ 6
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java View File

@@ -21,6 +21,8 @@ package org.sonar.server.computation;

import org.sonar.core.issue.db.UpdateConflictResolver;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.issue.IssueCache;
import org.sonar.server.computation.issue.IssueComputation;
import org.sonar.server.computation.issue.RuleCache;
@@ -47,6 +49,10 @@ public class ComputationContainer {
ComputationService.class,
ComputationSteps.class,

// component caches
ComputeComponentsRefCache.class,
DbComponentsRefCache.class,

// issues
ScmAccountCacheLoader.class,
ScmAccountCache.class,

+ 0
- 55
server/sonar-server/src/main/java/org/sonar/server/computation/component/Component.java View File

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

public class Component {

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

public Long getId() {
return id;
}

public Component setId(Long id) {
this.id = id;
return this;
}

public String getKey() {
return key;
}

public Component setKey(String key) {
this.key = key;
return this;
}

public String getUuid() {
return uuid;
}

public Component setUuid(String uuid) {
this.uuid = uuid;
return this;
}
}

+ 68
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/component/ComputeComponentsRefCache.java View File

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

import java.util.HashMap;
import java.util.Map;

/**
* Cache of components (uuid and key) that can be used in compute steps (For instance for issue computation)
*/
public class ComputeComponentsRefCache {

private final Map<Integer, ComputeComponent> componentsByRef;

public ComputeComponentsRefCache() {
componentsByRef = new HashMap<>();
}

public ComputeComponentsRefCache addComponent(Integer ref, ComputeComponent computeComponent) {
componentsByRef.put(ref, computeComponent);
return this;
}

public ComputeComponent getByRef(Integer ref) {
ComputeComponent computeComponent = componentsByRef.get(ref);
if (computeComponent == null) {
throw new IllegalArgumentException(String.format("Component ref '%s' does not exists", ref));
}
return componentsByRef.get(ref);
}

public static class ComputeComponent {
private String uuid;
private String key;

public ComputeComponent(String key, String uuid) {
this.key = key;
this.uuid = uuid;
}

public String getKey() {
return key;
}

public String getUuid() {
return uuid;
}

}
}

+ 76
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java View File

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

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
*/
public class DbComponentsRefCache {

private final Map<Integer, DbComponent> componentsByRef;

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

public DbComponentsRefCache addComponent(Integer ref, DbComponent component) {
componentsByRef.put(ref, component);
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));
}
return componentsByRef.get(ref);
}

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;
}

}
}

+ 6
- 5
server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java View File

@@ -61,11 +61,12 @@ public class IssueComputation {
this.diskIssuesAppender = issueCache.newAppender();
}

public void processComponentIssues(ComputationContext context, Iterable<BatchReport.Issue> issues, String componentUuid, @Nullable Integer componentReportRef) {
public void processComponentIssues(ComputationContext context, Iterable<BatchReport.Issue> issues, String componentUuid, @Nullable Integer componentReportRef,
String projectKey, String projectUuid) {
linesCache.init(componentUuid, componentReportRef, context.getReportReader());
computeDefaultAssignee(context.getProjectSettings().getString(CoreProperties.DEFAULT_ISSUE_ASSIGNEE));
for (BatchReport.Issue reportIssue : issues) {
DefaultIssue issue = toDefaultIssue(context, componentUuid, reportIssue);
DefaultIssue issue = toDefaultIssue(context, componentUuid, reportIssue, projectKey, projectUuid);
if (issue.isNew()) {
guessAuthor(issue);
autoAssign(issue, defaultAssignee);
@@ -76,7 +77,7 @@ public class IssueComputation {
linesCache.clear();
}

private DefaultIssue toDefaultIssue(ComputationContext context, String componentUuid, BatchReport.Issue issue) {
private DefaultIssue toDefaultIssue(ComputationContext context, String componentUuid, BatchReport.Issue issue, String projectKey, String projectUuid) {
DefaultIssue target = new DefaultIssue();
target.setKey(issue.getUuid());
target.setComponentUuid(componentUuid);
@@ -85,8 +86,8 @@ public class IssueComputation {
target.setManualSeverity(issue.getManualSeverity());
target.setMessage(issue.hasMsg() ? issue.getMsg() : null);
target.setLine(issue.hasLine() ? issue.getLine() : null);
target.setProjectUuid(context.getProject().uuid());
target.setProjectKey(context.getProject().key());
target.setProjectUuid(projectUuid);
target.setProjectKey(projectKey);
target.setEffortToFix(issue.hasEffortToFix() ? issue.getEffortToFix() : null);
target.setDebt(issue.hasDebtInMinutes() ? Duration.create(issue.getDebtInMinutes()) : null);
if (issue.hasDiffFields()) {

+ 0
- 56
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComponentUuidsCache.java View File

@@ -1,56 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.computation.step;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import org.sonar.batch.protocol.output.BatchReportReader;

import java.util.concurrent.ExecutionException;

/**
* Waiting for having all components persisted by the Compute Engine, this class contains a cache of component uuids by their report reference
*/
public class ComponentUuidsCache {

private final Cache<Integer, String> componentRefToUuidCache;

public ComponentUuidsCache(final BatchReportReader reader) {
this.componentRefToUuidCache = CacheBuilder.newBuilder()
.maximumSize(500_000)
.build(
new CacheLoader<Integer, String>() {
@Override
public String load(Integer ref) {
return reader.readComponent(ref).getUuid();
}
});
}

public String getUuidFromRef(int componentRef) {
try {
return componentRefToUuidCache.get(componentRef);
} catch (ExecutionException e) {
throw new IllegalStateException(String.format("Error while retrieving uuid of component ref '%d'", componentRef), e);
}
}
}

+ 0
- 44
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComponentsCache.java View File

@@ -1,44 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.computation.step;

import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.server.computation.component.Component;

import java.util.HashMap;
import java.util.Map;

/**
* To be finished
*/
public class ComponentsCache {

private final Map<Integer, Component> componentsByRef;

public ComponentsCache(final BatchReportReader reader) {
this.componentsByRef = new HashMap<>();
}

public Component getComponent(int componentRef) {
// TODO should we return null or fail on unknown component ?
return null;
}
}

+ 3
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java View File

@@ -37,10 +37,13 @@ public class ComputationSteps {
*/
public static List<Class<? extends ComputationStep>> orderedStepClasses() {
return Arrays.asList(
FeedComponentsCacheStep.class,

// Read report
ParseReportStep.class,

// Persist data
PersistComponentsStep.class,
PersistNumberOfDaysSinceLastCommitStep.class,
PersistMeasuresStep.class,
PersistIssuesStep.class,

+ 20
- 23
server/sonar-server/src/main/java/org/sonar/server/computation/step/FeedComponentsCacheStep.java View File

@@ -21,7 +21,6 @@
package org.sonar.server.computation.step;

import com.google.common.collect.Maps;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.internal.Uuids;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
@@ -31,67 +30,65 @@ import org.sonar.core.component.ComponentKeys;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.util.NonNullInputFunction;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.db.DbClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* To be finished
* Read all components from the batch report and feed the cache containing component uuid and key
*/
public class FeedComponentsCacheStep implements ComputationStep {

private final DbClient dbClient;
private final ComputeComponentsRefCache computeComponentsRefCache;

public FeedComponentsCacheStep(DbClient dbClient) {
public FeedComponentsCacheStep(DbClient dbClient, ComputeComponentsRefCache computeComponentsRefCache) {
this.dbClient = dbClient;
}

@Override
public String[] supportedProjectQualifiers() {
return new String[] {Qualifiers.PROJECT};
this.computeComponentsRefCache = computeComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
DbSession session = dbClient.openSession(false);
try {
List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectUuid(session, context.getProject().uuid());
List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, context.getProject().key());
Map<String, ComponentDto> componentDtosByKey = componentDtosByKey(components);
Map<Integer, Component> componentsByRef = new HashMap<>();
int rootComponentRef = context.getReportMetadata().getRootComponentRef();
recursivelyProcessComponent(context, rootComponentRef, context.getReportReader().readComponent(rootComponentRef), componentDtosByKey, componentsByRef);
recursivelyProcessComponent(context, rootComponentRef, context.getReportReader().readComponent(rootComponentRef), componentDtosByKey);
} finally {
session.close();
}
}

private void recursivelyProcessComponent(ComputationContext context, int componentRef, BatchReport.Component nearestModule,
Map<String, ComponentDto> componentDtosByKey, Map<Integer, Component> componentsByRef) {
private void recursivelyProcessComponent(ComputationContext context, int componentRef, BatchReport.Component nearestModule, Map<String, ComponentDto> componentDtosByKey) {
BatchReportReader reportReader = context.getReportReader();
BatchReport.Component reportComponent = reportReader.readComponent(componentRef);
String componentKey = ComponentKeys.createKey(nearestModule.getKey(), reportComponent.getPath(), context.getReportMetadata().getBranch());

Component component = new Component().setKey(componentKey);
String path = reportComponent.hasPath() ? reportComponent.getPath() : null;
String branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null;
String componentKey = reportComponent.hasKey() ?
ComponentKeys.createKey(reportComponent.getKey(), branch) :
ComponentKeys.createKey(nearestModule.getKey(), path, branch);

ComponentDto componentDto = componentDtosByKey.get(componentKey);
if (componentDto == null) {
component.setUuid(Uuids.create());
computeComponentsRefCache.addComponent(componentRef, new ComputeComponentsRefCache.ComputeComponent(componentKey, Uuids.create()));
} else {
component.setId(component.getId());
component.setKey(componentKey);
computeComponentsRefCache.addComponent(componentRef, new ComputeComponentsRefCache.ComputeComponent(componentKey, componentDto.uuid()));
}

for (Integer childRef : reportComponent.getChildRefList()) {
// If current component is not a module or a project, we need to keep the parent reference to the nearest module
BatchReport.Component nextNearestModule = !reportComponent.getType().equals(Constants.ComponentType.PROJECT) && !reportComponent.getType().equals(Constants.ComponentType.MODULE) ?
BatchReport.Component nextModuleParent = !reportComponent.getType().equals(Constants.ComponentType.PROJECT)
&& !reportComponent.getType().equals(Constants.ComponentType.MODULE) ?
nearestModule : reportComponent;
recursivelyProcessComponent(context, childRef, nextNearestModule, componentDtosByKey, componentsByRef);
recursivelyProcessComponent(context, childRef, nextModuleParent, componentDtosByKey);
}
}

private Map<String, ComponentDto> componentDtosByKey(List<ComponentDto> components){
private Map<String, ComponentDto> componentDtosByKey(List<ComponentDto> components) {
return Maps.uniqueIndex(components, new NonNullInputFunction<ComponentDto, String>() {
@Override
public String doApply(ComponentDto input) {

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

@@ -22,20 +22,23 @@ package org.sonar.server.computation.step;

import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;

/**
* 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;

public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao) {
public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao, DbComponentsRefCache dbComponentsRefCache) {
this.resourceIndexerDao = resourceIndexerDao;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
resourceIndexerDao.indexProject(context.getProject().getId());
resourceIndexerDao.indexProject(dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getId());
}

@Override

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

@@ -20,19 +20,22 @@
package org.sonar.server.computation.step;

import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.source.index.SourceLineIndexer;

public class IndexSourceLinesStep implements ComputationStep {

private final SourceLineIndexer indexer;
private final DbComponentsRefCache dbComponentsRefCache;

public IndexSourceLinesStep(SourceLineIndexer indexer) {
public IndexSourceLinesStep(SourceLineIndexer indexer, DbComponentsRefCache dbComponentsRefCache) {
this.indexer = indexer;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
indexer.index(context.getProject().uuid());
indexer.index(dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getUuid());
}

@Override

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

@@ -21,19 +21,22 @@
package org.sonar.server.computation.step;

import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.test.index.TestIndexer;

public class IndexTestsStep implements ComputationStep {

private final TestIndexer indexer;
private final DbComponentsRefCache dbComponentsRefCache;

public IndexTestsStep(TestIndexer indexer) {
public IndexTestsStep(TestIndexer indexer, DbComponentsRefCache dbComponentsRefCache) {
this.indexer = indexer;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
indexer.index(context.getProject().uuid());
indexer.index(dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getUuid());
}

@Override

+ 9
- 3
server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java View File

@@ -23,6 +23,7 @@ package org.sonar.server.computation.step;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.computation.issue.IssueComputation;

import java.util.List;
@@ -30,9 +31,11 @@ import java.util.List;
public class ParseReportStep implements ComputationStep {

private final IssueComputation issueComputation;
private final ComputeComponentsRefCache computeComponentsRefCache;

public ParseReportStep(IssueComputation issueComputation) {
public ParseReportStep(IssueComputation issueComputation, ComputeComponentsRefCache computeComponentsRefCache) {
this.issueComputation = issueComputation;
this.computeComponentsRefCache = computeComponentsRefCache;
}

@Override
@@ -47,7 +50,9 @@ public class ParseReportStep implements ComputationStep {
BatchReportReader reportReader = context.getReportReader();
BatchReport.Component component = reportReader.readComponent(componentRef);
List<BatchReport.Issue> issues = reportReader.readComponentIssues(componentRef);
issueComputation.processComponentIssues(context, issues, component.getUuid(), componentRef);
ComputeComponentsRefCache.ComputeComponent computeProject = computeComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef());
issueComputation.processComponentIssues(context, issues, computeComponentsRefCache.getByRef(componentRef).getUuid(), componentRef, computeProject.getKey(),
computeProject.getUuid());
for (Integer childRef : component.getChildRefList()) {
recursivelyProcessComponent(context, childRef);
}
@@ -55,9 +60,10 @@ public class ParseReportStep implements ComputationStep {

private void processDeletedComponents(ComputationContext context) {
int deletedComponentsCount = context.getReportMetadata().getDeletedComponentsCount();
ComputeComponentsRefCache.ComputeComponent computeProject = computeComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef());
for (int componentRef = 1; componentRef <= deletedComponentsCount; componentRef++) {
BatchReport.Issues issues = context.getReportReader().readDeletedComponentIssues(componentRef);
issueComputation.processComponentIssues(context, issues.getIssueList(), issues.getComponentUuid(), null);
issueComputation.processComponentIssues(context, issues.getIssueList(), issues.getComponentUuid(), null, computeProject.getKey(), computeProject.getUuid());
}
}


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

@@ -26,15 +26,15 @@ import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.internal.Uuids;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.util.NonNullInputFunction;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

import javax.annotation.Nullable;
@@ -45,21 +45,20 @@ import java.util.Map;
public class PersistComponentsStep implements ComputationStep {

private final DbClient dbClient;
private final ComputeComponentsRefCache computeComponentsRefCache;
private final DbComponentsRefCache dbComponentsRefCache;

public PersistComponentsStep(DbClient dbClient) {
public PersistComponentsStep(DbClient dbClient, ComputeComponentsRefCache computeComponentsRefCache, DbComponentsRefCache dbComponentsRefCache) {
this.dbClient = dbClient;
}

@Override
public String[] supportedProjectQualifiers() {
return new String[] {Qualifiers.PROJECT};
this.computeComponentsRefCache = computeComponentsRefCache;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
DbSession session = dbClient.openSession(false);
try {
List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectUuid(session, context.getProject().uuid());
List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, context.getProject().key());
Map<String, ComponentDto> componentDtosByKey = componentDtosByKey(components);
int rootComponentRef = context.getReportMetadata().getRootComponentRef();
ComponentContext componentContext = new ComponentContext(context, session, componentDtosByKey);
@@ -74,6 +73,7 @@ public class PersistComponentsStep implements ComputationStep {
BatchReportReader reportReader = componentContext.context.getReportReader();
BatchReport.Component reportComponent = reportReader.readComponent(componentRef);
ComponentDto componentDto = processComponent(componentContext, reportComponent, moduleParent);
dbComponentsRefCache.addComponent(componentRef, new DbComponentsRefCache.DbComponent(componentDto.getId(), componentDto.getKey(), componentDto.uuid()));

for (Integer childRef : reportComponent.getChildRefList()) {
// If current component is not a module or a project, we need to keep the parent reference to the nearest module
@@ -84,14 +84,12 @@ public class PersistComponentsStep implements ComputationStep {
}

private ComponentDto processComponent(ComponentContext componentContext, BatchReport.Component reportComponent, @Nullable ComponentDto moduleParent) {
String path = reportComponent.hasPath() ? reportComponent.getPath() : null;
String branch = componentContext.context.getReportMetadata().hasBranch() ? componentContext.context.getReportMetadata().getBranch() : null;
String componentKey = reportComponent.hasKey() || moduleParent == null ?
ComponentKeys.createKey(reportComponent.getKey(), branch) :
ComponentKeys.createEffectiveKey(moduleParent.getKey(), path);
ComputeComponentsRefCache.ComputeComponent cacheComputeComponent = computeComponentsRefCache.getByRef(reportComponent.getRef());
String componentKey = cacheComputeComponent.getKey();
String componentUuid = cacheComputeComponent.getUuid();
ComponentDto existingComponent = componentContext.componentDtosByKey.get(componentKey);
if (existingComponent == null) {
ComponentDto component = createComponent(reportComponent, componentKey, Uuids.create(), moduleParent);
ComponentDto component = createComponent(reportComponent, componentKey, componentUuid, moduleParent);
dbClient.componentDao().insert(componentContext.dbSession, component);
return component;
} else {
@@ -184,8 +182,9 @@ public class PersistComponentsStep implements ComputationStep {
return Scopes.DIRECTORY;
case FILE:
return Scopes.FILE;
default :
throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
}
throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
}

private static String getQualifier(BatchReport.Component reportComponent) {
@@ -198,8 +197,9 @@ public class PersistComponentsStep implements ComputationStep {
return Qualifiers.DIRECTORY;
case FILE:
return !reportComponent.getIsTest() ? Qualifiers.FILE : Qualifiers.UNIT_TEST_FILE;
default :
throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
}
throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
}

private static String getFileName(BatchReport.Component reportComponent) {

+ 19
- 24
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java View File

@@ -22,16 +22,15 @@ package org.sonar.server.computation.step;

import org.apache.commons.lang.StringEscapeUtils;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Range;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.measure.db.MetricDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

import java.util.List;
@@ -42,9 +41,11 @@ import java.util.List;
public class PersistDuplicationsStep implements ComputationStep {

private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;

public PersistDuplicationsStep(DbClient dbClient) {
public PersistDuplicationsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache) {
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
@@ -54,52 +55,47 @@ public class PersistDuplicationsStep implements ComputationStep {
MetricDto duplicationMetric = dbClient.metricDao().selectByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
DuplicationContext duplicationContext = new DuplicationContext(context, duplicationMetric, session);
int rootComponentRef = context.getReportMetadata().getRootComponentRef();
recursivelyProcessComponent(duplicationContext, rootComponentRef, rootComponentRef);
recursivelyProcessComponent(duplicationContext, rootComponentRef);
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
}

private void recursivelyProcessComponent(DuplicationContext duplicationContext, int parentModuleRef, int componentRef) {
private void recursivelyProcessComponent(DuplicationContext duplicationContext, int componentRef) {
BatchReportReader reportReader = duplicationContext.context().getReportReader();
BatchReport.Component component = reportReader.readComponent(componentRef);
List<BatchReport.Duplication> duplications = reportReader.readComponentDuplications(componentRef);
if (!duplications.isEmpty()) {
saveDuplications(duplicationContext, reportReader.readComponent(parentModuleRef), component, duplications);
saveDuplications(duplicationContext, component, duplications);
}

for (Integer childRef : component.getChildRefList()) {
// If current component is a folder, we need to keep the parent reference to module parent
int nextParent = !component.getType().equals(Constants.ComponentType.PROJECT) && !component.getType().equals(Constants.ComponentType.MODULE) ?
parentModuleRef : componentRef;
recursivelyProcessComponent(duplicationContext, nextParent, childRef);
recursivelyProcessComponent(duplicationContext, childRef);
}
}

private void saveDuplications(DuplicationContext duplicationContext, BatchReport.Component parentComponent, BatchReport.Component component,
List<BatchReport.Duplication> duplications) {
private void saveDuplications(DuplicationContext duplicationContext, BatchReport.Component component, List<BatchReport.Duplication> duplications) {

String duplicationXml = createXmlDuplications(duplicationContext, parentComponent, component.getPath(), duplications);
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(component.getId())
.setComponentId(dbComponent.getId())
.setSnapshotId(component.getSnapshotId());
dbClient.measureDao().insert(duplicationContext.session(), measureDto);
}

private String createXmlDuplications(DuplicationContext duplicationContext, BatchReport.Component parentComponent, String componentPath,
Iterable<BatchReport.Duplication> duplications) {
private String createXmlDuplications(DuplicationContext duplicationContext, String componentKey, Iterable<BatchReport.Duplication> duplications) {

StringBuilder xml = new StringBuilder();
xml.append("<duplications>");
for (BatchReport.Duplication duplication : duplications) {
xml.append("<g>");
appendDuplication(xml, ComponentKeys.createKey(parentComponent.getKey(), componentPath, duplicationContext.context().getReportMetadata().getBranch()),
duplication.getOriginPosition());
appendDuplication(xml, componentKey, duplication.getOriginPosition());
for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) {
processDuplicationBlock(duplicationContext, xml, duplicationBlock, parentComponent.getKey(), componentPath);
processDuplicationBlock(duplicationContext, xml, duplicationBlock, componentKey);
}
xml.append("</g>");
}
@@ -107,22 +103,21 @@ public class PersistDuplicationsStep implements ComputationStep {
return xml.toString();
}

private void processDuplicationBlock(DuplicationContext duplicationContext, StringBuilder xml, BatchReport.Duplicate duplicate, String parentComponentKey,
String componentPath) {
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 {
String branch = duplicationContext.context().getReportMetadata().getBranch();
if (duplicate.hasOtherFileRef()) {
// Duplication is on a different file
BatchReport.Component duplicationComponent = duplicationContext.context().getReportReader().readComponent(duplicate.getOtherFileRef());
appendDuplication(xml, ComponentKeys.createKey(parentComponentKey, duplicationComponent.getPath(), branch), duplicate);
DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(duplicationComponent.getRef());
appendDuplication(xml, dbComponent.getKey(), duplicate);
} else {
// Duplication is on a the same file
appendDuplication(xml, ComponentKeys.createKey(parentComponentKey, componentPath, branch), duplicate);
appendDuplication(xml, componentKey, duplicate);
}
}
}

+ 6
- 3
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java View File

@@ -28,6 +28,7 @@ import org.sonar.core.event.EventDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

import java.util.List;
@@ -36,10 +37,12 @@ public class PersistEventsStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system2;
private final DbComponentsRefCache dbComponentsRefCache;

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

@Override
@@ -90,7 +93,7 @@ public class PersistEventsStep implements ComputationStep {
}

private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component) {
for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) {
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());
}
@@ -99,7 +102,7 @@ public class PersistEventsStep implements ComputationStep {

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

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

@@ -36,6 +36,7 @@ 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.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.source.ComputeFileSourceData;
import org.sonar.server.computation.source.CoverageLineReader;
import org.sonar.server.computation.source.DuplicationLineReader;
@@ -59,10 +60,12 @@ public class PersistFileSourcesStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system2;
private final DbComponentsRefCache dbComponentsRefCache;

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

@Override
@@ -72,7 +75,8 @@ public class PersistFileSourcesStep implements ComputationStep {
DbSession session = dbClient.openSession(false);
try {
final Map<String, FileSourceDto> previousFileSourcesByUuid = new HashMap<>();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject", ImmutableMap.of("projectUuid", context.getProject().uuid(), "dataType", Type.SOURCE),
String projectUuid = dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getUuid();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject", ImmutableMap.of("projectUuid", projectUuid, "dataType", Type.SOURCE),
new ResultHandler() {
@Override
public void handleResult(ResultContext context) {
@@ -81,7 +85,7 @@ public class PersistFileSourcesStep implements ComputationStep {
}
});

recursivelyProcessComponent(new FileSourcesContext(session, context, previousFileSourcesByUuid), rootComponentRef);
recursivelyProcessComponent(new FileSourcesContext(session, context, previousFileSourcesByUuid, projectUuid), rootComponentRef);
} finally {
MyBatis.closeQuietly(session);
}
@@ -125,12 +129,13 @@ public class PersistFileSourcesStep implements ComputationStep {
String dataHash = DigestUtils.md5Hex(data);
String srcHash = fileSourceData.getSrcHash();
String lineHashes = fileSourceData.getLineHashes();
FileSourceDto previousDto = fileSourcesContext.previousFileSourcesByUuid.get(component.getUuid());
String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
FileSourceDto previousDto = fileSourcesContext.previousFileSourcesByUuid.get(componentUuid);

if (previousDto == null) {
FileSourceDto dto = new FileSourceDto()
.setProjectUuid(fileSourcesContext.context.getProject().uuid())
.setFileUuid(component.getUuid())
.setProjectUuid(fileSourcesContext.projectUuid)
.setFileUuid(componentUuid)
.setDataType(Type.SOURCE)
.setBinaryData(data)
.setSrcHash(srcHash)
@@ -164,11 +169,13 @@ public class PersistFileSourcesStep implements ComputationStep {
DbSession session;
ComputationContext context;
Map<String, FileSourceDto> previousFileSourcesByUuid;
String projectUuid;

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


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

@@ -28,6 +28,7 @@ import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
@@ -48,11 +49,13 @@ public class PersistMeasuresStep implements ComputationStep {
private final DbClient dbClient;
private final RuleCache ruleCache;
private final MetricCache metricCache;
private final DbComponentsRefCache dbComponentsRefCache;

public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache) {
public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache, DbComponentsRefCache dbComponentsRefCache) {
this.dbClient = dbClient;
this.ruleCache = ruleCache;
this.metricCache = metricCache;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
@@ -107,7 +110,7 @@ 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(component.getId());
out.setComponentId(dbComponentsRefCache.getByRef(component.getRef()).getId());
out.setSnapshotId(component.getSnapshotId());
out.setMetricId(metricCache.get(in.getMetricKey()).getId());
out.setRuleId(in.hasRuleKey() ? ruleCache.get(RuleKey.parse(in.getRuleKey())).getId() : null);

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

@@ -28,6 +28,7 @@ import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.index.SourceLineIndex;
@@ -48,14 +49,17 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
private final SourceLineIndex sourceLineIndex;
private final MetricCache metricCache;
private final System2 system;
private final DbComponentsRefCache dbComponentsRefCache;

private long lastCommitTimestamp = 0L;

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

@Override
@@ -69,7 +73,7 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
recursivelyProcessComponent(context, rootComponentRef);

if (!commitFound()) {
Long lastCommitFromIndex = lastCommitFromIndex(context.getProject().uuid());
Long lastCommitFromIndex = lastCommitFromIndex(dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getUuid());
lastCommitTimestamp = firstNonNull(lastCommitFromIndex, lastCommitTimestamp);
}


+ 7
- 3
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java View File

@@ -31,6 +31,7 @@ import org.sonar.core.component.ComponentLinkDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

import javax.annotation.Nullable;
@@ -49,6 +50,7 @@ public class PersistProjectLinksStep implements ComputationStep {

private final DbClient dbClient;
private final I18n i18n;
private final DbComponentsRefCache dbComponentsRefCache;

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

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

@Override
@@ -88,8 +91,9 @@ public class PersistProjectLinksStep implements ComputationStep {
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();
List<ComponentLinkDto> previousLinks = dbClient.componentLinkDao().selectByComponentUuid(session, component.getUuid());
mergeLinks(session, component.getUuid(), links, previousLinks);
String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
List<ComponentLinkDto> previousLinks = dbClient.componentLinkDao().selectByComponentUuid(session, componentUuid);
mergeLinks(session, componentUuid, links, previousLinks);
}
}


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

@@ -39,6 +39,7 @@ 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.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.source.ReportIterator;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDb;
@@ -59,10 +60,12 @@ public class PersistTestsStep implements ComputationStep {

private final DbClient dbClient;
private final System2 system;
private final DbComponentsRefCache dbComponentsRefCache;

public PersistTestsStep(DbClient dbClient, System2 system) {
public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache) {
this.dbClient = dbClient;
this.system = system;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
@@ -70,7 +73,7 @@ public class PersistTestsStep implements ComputationStep {
DbSession session = dbClient.openSession(true);
try {
int rootComponentRef = computationContext.getReportMetadata().getRootComponentRef();
TestContext context = new TestContext(computationContext, session);
TestContext context = new TestContext(computationContext, session, dbComponentsRefCache);

recursivelyProcessComponent(context, rootComponentRef);
session.commit();
@@ -106,7 +109,8 @@ public class PersistTestsStep implements ComputationStep {
return;
}

FileSourceDto existingDto = context.existingFileSourcesByUuid.get(component.getUuid());
String componentUuid = context.getUuid(component.getRef());
FileSourceDto existingDto = context.existingFileSourcesByUuid.get(componentUuid);
long now = system.now();
if (existingDto != null) {
// update
@@ -118,8 +122,8 @@ public class PersistTestsStep implements ComputationStep {
// insert
FileSourceDto newDto = new FileSourceDto()
.setTestData(tests)
.setFileUuid(component.getUuid())
.setProjectUuid(context.context.getProject().uuid())
.setFileUuid(componentUuid)
.setProjectUuid(context.getUuid(context.context.getReportMetadata().getRootComponentRef()))
.setDataType(Type.TEST)
.setCreatedAt(now)
.setUpdatedAt(now);
@@ -236,18 +240,18 @@ public class PersistTestsStep implements ComputationStep {
final DbSession session;
final ComputationContext context;
final BatchReportReader reader;
final ComponentUuidsCache componentRefToUuidCache;
final DbComponentsRefCache dbComponentsRefCache;
final Map<String, FileSourceDto> existingFileSourcesByUuid;
boolean hasUnprocessedCoverageDetails = false;

TestContext(ComputationContext context, DbSession session) {
TestContext(ComputationContext context, DbSession session, DbComponentsRefCache dbComponentsRefCache) {
this.session = session;
this.context = context;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reader = context.getReportReader();
this.componentRefToUuidCache = new ComponentUuidsCache(context.getReportReader());
this.existingFileSourcesByUuid = new HashMap<>();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject",
ImmutableMap.of("projectUuid", context.getProject().uuid(), "dataType", Type.TEST),
ImmutableMap.of("projectUuid", dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef()).getUuid(), "dataType", Type.TEST),
new ResultHandler() {
@Override
public void handleResult(ResultContext context) {
@@ -258,7 +262,7 @@ public class PersistTestsStep implements ComputationStep {
}

public String getUuid(int fileRef) {
return componentRefToUuidCache.getUuidFromRef(fileRef);
return dbComponentsRefCache.getByRef(fileRef).getUuid();
}
}
}

+ 6
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java View File

@@ -25,23 +25,27 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.purge.IdUuidPair;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

public class PurgeDatastoresStep implements ComputationStep {

private final ProjectCleaner projectCleaner;
private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;

public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner) {
public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbComponentsRefCache dbComponentsRefCache) {
this.projectCleaner = projectCleaner;
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
}

@Override
public void execute(ComputationContext context) {
DbSession session = dbClient.openSession(true);
try {
projectCleaner.purge(session, new IdUuidPair(context.getProject().getId(), context.getProject().uuid()), context.getProjectSettings());
DbComponentsRefCache.DbComponent project = dbComponentsRefCache.getByRef(context.getReportMetadata().getRootComponentRef());
projectCleaner.purge(session, new IdUuidPair(project.getId(), project.getUuid()), context.getProjectSettings());
session.commit();
} finally {
MyBatis.closeQuietly(session);

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java View File

@@ -457,10 +457,10 @@ public class ComponentDaoTest {
public void select_components_from_project() {
db.prepareDbUnit(getClass(), "multi-modules.xml");

List<ComponentDto> components = sut.selectComponentsFromProjectUuid(session, "ABCD");
List<ComponentDto> components = sut.selectComponentsFromProjectKey(session, "org.struts:struts");
assertThat(components).hasSize(5);

assertThat(sut.selectComponentsFromProjectUuid(session, "UNKNOWN")).isEmpty();
assertThat(sut.selectComponentsFromProjectKey(session, "UNKNOWN")).isEmpty();
}

@Test

+ 4
- 2
server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java View File

@@ -43,7 +43,9 @@ import java.io.IOException;
import java.util.Arrays;

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

public class IssueComputationTest {

@@ -214,6 +216,6 @@ public class IssueComputationTest {
}

private void process() {
sut.processComponentIssues(context, Arrays.asList(inputIssue.build()), "FILE_A", 1);
sut.processComponentIssues(context, Arrays.asList(inputIssue.build()), "FILE_A", 1, "PROJECT_KEY", "PROJECT_UUID");
}
}

+ 0
- 60
server/sonar-server/src/test/java/org/sonar/server/computation/step/ComponentUuidsCacheTest.java View File

@@ -1,60 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.computation.step;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;

import java.io.File;

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

public class ComponentUuidsCacheTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

File reportDir;

@Before
public void setUp() throws Exception {
reportDir = temp.newFolder();
}

@Test
public void get_uuid_from_ref() {
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.build());

ComponentUuidsCache cache = new ComponentUuidsCache(new BatchReportReader(reportDir));
assertThat(cache.getUuidFromRef(1)).isEqualTo("ABCD");
}
}

+ 7
- 5
server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java View File

@@ -48,12 +48,14 @@ public class ComputationStepsTest {
mock(PersistNumberOfDaysSinceLastCommitStep.class),
mock(PersistFileSourcesStep.class),
mock(PersistTestsStep.class),
mock(IndexTestsStep.class)
);
mock(IndexTestsStep.class),
mock(FeedComponentsCacheStep.class),
mock(PersistComponentsStep.class)
);

assertThat(registry.orderedSteps()).hasSize(17);
assertThat(registry.orderedSteps().get(0)).isInstanceOf(ParseReportStep.class);
assertThat(registry.orderedSteps().get(16)).isInstanceOf(SendIssueNotificationsStep.class);
assertThat(registry.orderedSteps()).hasSize(19);
assertThat(registry.orderedSteps().get(0)).isInstanceOf(FeedComponentsCacheStep.class);
assertThat(registry.orderedSteps().get(18)).isInstanceOf(SendIssueNotificationsStep.class);
}

@Test

+ 220
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/step/FeedComponentsCacheStepTest.java View File

@@ -0,0 +1,220 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.computation.step;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

import java.io.File;

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

@Category(DbTests.class)
public class FeedComponentsCacheStepTest extends BaseStepTest {

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

@Rule
public TemporaryFolder temp = new TemporaryFolder();

File reportDir;

DbSession session;

DbClient dbClient;

ComputeComponentsRefCache computeComponentsRefCache;

FeedComponentsCacheStep sut;

@Before
public void setup() throws Exception {
dbTester.truncateTables();
session = dbTester.myBatis().openSession(false);
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());

reportDir = temp.newFolder();

computeComponentsRefCache = new ComputeComponentsRefCache();
sut = new FeedComponentsCacheStep(dbClient, computeComponentsRefCache);
}

@Override
protected ComputationStep step() {
return sut;
}

@Test
public void add_components() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));

assertThat(computeComponentsRefCache.getByRef(1).getKey()).isEqualTo("PROJECT_KEY");
assertThat(computeComponentsRefCache.getByRef(1).getUuid()).isNotNull();

assertThat(computeComponentsRefCache.getByRef(2).getKey()).isEqualTo("MODULE_KEY");
assertThat(computeComponentsRefCache.getByRef(2).getUuid()).isNotNull();

assertThat(computeComponentsRefCache.getByRef(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
assertThat(computeComponentsRefCache.getByRef(3).getUuid()).isNotNull();

assertThat(computeComponentsRefCache.getByRef(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
assertThat(computeComponentsRefCache.getByRef(4).getUuid()).isNotNull();
}

@Test
public void use_latest_module_for_files_key() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setName("Project")
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.MODULE)
.setKey("SUB_MODULE_KEY")
.setName("Sub Module")
.addChildRef(4)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(5)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(5)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));

assertThat(computeComponentsRefCache.getByRef(4).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir");
assertThat(computeComponentsRefCache.getByRef(5).getKey()).isEqualTo("SUB_MODULE_KEY:src/main/java/dir/Foo.java");
}

@Test
public void use_branch_to_generate_keys() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setBranch("origin/master")
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setName("Project")
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));

assertThat(computeComponentsRefCache.getByRef(1).getKey()).isEqualTo("PROJECT_KEY:origin/master");
assertThat(computeComponentsRefCache.getByRef(2).getKey()).isEqualTo("MODULE_KEY:origin/master");
assertThat(computeComponentsRefCache.getByRef(3).getKey()).isEqualTo("MODULE_KEY:origin/master:src/main/java/dir");
assertThat(computeComponentsRefCache.getByRef(4).getKey()).isEqualTo("MODULE_KEY:origin/master:src/main/java/dir/Foo.java");
}


}

+ 27
- 4
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java View File

@@ -20,24 +20,47 @@

package org.sonar.server.computation.step;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;

import static org.mockito.Mockito.*;
import java.io.File;
import java.io.IOException;

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

public class IndexComponentsStepTest extends BaseStepTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

ResourceIndexerDao resourceIndexerDao = mock(ResourceIndexerDao.class);
IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao);
DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao, dbComponentsRefCache);

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

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

ComponentDto project = mock(ComponentDto.class);
when(project.getId()).thenReturn(123L);
ComputationContext context = new ComputationContext(mock(BatchReportReader.class), project);
ComputationContext context = new ComputationContext(new BatchReportReader(reportDir), project);

sut.execute(context);


+ 22
- 3
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java View File

@@ -22,12 +22,17 @@ package org.sonar.server.computation.step;
import org.elasticsearch.search.SearchHit;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.source.db.FileSourceDao;
@@ -36,14 +41,17 @@ import org.sonar.server.source.index.SourceLineDoc;
import org.sonar.server.source.index.SourceLineIndexDefinition;
import org.sonar.server.source.index.SourceLineIndexer;

import java.io.File;
import java.sql.Connection;
import java.util.List;

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

public class IndexSourceLinesStepTest extends BaseStepTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

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

@@ -52,26 +60,37 @@ public class IndexSourceLinesStepTest extends BaseStepTest {

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);
return new IndexSourceLinesStep(sourceLineIndexer, dbComponentsRefCache);
}

@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();

step().execute(new ComputationContext(mock(BatchReportReader.class), ComponentTesting.newProjectDto("ABCD")));
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

step().execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("ABCD")));

List<SearchHit> docs = esTester.getDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE);
assertThat(docs).hasSize(1);

+ 22
- 3
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java View File

@@ -23,12 +23,17 @@ package org.sonar.server.computation.step;
import org.elasticsearch.search.SearchHit;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.source.db.FileSourceDao;
@@ -37,14 +42,17 @@ import org.sonar.server.test.index.TestDoc;
import org.sonar.server.test.index.TestIndexDefinition;
import org.sonar.server.test.index.TestIndexer;

import java.io.File;
import java.sql.Connection;
import java.util.List;

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

public class IndexTestsStepTest extends BaseStepTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

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

@@ -53,27 +61,38 @@ public class IndexTestsStepTest extends BaseStepTest {

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);
return new IndexTestsStep(testIndexer, dbComponentsRefCache);
}

@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();

step().execute(new ComputationContext(mock(BatchReportReader.class), ComponentTesting.newProjectDto("ABCD")));
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

step().execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("ABCD")));

List<SearchHit> docs = esTester.getDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE);
assertThat(docs).hasSize(1);

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

@@ -30,6 +30,7 @@ import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.computation.issue.IssueComputation;

import java.io.File;
@@ -55,10 +56,16 @@ public class ParseReportStepTest extends BaseStepTest {
public static DbTester dbTester = new DbTester();

IssueComputation issueComputation = mock(IssueComputation.class);
ParseReportStep sut = new ParseReportStep(issueComputation);
ComputeComponentsRefCache computeComponentsRefCache = new ComputeComponentsRefCache();

ParseReportStep sut = new ParseReportStep(issueComputation, computeComponentsRefCache);

@Test
public void extract_report_from_db_and_browse_components() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "PROJECT_UUID"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:file1", "FILE1_UUID"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:file2", "FILE2_UUID"));

File reportDir = generateReport();

ComputationContext context = new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class));
@@ -68,10 +75,10 @@ public class ParseReportStepTest extends BaseStepTest {
assertThat(context.getReportMetadata().getDeletedComponentsCount()).isEqualTo(1);

// verify that all components are processed (currently only for issues)
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "PROJECT_UUID", 1);
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "FILE1_UUID", 2);
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "FILE2_UUID", 3);
verify(issueComputation).processComponentIssues(context, ISSUES_ON_DELETED_COMPONENT, "DELETED_UUID", null);
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "PROJECT_UUID", 1, "PROJECT_KEY", "PROJECT_UUID");
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "FILE1_UUID", 2, "PROJECT_KEY", "PROJECT_UUID");
verify(issueComputation).processComponentIssues(context, Collections.<BatchReport.Issue>emptyList(), "FILE2_UUID", 3, "PROJECT_KEY", "PROJECT_UUID");
verify(issueComputation).processComponentIssues(context, ISSUES_ON_DELETED_COMPONENT, "DELETED_UUID", null, "PROJECT_KEY", "PROJECT_UUID");
verify(issueComputation).afterReportProcessing();
}

@@ -89,19 +96,16 @@ public class ParseReportStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("PROJECT_UUID")
.addChildRef(2)
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.FILE)
.setUuid("FILE1_UUID")
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.FILE)
.setUuid("FILE2_UUID")
.build());

// deleted components

+ 56
- 104
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java View File

@@ -37,6 +37,8 @@ import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.ComputeComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

@@ -59,6 +61,9 @@ public class PersistComponentsStepTest extends BaseStepTest {

DbClient dbClient;

ComputeComponentsRefCache computeComponentsRefCache;
DbComponentsRefCache dbComponentsRefCache;

PersistComponentsStep sut;

@Before
@@ -69,7 +74,9 @@ public class PersistComponentsStepTest extends BaseStepTest {

reportDir = temp.newFolder();

sut = new PersistComponentsStep(dbClient);
computeComponentsRefCache = new ComputeComponentsRefCache();
dbComponentsRefCache = new DbComponentsRefCache();
sut = new PersistComponentsStep(dbClient, computeComponentsRefCache, dbComponentsRefCache);
}

@Override
@@ -84,6 +91,11 @@ public class PersistComponentsStepTest extends BaseStepTest {

@Test
public void persist_components() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY", "BCDE"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir", "CDEF"));
computeComponentsRefCache.addComponent(4, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir/Foo.java", "DEFG"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -127,7 +139,7 @@ public class PersistComponentsStepTest extends BaseStepTest {
assertThat(project).isNotNull();
assertThat(project.name()).isEqualTo("Project");
assertThat(project.description()).isEqualTo("Project description");
assertThat(project.uuid()).isNotNull();
assertThat(project.uuid()).isEqualTo("ABCD");
assertThat(project.moduleUuid()).isNull();
assertThat(project.moduleUuidPath()).isEqualTo("." + project.uuid() + ".");
assertThat(project.projectUuid()).isEqualTo(project.uuid());
@@ -139,7 +151,7 @@ public class PersistComponentsStepTest extends BaseStepTest {
assertThat(module).isNotNull();
assertThat(module.name()).isEqualTo("Module");
assertThat(module.description()).isEqualTo("Module description");
assertThat(module.uuid()).isNotNull();
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());
@@ -151,7 +163,7 @@ public class PersistComponentsStepTest extends BaseStepTest {
assertThat(directory).isNotNull();
assertThat(directory.name()).isEqualTo("src/main/java/dir");
assertThat(directory.path()).isEqualTo("src/main/java/dir");
assertThat(directory.uuid()).isNotNull();
assertThat(directory.uuid()).isEqualTo("CDEF");
assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
assertThat(directory.projectUuid()).isEqualTo(project.uuid());
@@ -164,17 +176,26 @@ public class PersistComponentsStepTest extends BaseStepTest {
assertThat(file.name()).isEqualTo("Foo.java");
assertThat(file.path()).isEqualTo("src/main/java/dir/Foo.java");
assertThat(file.language()).isEqualTo("java");
assertThat(file.uuid()).isNotNull();
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());
}

@Test
public void persist_file_directly_attached_on_root_directory() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:/", "CDEF"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:pom.xml", "DEFG"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -215,6 +236,10 @@ public class PersistComponentsStepTest extends BaseStepTest {

@Test
public void persist_unit_test() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:src/test/java/dir", "CDEF"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY:src/test/java/dir/FooTest.java", "DEFG"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -251,101 +276,13 @@ public class PersistComponentsStepTest extends BaseStepTest {
assertThat(file.scope()).isEqualTo("FIL");
}

@Test
public void use_latest_module_for_files_key() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setName("Project")
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.MODULE)
.setKey("SUB_MODULE_KEY")
.setName("Sub Module")
.addChildRef(4)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(5)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(5)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));

assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY:src/main/java/dir")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY:src/main/java/dir/Foo.java")).isNotNull();
}

@Test
public void persist_with_branch() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setBranch("origin/master")
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setName("Project")
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setKey("MODULE_KEY")
.setName("Module")
.addChildRef(3)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(3)
.setType(Constants.ComponentType.DIRECTORY)
.setPath("src/main/java/dir")
.addChildRef(4)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(4)
.setType(Constants.ComponentType.FILE)
.setPath("src/main/java/dir/Foo.java")
.build());

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));

assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
assertThat(dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY:origin/master")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master:src/main/java/dir")).isNotNull();
assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master:src/main/java/dir/Foo.java")).isNotNull();
}

@Test
public void persist_only_new_components() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY", "BCDE"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir", "CDEF"));
computeComponentsRefCache.addComponent(4, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir/Foo.java", "DEFG"));

// Project amd module already exists
ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
dbClient.componentDao().insert(session, project);
@@ -418,6 +355,11 @@ public class PersistComponentsStepTest extends BaseStepTest {

@Test
public void nothing_to_persist() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY", "BCDE"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir", "CDEF"));
computeComponentsRefCache.addComponent(4, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY:src/main/java/dir/Foo.java", "DEFG"));

ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
dbClient.componentDao().insert(session, project);
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setName("Module");
@@ -506,6 +448,9 @@ public class PersistComponentsStepTest extends BaseStepTest {

@Test
public void update_name_and_description() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("MODULE_KEY", "BCDE"));

ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
dbClient.componentDao().insert(session, project);
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setName("Module");
@@ -547,10 +492,17 @@ public class PersistComponentsStepTest extends BaseStepTest {

@Test
public void update_module_uuid_when_moving_a_module() throws Exception {
computeComponentsRefCache.addComponent(1, new ComputeComponentsRefCache.ComputeComponent("PROJECT_KEY", "ABCD"));
computeComponentsRefCache.addComponent(2, new ComputeComponentsRefCache.ComputeComponent("MODULE_A", "EDCB"));
computeComponentsRefCache.addComponent(3, new ComputeComponentsRefCache.ComputeComponent("MODULE_B", "BCDE"));
computeComponentsRefCache.addComponent(4, new ComputeComponentsRefCache.ComputeComponent("MODULE_B:src/main/java/dir", "CDEF"));
computeComponentsRefCache.addComponent(5, new ComputeComponentsRefCache.ComputeComponent("MODULE_B:src/main/java/dir/Foo.java", "DEFG"));

ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
dbClient.componentDao().insert(session, project);
ComponentDto moduleA = ComponentTesting.newModuleDto("EDCB", project).setKey("MODULE_A").setName("Module A");
ComponentDto moduleB = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_B").setName("Module B");
dbClient.componentDao().insert(session, moduleB);
dbClient.componentDao().insert(session, moduleA, moduleB);
ComponentDto directory = ComponentTesting.newDirectory(moduleB, "src/main/java/dir").setUuid("CDEF").setKey("MODULE_B:src/main/java/dir");
ComponentDto file = ComponentTesting.newFileDto(moduleB, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java").setKey("MODULE_B:src/main/java/dir/Foo.java");
dbClient.componentDao().insert(session, directory, file);
@@ -600,16 +552,16 @@ public class PersistComponentsStepTest extends BaseStepTest {

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

ComponentDto moduleA = dbClient.componentDao().selectNullableByKey(session, "MODULE_A");
assertThat(moduleA).isNotNull();
ComponentDto moduleAreloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_A");
assertThat(moduleAreloaded).isNotNull();

ComponentDto moduleBReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_B");
assertThat(moduleBReloaded).isNotNull();
assertThat(moduleBReloaded.uuid()).isEqualTo(moduleB.uuid());
assertThat(moduleBReloaded.moduleUuid()).isEqualTo(moduleA.uuid());
assertThat(moduleBReloaded.moduleUuidPath()).isEqualTo(moduleA.moduleUuidPath() + moduleBReloaded.uuid() + ".");
assertThat(moduleBReloaded.moduleUuid()).isEqualTo(moduleAreloaded.uuid());
assertThat(moduleBReloaded.moduleUuidPath()).isEqualTo(moduleAreloaded.moduleUuidPath() + moduleBReloaded.uuid() + ".");
assertThat(moduleBReloaded.projectUuid()).isEqualTo(project.uuid());
assertThat(moduleBReloaded.parentProjectId()).isEqualTo(moduleA.getId());
assertThat(moduleBReloaded.parentProjectId()).isEqualTo(moduleAreloaded.getId());

ComponentDto directoryReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_B:src/main/java/dir");
assertThat(directoryReloaded).isNotNull();

+ 24
- 51
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java View File

@@ -38,6 +38,8 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.measure.persistence.MetricDao;
@@ -64,6 +66,8 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

DbClient dbClient;

DbComponentsRefCache dbComponentsRefCache;

PersistDuplicationsStep sut;

@Before
@@ -74,7 +78,8 @@ public class PersistDuplicationsStepTest extends BaseStepTest {

reportDir = temp.newFolder();

sut = new PersistDuplicationsStep(dbClient);
dbComponentsRefCache = new DbComponentsRefCache();
sut = new PersistDuplicationsStep(dbClient, dbComponentsRefCache);
}

@Override
@@ -130,6 +135,10 @@ 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"));

saveDuplicationMetric();

File reportDir = temp.newFolder();
@@ -185,6 +194,11 @@ 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"));


saveDuplicationMetric();

BatchReportWriter writer = new BatchReportWriter(reportDir);
@@ -239,6 +253,11 @@ 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"));

saveDuplicationMetric();

BatchReportWriter writer = new BatchReportWriter(reportDir);
@@ -297,58 +316,9 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
assertThat(dto.get("textValue")).isEqualTo("<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:file\"/></g></duplications>");
}

@Test
public void persist_duplications_on_same_file_when_a_branch_is_used() throws Exception {
saveDuplicationMetric();

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setBranch("origin/master")
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("PROJECT_KEY")
.setSnapshotId(10L)
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.FILE)
.setSnapshotId(11L)
.setPath("file")
.build());

BatchReport.Duplication duplication = BatchReport.Duplication.newBuilder()
.setOriginPosition(Range.newBuilder()
.setStartLine(1)
.setEndLine(5)
.build())
.addDuplicate(BatchReport.Duplicate.newBuilder()
.setOtherFileRef(2)
.setRange(Range.newBuilder()
.setStartLine(6)
.setEndLine(10)
.build())
.build())
.build();
writer.writeComponentDuplications(2, newArrayList(duplication));

sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto("PROJECT")));

assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1);

Map<String, Object> dto = dbTester.selectFirst("select snapshot_id as \"snapshotId\", text_value as \"textValue\" from project_measures");
assertThat(dto.get("snapshotId")).isEqualTo(11L);
assertThat(dto.get("textValue")).isEqualTo(
"<duplications><g><b s=\"1\" l=\"5\" r=\"PROJECT_KEY:origin/master:file\"/><b s=\"6\" l=\"5\" r=\"PROJECT_KEY:origin/master:file\"/></g></duplications>");
}

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

@@ -413,6 +383,9 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
}

private BatchReportWriter initReportWithProjectAndFile() {
dbComponentsRefCache.addComponent(1, new DbComponent(1L, "PROJECT_KEY", "ABCD"));
dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:file", "BCDE"));

BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)

+ 17
- 7
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java View File

@@ -36,6 +36,8 @@ import org.sonar.core.component.ComponentDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.event.db.EventDao;
import org.sonar.test.DbTests;
@@ -60,6 +62,8 @@ public class PersistEventsStepTest extends BaseStepTest {

System2 system2;

DbComponentsRefCache dbComponentsRefCache;

PersistEventsStep step;

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

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

@Override
@@ -88,6 +93,8 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -99,7 +106,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.build());

step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
@@ -111,6 +117,8 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -122,7 +130,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.setSnapshotId(1000L)
.addEvent(BatchReport.Event.newBuilder()
.setName("Red (was Orange)")
@@ -147,6 +154,9 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -158,7 +168,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.setSnapshotId(1000L)
.addEvent(BatchReport.Event.newBuilder()
.setName("Red (was Orange)")
@@ -171,7 +180,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setUuid("BCDE")
.setSnapshotId(1001L)
.addEvent(BatchReport.Event.newBuilder()
.setName("Red (was Orange)")
@@ -189,6 +197,8 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -200,7 +210,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.setSnapshotId(1000L)
.setVersion("1.0")
.build());
@@ -214,6 +223,8 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -225,7 +236,6 @@ public class PersistEventsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.setSnapshotId(1001L)
.setVersion("1.5-SNAPSHOT")
.build());

+ 12
- 6
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java View File

@@ -41,6 +41,7 @@ import org.sonar.core.source.db.FileSourceDto;
import org.sonar.core.source.db.FileSourceDto.Type;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
import org.sonar.server.source.db.FileSourceDb;
@@ -78,6 +79,8 @@ public class PersistFileSourcesStepTest extends BaseStepTest {

System2 system2;

DbComponentsRefCache dbComponentsRefCache;

PersistFileSourcesStep sut;

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

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

@Override
@@ -131,6 +135,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));

BatchReportWriter writer = new BatchReportWriter(reportDir);
FileUtils.writeLines(writer.getFileStructure().fileFor(FileStructure.Domain.SOURCE, FILE_REF), Lists.newArrayList("line1", "line2"));
writer.writeMetadata(BatchReport.Metadata.newBuilder()
@@ -140,13 +147,11 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid(PROJECT_UUID)
.addChildRef(FILE_REF)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(FILE_REF)
.setType(Constants.ComponentType.FILE)
.setUuid(FILE_UUID)
// Lines is set to 3 but only 2 lines are read from the file -> the last lines should be added
.setLines(3)
.build());
@@ -440,6 +445,10 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
}

private BatchReportWriter 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));

BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
@@ -449,19 +458,16 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid(PROJECT_UUID)
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setUuid("MODULE")
.addChildRef(FILE_REF)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(FILE_REF)
.setType(Constants.ComponentType.FILE)
.setUuid(FILE_UUID)
.setPath("src/Foo.java")
.setLines(numberOfLines)
.build());

+ 154
- 70
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java View File

@@ -20,15 +20,17 @@

package org.sonar.server.computation.step;

import org.assertj.core.data.Offset;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.Uuids;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.Constants.MeasureValueType;
import org.sonar.batch.protocol.output.BatchReport;
@@ -36,55 +38,93 @@ import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.measure.db.MeasureDto;
import org.sonar.core.measure.db.MetricDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.computation.issue.RuleCacheLoader;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.measure.persistence.MetricDao;
import org.sonar.server.rule.RuleTesting;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.test.DbTests;

import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

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

@Category(DbTests.class)
public class PersistMeasuresStepTest extends BaseStepTest {

private static final String METRIC_KEY = "metric-key";
private static final RuleKey RULE_KEY = RuleKey.of("repo", "rule-key");

DbSession session;

@Rule
public TemporaryFolder temp = new TemporaryFolder();

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

DbClient dbClient;
RuleCache ruleCache;
MetricCache metricCache;
MeasureDao measureDao;
DbComponentsRefCache dbComponentsRefCache;

PersistMeasuresStep sut;
MetricDto metric;
RuleDto rule;

private BatchReport.Component component;
PersistMeasuresStep sut;

@Before
public void setUp() {
dbClient = mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS);
ruleCache = mock(RuleCache.class, Mockito.RETURNS_DEEP_STUBS);
metricCache = mock(MetricCache.class, Mockito.RETURNS_DEEP_STUBS);
when(metricCache.get("metric-key").getId()).thenReturn(654);
measureDao = mock(MeasureDao.class);
when(ruleCache.get(any(RuleKey.class)).getId()).thenReturn(987);
dbTester.truncateTables();

sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache);
dbComponentsRefCache = new DbComponentsRefCache();

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

metric = new MetricDto().setKey(METRIC_KEY).setEnabled(true).setOptimizedBestValue(false).setHidden(false).setDeleteHistoricalData(false);
dbClient.metricDao().insert(session, metric);
rule = RuleTesting.newDto(RULE_KEY);
dbClient.ruleDao().insert(session, rule);
session.commit();

ruleCache = new RuleCache(new RuleCacheLoader(dbClient));
metricCache = new MetricCache(dbClient);
session.commit();

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

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

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

File dir = temp.newFolder();
BatchReportWriter report = new BatchReportWriter(dir);

when(dbClient.measureDao()).thenReturn(measureDao);

report.writeMetadata(BatchReport.Metadata.newBuilder()
.setAnalysisDate(new Date().getTime())
.setRootComponentRef(1)
@@ -102,73 +142,85 @@ public class PersistMeasuresStepTest extends BaseStepTest {

report.writeComponentMeasures(1, Arrays.asList(
BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.STRING)
.setValueType(MeasureValueType.STRING)
.setStringValue("measure-data")
.setVariationValue1(1.1d)
.setVariationValue2(2.2d)
.setVariationValue3(3.3d)
.setVariationValue4(4.4d)
.setVariationValue5(5.5d)
.setAlertStatus("measure-alert-status")
.setAlertText("measure-alert-text")
.setAlertStatus("WARN")
.setAlertText("Open issues > 0")
.setDescription("measure-description")
.setSeverity(Constants.Severity.INFO)
.setMetricKey("metric-key")
.setRuleKey("repo:rule-key")
.setMetricKey(METRIC_KEY)
.setRuleKey(RULE_KEY.toString())
.setCharactericId(123456)
.build()));

report.writeComponentMeasures(2, Arrays.asList(
BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.DOUBLE)
.setValueType(MeasureValueType.DOUBLE)
.setDoubleValue(123.123d)
.setVariationValue1(1.1d)
.setVariationValue2(2.2d)
.setVariationValue3(3.3d)
.setVariationValue4(4.4d)
.setVariationValue5(5.5d)
.setAlertStatus("measure-alert-status")
.setAlertText("measure-alert-text")
.setAlertStatus("ERROR")
.setAlertText("Blocker issues variation > 0")
.setDescription("measure-description")
.setSeverity(Constants.Severity.BLOCKER)
.setMetricKey("metric-key")
.setRuleKey("repo:rule-key")
.setMetricKey(METRIC_KEY)
.setRuleKey(RULE_KEY.toString())
.setCharactericId(123456)
.build()));

sut.execute(new ComputationContext(new BatchReportReader(dir), mock(ComponentDto.class)));

ArgumentCaptor<MeasureDto> argument = ArgumentCaptor.forClass(MeasureDto.class);
verify(measureDao, times(2)).insert(any(DbSession.class), argument.capture());
assertThat(argument.getValue().getValue()).isEqualTo(123.123d, Offset.offset(0.0001d));
assertThat(argument.getValue().getMetricId()).isEqualTo(654);
assertThat(argument.getValue().getRuleId()).isEqualTo(987);
assertThat(argument.getValue().getSeverity()).isEqualTo(Severity.BLOCKER);
}

private BatchReport.Component.Builder defaultComponent() {
return BatchReport.Component.newBuilder()
.setRef(1)
.setId(2)
.setSnapshotId(3);
session.commit();

assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(2);

List<Map<String, Object>> dtos = dbTester.select(
"select snapshot_id as \"snapshotId\", project_id as \"componentId\", metric_id as \"metricId\", rule_id as \"ruleId\", value as \"value\", text_value as \"textValue\", " +
"rule_priority as \"severity\" from project_measures");

Map<String, Object> dto = dtos.get(0);
assertThat(dto.get("snapshotId")).isNotNull();
assertThat(dto.get("componentId")).isEqualTo(project.getId());
assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
assertThat(dto.get("textValue")).isEqualTo("measure-data");
assertThat(dto.get("severity")).isEqualTo(0L);

dto = dtos.get(1);
assertThat(dto.get("snapshotId")).isNotNull();
assertThat(dto.get("componentId")).isEqualTo(file.getId());
assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
assertThat(dto.get("value")).isEqualTo(123.123d);
assertThat(dto.get("severity")).isEqualTo(4L);
}

@Test
public void map_full_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.DOUBLE)
.setValueType(MeasureValueType.DOUBLE)
.setDoubleValue(123.123d)
.setVariationValue1(1.1d)
.setVariationValue2(2.2d)
.setVariationValue3(3.3d)
.setVariationValue4(4.4d)
.setVariationValue5(5.5d)
.setAlertStatus("measure-alert-status")
.setAlertText("measure-alert-text")
.setAlertStatus("WARN")
.setAlertText("Open issues > 0")
.setDescription("measure-description")
.setSeverity(Constants.Severity.CRITICAL)
.setMetricKey("metric-key")
.setRuleKey("repo:rule-key")
.setMetricKey(METRIC_KEY)
.setRuleKey(RULE_KEY.toString())
.setCharactericId(123456)
.setPersonId(5432)
.build();
@@ -180,9 +232,12 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void map_minimal_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.INT)
.setMetricKey("metric-key")
.setValueType(MeasureValueType.INT)
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
@@ -192,10 +247,13 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void map_boolean_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.BOOLEAN)
.setValueType(MeasureValueType.BOOLEAN)
.setBooleanValue(true)
.setMetricKey("metric-key")
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
@@ -203,9 +261,9 @@ public class PersistMeasuresStepTest extends BaseStepTest {
assertThat(measure.getValue()).isEqualTo(1.0);

batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.BOOLEAN)
.setValueType(MeasureValueType.BOOLEAN)
.setBooleanValue(false)
.setMetricKey("metric-key")
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
@@ -213,8 +271,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
assertThat(measure.getValue()).isEqualTo(0.0);

batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.BOOLEAN)
.setMetricKey("metric-key")
.setValueType(MeasureValueType.BOOLEAN)
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
@@ -224,10 +282,13 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void map_double_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.DOUBLE)
.setValueType(MeasureValueType.DOUBLE)
.setDoubleValue(3.2)
.setMetricKey("metric-key")
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
@@ -235,8 +296,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
assertThat(measure.getValue()).isEqualTo(3.2);

batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.DOUBLE)
.setMetricKey("metric-key")
.setValueType(MeasureValueType.DOUBLE)
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
@@ -246,10 +307,13 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void map_int_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.INT)
.setValueType(MeasureValueType.INT)
.setIntValue(3)
.setMetricKey("metric-key")
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
@@ -257,8 +321,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
assertThat(measure.getValue()).isEqualTo(3.0);

batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.INT)
.setMetricKey("metric-key")
.setValueType(MeasureValueType.INT)
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
@@ -268,10 +332,13 @@ public class PersistMeasuresStepTest extends BaseStepTest {

@Test
public void map_long_batch_measure() {
BatchReport.Component component = defaultComponent().build();
addComponent(component.getRef(), "component-key");

BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.LONG)
.setValueType(MeasureValueType.LONG)
.setLongValue(3L)
.setMetricKey("metric-key")
.setMetricKey(METRIC_KEY)
.build();

MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
@@ -279,8 +346,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
assertThat(measure.getValue()).isEqualTo(3.0);

batchMeasure = BatchReport.Measure.newBuilder()
.setValueType(Constants.MeasureValueType.LONG)
.setMetricKey("metric-key")
.setValueType(MeasureValueType.LONG)
.setMetricKey(METRIC_KEY)
.build();

measure = sut.toMeasureDto(batchMeasure, component);
@@ -296,6 +363,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.build();
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
}

@@ -306,6 +374,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.build();
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
}

@@ -316,6 +385,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.build();
BatchReport.Component component = defaultComponent()
.build();
addComponent(component.getRef(), "component-key");
sut.toMeasureDto(measure, component);
}

@@ -331,19 +401,33 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setVariation(3, 3.3d)
.setVariation(4, 4.4d)
.setVariation(5, 5.5d)
.setAlertStatus("measure-alert-status")
.setAlertText("measure-alert-text")
.setAlertStatus("WARN")
.setAlertText("Open issues > 0")
.setDescription("measure-description")
.setSeverity(Severity.CRITICAL)
.setMetricId(654)
.setRuleId(987);
.setMetricId(metric.getId())
.setRuleId(rule.getId());
}

private MeasureDto expectedMinimalistMeasure() {
return new MeasureDto()
.setComponentId(2L)
.setSnapshotId(3L)
.setMetricId(654);
.setMetricId(metric.getId());
}

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

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;
}

@Override

+ 9
- 3
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java View File

@@ -35,6 +35,7 @@ import org.sonar.core.measure.db.MetricDto;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.measure.MetricCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.measure.persistence.MeasureDao;
@@ -61,16 +62,19 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
SourceLineIndex sourceLineIndex;
MetricCache metricCache;

DbComponentsRefCache dbComponentsRefCache;

@Before
public void setUp() throws Exception {
db.truncateTables();
dbClient = new DbClient(db.database(), db.myBatis(), new MeasureDao());
sourceLineIndex = mock(SourceLineIndex.class);
metricCache = mock(MetricCache.class);
when(metricCache.get(anyString())).thenReturn(new MetricDto().setId(10));
dbComponentsRefCache = new DbComponentsRefCache();
dir = temp.newFolder();
db.truncateTables();

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

@Override
@@ -121,6 +125,9 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
}

private BatchReportWriter initReportWithProjectAndFile() {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, "project-key", "project-uuid"));
dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "project-key:file", "file-uuid"));

BatchReportWriter writer = new BatchReportWriter(dir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
@@ -131,7 +138,6 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setKey("project-key")
.setUuid("project-uuid")
.setSnapshotId(10L)
.addChildRef(2)
.build());

+ 20
- 15
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java View File

@@ -37,6 +37,7 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.component.db.ComponentLinkDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;
import org.sonar.test.DbTests;

@@ -63,6 +64,8 @@ public class PersistProjectLinksStepTest extends BaseStepTest {

I18n i18n;

DbComponentsRefCache dbComponentsRefCache;

PersistProjectLinksStep step;

@Before
@@ -78,7 +81,8 @@ 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");

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

@Override
@@ -95,6 +99,9 @@ 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"));

File reportDir = temp.newFolder();
// project and 1 module
BatchReportWriter writer = new BatchReportWriter(reportDir);
@@ -107,7 +114,6 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.addChildRef(2)
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar").build())
@@ -118,7 +124,6 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setUuid("BCDE")
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar/server").build())
.build());

@@ -131,18 +136,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.build());

@@ -155,18 +160,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.FILE)
.setUuid("ABCD")
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.build());

@@ -179,18 +184,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.build());

@@ -203,18 +208,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.build());

step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
@@ -226,18 +231,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.build());

step.execute(new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class)));
@@ -249,18 +254,18 @@ 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"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.setProjectKey("PROJECT_KEY")
.setAnalysisDate(150000000L)
.build());

writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid("ABCD")
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
.build());

+ 18
- 9
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java View File

@@ -39,6 +39,8 @@ import org.sonar.core.persistence.DbTester;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.source.db.FileSourceDto;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDao;
import org.sonar.server.source.db.FileSourceDb;
@@ -66,8 +68,6 @@ public class PersistTestsStepTest extends BaseStepTest {
private static final String TEST_FILE_PATH_1 = "TEST-PATH-1";
private static final String TEST_FILE_PATH_2 = "TEST-PATH-2";

PersistTestsStep sut;

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@@ -84,6 +84,10 @@ public class PersistTestsStepTest extends BaseStepTest {

long now = 123456789L;

DbComponentsRefCache dbComponentsRefCache;

PersistTestsStep sut;

@Before
public void setup() throws Exception {
db.truncateTables();
@@ -93,7 +97,9 @@ public class PersistTestsStepTest extends BaseStepTest {

system2 = mock(System2.class);
when(system2.now()).thenReturn(now);
sut = new PersistTestsStep(dbClient, system2);

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

initBasicReport();
}
@@ -131,6 +137,8 @@ public class PersistTestsStepTest extends BaseStepTest {

sut.execute(new ComputationContext(new BatchReportReader(reportDir), newProjectDto(PROJECT_UUID)));

assertThat(db.countRowsOfTable("file_sources")).isEqualTo(1);

FileSourceDto dto = dbClient.fileSourceDao().selectTest(TEST_FILE_UUID_1);
assertThat(dto.getCreatedAt()).isEqualTo(now);
assertThat(dto.getUpdatedAt()).isEqualTo(now);
@@ -295,6 +303,13 @@ public class PersistTestsStepTest extends BaseStepTest {
}

private BatchReportWriter 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));

BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
@@ -304,38 +319,32 @@ public class PersistTestsStepTest extends BaseStepTest {
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(1)
.setType(Constants.ComponentType.PROJECT)
.setUuid(PROJECT_UUID)
.addChildRef(2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(2)
.setType(Constants.ComponentType.MODULE)
.setUuid("MODULE")
.addAllChildRef(Arrays.asList(TEST_FILE_REF_1, TEST_FILE_REF_2, MAIN_FILE_REF_1, MAIN_FILE_REF_2))
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(TEST_FILE_REF_1)
.setIsTest(true)
.setType(Constants.ComponentType.FILE)
.setUuid(TEST_FILE_UUID_1)
.setPath(TEST_FILE_PATH_1)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(TEST_FILE_REF_2)
.setIsTest(true)
.setType(Constants.ComponentType.FILE)
.setUuid(TEST_FILE_UUID_2)
.setPath(TEST_FILE_PATH_2)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(MAIN_FILE_REF_1)
.setType(Constants.ComponentType.FILE)
.setUuid(MAIN_FILE_UUID_1)
.build());
writer.writeComponent(BatchReport.Component.newBuilder()
.setRef(MAIN_FILE_REF_2)
.setType(Constants.ComponentType.FILE)
.setUuid(MAIN_FILE_UUID_2)
.build());

return writer;

+ 28
- 8
server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java View File

@@ -23,36 +23,56 @@ package org.sonar.server.computation.step;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.sonar.api.config.Settings;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.computation.dbcleaner.ProjectCleaner;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.purge.IdUuidPair;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.db.DbClient;

import static org.mockito.Mockito.*;
import java.io.File;
import java.io.IOException;

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

public class PurgeDatastoresStepTest extends BaseStepTest {

ProjectCleaner projectCleaner = mock(ProjectCleaner.class);;
PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner);
ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbComponentsRefCache);

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void call_purge_method_of_the_purge_task() {
public void call_purge_method_of_the_purge_task() throws IOException {
dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(123L, "PROJECT_KEY", "UUID-1234"));

File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
.setRootComponentRef(1)
.build());

ComponentDto project = mock(ComponentDto.class);
when(project.getId()).thenReturn(123L);
when(project.uuid()).thenReturn("UUID-1234");
ComputationContext context = new ComputationContext(mock(BatchReportReader.class), project);
ComputationContext context = new ComputationContext(new BatchReportReader(reportDir), project);

sut.execute(context);

verify(projectCleaner).purge(any(DbSession.class), any(IdUuidPair.class), any(Settings.class));
ArgumentCaptor<IdUuidPair> argumentCaptor = ArgumentCaptor.forClass(IdUuidPair.class);
verify(projectCleaner).purge(any(DbSession.class), argumentCaptor.capture(), any(Settings.class));
assertThat(argumentCaptor.getValue().getId()).isEqualTo(123L);
assertThat(argumentCaptor.getValue().getUuid()).isEqualTo("UUID-1234");
}

@Override

+ 3079
- 5287
sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java
File diff suppressed because it is too large
View File


+ 7
- 9
sonar-batch-protocol/src/main/protobuf/batch_report.proto View File

@@ -72,21 +72,19 @@ message Component {
optional bool is_test = 5;
optional string language = 6;
repeated int32 child_ref = 7 [packed = true];
repeated ComponentLink link = 10;
repeated ComponentLink link = 8;
// Only available on PROJECT and MODULE types
optional string version = 12;
optional string version = 9;
// Only available on PROJECT and MODULE types
optional string key = 14;
optional string key = 10;
// Only available on FILE type
optional int32 lines = 15;
optional int32 lines = 11;
// Only available on PROJECT and MODULE types
optional string description = 16;
optional string description = 12;

// temporary fields during development of computation stack
optional int64 id = 13;
optional int64 snapshot_id = 8;
optional string uuid = 9;
repeated Event event = 11;
optional int64 snapshot_id = 13;
repeated Event event = 14;
}

message Measure {

+ 0
- 2
sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/output/BatchReportWriterTest.java View File

@@ -78,7 +78,6 @@ public class BatchReportWriterTest {
.setRef(1)
.setLanguage("java")
.setPath("src/Foo.java")
.setUuid("UUID_A")
.setType(Constants.ComponentType.FILE)
.setIsTest(false)
.addChildRef(5)
@@ -93,7 +92,6 @@ public class BatchReportWriterTest {
assertThat(read.getChildRefList()).containsOnly(5, 42);
assertThat(read.hasName()).isFalse();
assertThat(read.getIsTest()).isFalse();
assertThat(read.getUuid()).isEqualTo("UUID_A");
}

@Test

+ 2
- 5
sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java View File

@@ -31,10 +31,11 @@ import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.Constants.ComponentLinkType;
import org.sonar.batch.protocol.output.*;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Component.Builder;
import org.sonar.batch.protocol.output.BatchReport.ComponentLink;
import org.sonar.batch.protocol.output.BatchReport.Event;
import org.sonar.batch.protocol.output.BatchReportWriter;

import javax.annotation.CheckForNull;

@@ -74,10 +75,6 @@ public class ComponentsPublisher implements ReportPublisherStep {

// protocol buffers does not accept null values

String uuid = r.getUuid();
if (uuid != null) {
builder.setUuid(uuid);
}
Integer sid = batchResource.snapshotId();
if (sid != null) {
builder.setSnapshotId(sid);

+ 1
- 2
sonar-core/src/main/java/org/sonar/core/component/ComponentDto.java View File

@@ -135,12 +135,11 @@ public class ComponentDto implements Component {
/**
* Return the path from the project to the last modules
*/
@CheckForNull
public String moduleUuidPath() {
return moduleUuidPath;
}

public ComponentDto setModuleUuidPath(@Nullable String moduleUuidPath) {
public ComponentDto setModuleUuidPath(String moduleUuidPath) {
this.moduleUuidPath = moduleUuidPath;
return this;
}

+ 1
- 1
sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java View File

@@ -96,7 +96,7 @@ public interface ComponentMapper {
/**
* Return all components of a project
*/
List<ComponentDto> selectComponentsFromProjectUuid(@Param("projectUuid") String projectUuid);
List<ComponentDto> selectComponentsFromProjectKey(@Param("projectKey") String projectKey);

/**
* Return technical projects from a view or a sub-view

+ 3
- 3
sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml View File

@@ -213,11 +213,11 @@
</where>
</select>

<select id="selectComponentsFromProjectUuid" parameterType="map" resultType="Component">
<select id="selectComponentsFromProjectKey" parameterType="map" resultType="Component">
SELECT <include refid="componentColumns"/>
FROM projects p
INNER JOIN projects root ON root.uuid=p.project_uuid AND root.kee=#{projectKey}
<where>
AND p.project_uuid=#{projectUuid}
AND p.enabled=${_true}
</where>
</select>
@@ -285,7 +285,7 @@
#{createdAt,jdbcType=TIMESTAMP}, #{authorizationUpdatedAt,jdbcType=BIGINT})
</insert>

<insert id="update" parameterType="Component">
<insert id="update" parameterType="Component" useGeneratedKeys="false">
UPDATE projects SET
kee=#{kee,jdbcType=VARCHAR},
deprecated_kee=#{deprecatedKey,jdbcType=VARCHAR},

+ 14
- 4
sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java View File

@@ -62,7 +62,12 @@ import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.*;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -198,7 +203,7 @@ public class DbTester extends ExternalResource {
throw new IllegalStateException("No results for " + sql);

} catch (Exception e) {
throw new IllegalStateException("Fail to execute sql: " + sql);
throw new IllegalStateException("Fail to execute sql: " + sql, e);
}
}

@@ -209,7 +214,7 @@ public class DbTester extends ExternalResource {
ResultSet rs = stmt.executeQuery()) {
return getHashMap(rs);
} catch (Exception e) {
throw new IllegalStateException("Fail to execute sql: " + selectSql);
throw new IllegalStateException("Fail to execute sql: " + selectSql, e);
}
}

@@ -237,7 +242,12 @@ public class DbTester extends ExternalResource {
doClobFree(clob);
} else if (value instanceof BigDecimal) {
// In Oracle, INTEGER types are mapped as BigDecimal
value = ((BigDecimal) value).longValue();
BigDecimal bgValue = ((BigDecimal)value);
if (bgValue.scale() == 0) {
value = bgValue.longValue();
} else {
value = bgValue.doubleValue();
}
} else if (value instanceof Integer) {
// To be consistent, all INTEGER types are mapped as Long
value = ((Integer) value).longValue();

Loading…
Cancel
Save