From be8707ef18df79c56b14d8296a0955a6f81eae89 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 26 May 2015 14:22:27 +0200 Subject: [PATCH] SONAR-6589 make BatchReportReader a dependency of ComputationSteps move batch zip file extraction to new class ReportExtractor --- .../benchmark/PersistFileSourcesStepTest.java | 2 +- .../computation/ComputationContainer.java | 35 +++-- .../computation/ComputationService.java | 97 +++--------- .../activity/CEActivityManager.java | 72 +++++++++ .../computation/activity/package-info.java | 24 +++ ...rtReader.java => CEBatchReportReader.java} | 7 +- .../computation/batch/ReportExtractor.java | 56 +++++++ .../computation/component/ComponentImpl.java | 11 +- .../component/ComponentTreeBuilders.java | 8 +- .../computation/container/CEContainer.java | 55 +++++++ .../computation/container/package-info.java | 24 +++ .../computation/issue/IssueComputation.java | 15 +- .../computation/step/ComputationSteps.java | 41 ++--- .../computation/step/ParseReportStep.java | 10 +- .../step/PersistComponentsStep.java | 23 ++- .../step/PersistDuplicationsStep.java | 7 +- .../computation/step/PersistEventsStep.java | 5 +- .../step/PersistFileSourcesStep.java | 5 +- .../computation/step/PersistMeasuresStep.java | 6 +- ...ersistNumberOfDaysSinceLastCommitStep.java | 5 +- .../step/PersistProjectLinksStep.java | 5 +- .../computation/step/PersistTestsStep.java | 12 +- .../PopulateComponentsUuidAndKeyStep.java | 5 +- .../step/SendIssueNotificationsStep.java | 14 +- .../computation/ComputationServiceTest.java | 146 ++++-------------- .../activity/CEActivityManagerTest.java | 86 +++++++++++ .../batch/BatchReportReaderRule.java | 2 + .../batch/ReportExtractorTest.java | 58 +++++++ .../issue/IssueComputationTest.java | 11 +- .../step/ComputationStepsTest.java | 18 ++- .../step/IndexComponentsStepTest.java | 20 +-- .../step/IndexSourceLinesStepTest.java | 21 +-- .../computation/step/IndexTestsStepTest.java | 19 +-- .../computation/step/ParseReportStepTest.java | 2 +- .../step/PersistComponentsStepTest.java | 2 +- .../step/PersistDuplicationsStepTest.java | 2 +- .../step/PersistEventsStepTest.java | 2 +- .../step/PersistFileSourcesStepTest.java | 2 +- .../step/PersistMeasuresStepTest.java | 2 +- ...stNumberOfDaysSinceLastCommitStepTest.java | 2 +- .../step/PersistProjectLinksStepTest.java | 118 +++++++------- .../step/PersistTestsStepTest.java | 6 +- .../PopulateComponentsUuidAndKeyStepTest.java | 2 +- .../step/SendIssueNotificationsStepTest.java | 2 +- .../CEActivityManagerTest}/shared.xml | 2 +- .../core/platform/ComponentContainer.java | 16 +- 46 files changed, 664 insertions(+), 421 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/activity/CEActivityManager.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/activity/package-info.java rename server/sonar-server/src/main/java/org/sonar/server/computation/batch/{FileBatchReportReader.java => CEBatchReportReader.java} (95%) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/container/CEContainer.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/container/package-info.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/activity/CEActivityManagerTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java rename server/sonar-server/src/test/resources/org/sonar/server/computation/{ComputationServiceTest => activity/CEActivityManagerTest}/shared.xml (93%) diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java index e7a27afed64..637a1b692e9 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java @@ -76,7 +76,7 @@ public class PersistFileSourcesStepTest { long start = System.currentTimeMillis(); - PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, dbComponentsRefCache); + PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, dbComponentsRefCache, reportReader); step.execute(new ComputationContext(reportReader, "PROJECT_KEY", new Settings(), dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), mock(LanguageRepository.class))); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java index a669ba7778d..e8058874ca0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java @@ -19,10 +19,16 @@ */ package org.sonar.server.computation; +import java.util.Arrays; +import java.util.List; import org.sonar.core.issue.db.UpdateConflictResolver; import org.sonar.core.platform.ComponentContainer; +import org.sonar.server.computation.activity.CEActivityManager; +import org.sonar.server.computation.batch.CEBatchReportReader; +import org.sonar.server.computation.batch.ReportExtractor; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.ProjectSettingsRepository; +import org.sonar.server.computation.container.CEContainer; import org.sonar.server.computation.issue.IssueCache; import org.sonar.server.computation.issue.IssueComputation; import org.sonar.server.computation.issue.RuleCache; @@ -36,9 +42,6 @@ import org.sonar.server.computation.step.ComputationSteps; import org.sonar.server.platform.Platform; import org.sonar.server.view.index.ViewIndex; -import java.util.Arrays; -import java.util.List; - public class ComputationContainer { /** @@ -47,14 +50,15 @@ public class ComputationContainer { */ static List componentClasses() { return Arrays.asList( - // context-scope repositories + CEActivityManager.class, + ReportExtractor.class, + CEBatchReportReader.class, + + // repositories PlatformLanguageRepository.class, ProjectSettingsRepository.class, - ComputationService.class, - ComputationSteps.class, - - // component cache + // component caches DbComponentsRefCache.class, // issues @@ -74,17 +78,20 @@ public class ComputationContainer { public void execute(ReportQueue.Item item) { ComponentContainer container = Platform.getInstance().getContainer(); - ComponentContainer child = container.createChild(); - child.addSingletons(componentClasses()); - child.addSingletons(ComputationSteps.orderedStepClasses()); - child.startComponents(); + + ComponentContainer ceContainer = new CEContainer(container); + ceContainer.add(ceContainer); + ceContainer.add(item); + ceContainer.addSingletons(componentClasses()); + ceContainer.addSingletons(ComputationSteps.orderedStepClasses()); try { - child.getComponentByType(ComputationService.class).process(item); + ceContainer.getComponentByType(ComputationService.class).process(); } finally { - child.stopComponents(); + ceContainer.stopComponents(); // TODO not possible to have multiple children -> will be // a problem when we will have multiple concurrent computation workers container.removeChild(); } } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationService.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationService.java index 0c934542a72..5646d2f6efb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationService.java @@ -17,37 +17,22 @@ * 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; import com.google.common.base.Throwables; -import java.io.File; -import java.io.IOException; -import javax.annotation.CheckForNull; -import org.apache.commons.io.FileUtils; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.System2; -import org.sonar.api.utils.TempFolder; -import org.sonar.api.utils.ZipUtils; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.server.activity.Activity; -import org.sonar.server.activity.ActivityService; +import org.sonar.server.computation.activity.CEActivityManager; import org.sonar.server.computation.batch.BatchReportReader; -import org.sonar.server.computation.batch.FileBatchReportReader; import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.language.LanguageRepository; import org.sonar.server.computation.step.ComputationStep; import org.sonar.server.computation.step.ComputationSteps; import org.sonar.server.db.DbClient; -import static org.sonar.api.utils.DateUtils.formatDateTimeNullSafe; -import static org.sonar.api.utils.DateUtils.longToDate; import static org.sonar.core.computation.db.AnalysisReportDto.Status.FAILED; import static org.sonar.core.computation.db.AnalysisReportDto.Status.SUCCESS; @@ -56,33 +41,35 @@ public class ComputationService { private static final Logger LOG = Loggers.get(ComputationService.class); - private final DbClient dbClient; + private final ReportQueue.Item item; private final ComputationSteps steps; - private final ActivityService activityService; - private final TempFolder tempFolder; + private final BatchReportReader reportReader; + private final CEActivityManager activityManager; private final System2 system; + private final DbClient dbClient; private final LanguageRepository languageRepository; - public ComputationService(DbClient dbClient, ComputationSteps steps, ActivityService activityService, - TempFolder tempFolder, System2 system, LanguageRepository languageRepository) { - this.dbClient = dbClient; + public ComputationService(ReportQueue.Item item, ComputationSteps steps, CEActivityManager activityManager, System2 system, + BatchReportReader reportReader, DbClient dbClient, LanguageRepository languageRepository) { + this.item = item; this.steps = steps; - this.activityService = activityService; - this.tempFolder = tempFolder; + this.reportReader = reportReader; + this.activityManager = activityManager; this.system = system; + this.dbClient = dbClient; this.languageRepository = languageRepository; } - public void process(ReportQueue.Item item) { + public void process() { String projectKey = item.dto.getProjectKey(); - Profiler profiler = Profiler.create(LOG).startDebug(String.format( - "Analysis of project %s (report %d)", projectKey, item.dto.getId())); + Profiler profiler = Profiler.create(LOG).startDebug( + String.format("Analysis of project %s (report %d)", projectKey, item.dto.getId()) + ); try { - File reportDir = extractReportInDir(item); - BatchReportReader reader = new FileBatchReportReader(new org.sonar.batch.protocol.output.BatchReportReader(reportDir)); - ComputationContext context = new ComputationContext(reader, null, null, dbClient, ComponentTreeBuilders.from(reader), languageRepository); - for (ComputationStep step : steps.orderedSteps()) { + ComputationContext context = new ComputationContext(reportReader, null, null, dbClient, ComponentTreeBuilders.from(reportReader), languageRepository); + + for (ComputationStep step : steps.instances()) { Profiler stepProfiler = Profiler.createIfDebug(LOG).startDebug(step.getDescription()); step.execute(context); stepProfiler.stopDebug(); @@ -93,54 +80,8 @@ public class ComputationService { throw Throwables.propagate(e); } finally { item.dto.setFinishedAt(system.now()); - saveActivity(item.dto); + activityManager.saveActivity(item.dto); profiler.stopInfo(); } } - - private File extractReportInDir(ReportQueue.Item item) { - File dir = tempFolder.newDir(); - try { - Profiler profiler = Profiler.createIfDebug(LOG).start(); - ZipUtils.unzip(item.zipFile, dir); - if (profiler.isDebugEnabled()) { - String message = String.format("Report extracted | size=%s | project=%s", - FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(dir)), item.dto.getProjectKey()); - profiler.stopDebug(message); - } - return dir; - } catch (IOException e) { - throw new IllegalStateException(String.format("Fail to unzip %s into %s", item.zipFile, dir), e); - } - } - - private void saveActivity(AnalysisReportDto report) { - ComponentDto project = loadProject(report.getProjectKey()); - Activity activity = new Activity(); - activity.setType(Activity.Type.ANALYSIS_REPORT); - activity.setAction("LOG_ANALYSIS_REPORT"); - activity - .setData("key", String.valueOf(report.getId())) - .setData("projectKey", report.getProjectKey()) - .setData("status", String.valueOf(report.getStatus())) - .setData("submittedAt", formatDateTimeNullSafe(longToDate(report.getCreatedAt()))) - .setData("startedAt", formatDateTimeNullSafe(longToDate(report.getStartedAt()))) - .setData("finishedAt", formatDateTimeNullSafe(longToDate(report.getFinishedAt()))); - if (project != null) { - activity - .setData("projectName", project.name()) - .setData("projectUuid", project.uuid()); - } - activityService.save(activity); - } - - @CheckForNull - private ComponentDto loadProject(String projectKey) { - DbSession session = dbClient.openSession(false); - try { - return dbClient.componentDao().selectNullableByKey(session, projectKey); - } finally { - MyBatis.closeQuietly(session); - } - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/activity/CEActivityManager.java b/server/sonar-server/src/main/java/org/sonar/server/computation/activity/CEActivityManager.java new file mode 100644 index 00000000000..c77700a7ab5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/activity/CEActivityManager.java @@ -0,0 +1,72 @@ +/* + * 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.activity; + +import javax.annotation.CheckForNull; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.activity.Activity; +import org.sonar.server.activity.ActivityService; +import org.sonar.server.db.DbClient; + +import static org.sonar.api.utils.DateUtils.formatDateTimeNullSafe; +import static org.sonar.api.utils.DateUtils.longToDate; + +public class CEActivityManager { + private final ActivityService activityService; + private final DbClient dbClient; + + public CEActivityManager(ActivityService activityService, DbClient dbClient) { + this.activityService = activityService; + this.dbClient = dbClient; + } + + public void saveActivity(AnalysisReportDto report) { + ComponentDto project = loadProject(report.getProjectKey()); + Activity activity = new Activity(); + activity.setType(Activity.Type.ANALYSIS_REPORT); + activity.setAction("LOG_ANALYSIS_REPORT"); + activity + .setData("key", String.valueOf(report.getId())) + .setData("projectKey", report.getProjectKey()) + .setData("status", String.valueOf(report.getStatus())) + .setData("submittedAt", formatDateTimeNullSafe(longToDate(report.getCreatedAt()))) + .setData("startedAt", formatDateTimeNullSafe(longToDate(report.getStartedAt()))) + .setData("finishedAt", formatDateTimeNullSafe(longToDate(report.getFinishedAt()))); + if (project != null) { + activity + .setData("projectName", project.name()) + .setData("projectUuid", project.uuid()); + } + activityService.save(activity); + } + + @CheckForNull + private ComponentDto loadProject(String projectKey) { + DbSession session = dbClient.openSession(false); + try { + return dbClient.componentDao().selectNullableByKey(session, projectKey); + } finally { + MyBatis.closeQuietly(session); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/activity/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/activity/package-info.java new file mode 100644 index 00000000000..84449c529aa --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/activity/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +@ParametersAreNonnullByDefault +package org.sonar.server.computation.activity; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/FileBatchReportReader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/CEBatchReportReader.java similarity index 95% rename from server/sonar-server/src/main/java/org/sonar/server/computation/batch/FileBatchReportReader.java rename to server/sonar-server/src/main/java/org/sonar/server/computation/batch/CEBatchReportReader.java index ae838b8f2fe..810443eb5da 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/FileBatchReportReader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/CEBatchReportReader.java @@ -32,13 +32,14 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.server.computation.ReportQueue; import org.sonar.server.util.CloseableIterator; -public class FileBatchReportReader implements BatchReportReader { +public class CEBatchReportReader implements BatchReportReader { private final org.sonar.batch.protocol.output.BatchReportReader delegate; - public FileBatchReportReader(org.sonar.batch.protocol.output.BatchReportReader delegate) { - this.delegate = delegate; + public CEBatchReportReader(ReportExtractor reportExtractor, ReportQueue.Item item) { + this.delegate = new org.sonar.batch.protocol.output.BatchReportReader(reportExtractor.extractReportInDir(item)); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java new file mode 100644 index 00000000000..61aa6a95cfc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.computation.batch; + +import java.io.File; +import java.io.IOException; +import org.apache.commons.io.FileUtils; +import org.sonar.api.utils.TempFolder; +import org.sonar.api.utils.ZipUtils; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.api.utils.log.Profiler; +import org.sonar.server.computation.ReportQueue; + +public class ReportExtractor { + private static final Logger LOG = Loggers.get(ReportExtractor.class); + + private final TempFolder tempFolder; + + public ReportExtractor(TempFolder tempFolder) { + this.tempFolder = tempFolder; + } + + public File extractReportInDir(ReportQueue.Item item) { + File dir = tempFolder.newDir(); + try { + Profiler profiler = Profiler.createIfDebug(LOG).start(); + ZipUtils.unzip(item.zipFile, dir); + if (profiler.isDebugEnabled()) { + String message = String.format("Report extracted | size=%s | project=%s", + FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(dir)), item.dto.getProjectKey()); + profiler.stopDebug(message); + } + return dir; + } catch (IOException e) { + throw new IllegalStateException(String.format("Fail to unzip %s into %s", item.zipFile, dir), e); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentImpl.java index 92e67c3c62a..c0690e03cbd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentImpl.java @@ -34,6 +34,7 @@ import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.measure.db.MeasureDto; import org.sonar.core.persistence.DbSession; import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.event.Event; import org.sonar.server.computation.event.EventRepository; import org.sonar.server.computation.measure.MeasureRepository; @@ -49,15 +50,18 @@ public class ComponentImpl implements Component { private final Type type; private final BatchReport.Component component; private final List children; + private final BatchReportReader reportReader; private final EventRepository eventRepository = new SetEventRepository(); // Mutable values private String key; private String uuid; - public ComponentImpl(ComputationContext context, BatchReport.Component component, @Nullable Iterable children) { + public ComponentImpl(ComputationContext context, BatchReport.Component component, + BatchReportReader reportReader, @Nullable Iterable children) { this.context = context; this.component = component; + this.reportReader = reportReader; this.type = convertType(component.getType()); this.children = children == null ? Collections.emptyList() : copyOf(filter(children, notNull())); } @@ -134,7 +138,8 @@ public class ComponentImpl implements Component { DbClient dbClient = context.getDbClient(); try (DbSession dbSession = dbClient.openSession(false)) { return Optional.fromNullable( - // TODO replace component.getKey() by ${link #getKey} as component.getKey() is only for project/module and does not take into account usage of the branch + // TODO replace component.getKey() by ${link #getKey} as component.getKey() is only for project/module and does not take into + // account usage of the branch dbClient.measureDao().findByComponentKeyAndMetricKey(dbSession, component.getKey(), metric.getKey()) ); } @@ -143,7 +148,7 @@ public class ComponentImpl implements Component { @Override public Optional findCurrent(final Metric metric) { return Optional.fromNullable(Iterables.find( - context.getReportReader().readComponentMeasures(component.getRef()), + reportReader.readComponentMeasures(component.getRef()), new Predicate() { @Override public boolean apply(@Nonnull BatchReport.Measure input) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentTreeBuilders.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentTreeBuilders.java index 957ade019ca..3369a91e1a0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentTreeBuilders.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentTreeBuilders.java @@ -66,18 +66,18 @@ public final class ComponentTreeBuilders { private Component buildComponentRoot(ComputationContext computationContext, BatchReportReader reportReader) { int rootComponentRef = computationContext.getReportMetadata().getRootComponentRef(); BatchReport.Component component = reportReader.readComponent(rootComponentRef); - return new ComponentImpl(computationContext, component, buildComponent(computationContext, rootComponentRef)); + return new ComponentImpl(computationContext, component, reportReader, buildComponent(computationContext, rootComponentRef)); } private Iterable buildComponent(final ComputationContext computationContext, int componentRef) { - BatchReport.Component component = computationContext.getReportReader().readComponent(componentRef); + BatchReport.Component component = reportReader.readComponent(componentRef); return Iterables.transform( component.getChildRefList(), new Function() { @Override public Component apply(@Nonnull Integer componentRef) { - BatchReport.Component component = computationContext.getReportReader().readComponent(componentRef); - return new ComponentImpl(computationContext, component, buildComponent(computationContext, componentRef)); + BatchReport.Component component = reportReader.readComponent(componentRef); + return new ComponentImpl(computationContext, component, reportReader, buildComponent(computationContext, componentRef)); } } ); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/CEContainer.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/CEContainer.java new file mode 100644 index 00000000000..770376b13f8 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/CEContainer.java @@ -0,0 +1,55 @@ +/* + * 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.container; + +import org.picocontainer.ComponentAdapter; +import org.picocontainer.DefaultPicoContainer; +import org.picocontainer.MutablePicoContainer; +import org.picocontainer.behaviors.OptInCaching; +import org.picocontainer.lifecycle.ReflectionLifecycleStrategy; +import org.picocontainer.monitors.NullComponentMonitor; +import org.sonar.api.utils.log.Loggers; +import org.sonar.api.utils.log.Profiler; +import org.sonar.core.platform.ComponentContainer; + +public class CEContainer extends ComponentContainer { + public CEContainer(ComponentContainer parent) { + super(createContainer(parent), parent); + } + + private static MutablePicoContainer createContainer(ComponentContainer parent) { + ReflectionLifecycleStrategy lifecycleStrategy = new ReflectionLifecycleStrategy(new NullComponentMonitor(), "start", "stop", "close") { + @Override + public boolean isLazy(ComponentAdapter adapter) { + return true; + } + + @Override + public void start(Object component) { + Profiler profiler = Profiler.createIfTrace(Loggers.get(ComponentContainer.class)); + profiler.start(); + super.start(component); + profiler.stopTrace(component.getClass().getCanonicalName() + " started"); + } + }; + + return new DefaultPicoContainer(new OptInCaching(), lifecycleStrategy, parent.getPicoContainer()); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/package-info.java new file mode 100644 index 00000000000..de45519a6e6 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +@ParametersAreNonnullByDefault +package org.sonar.server.computation.container; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java index 17b8cfd6468..568d2b9982d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueComputation.java @@ -21,6 +21,8 @@ package org.sonar.server.computation.issue; import com.google.common.base.Strings; import com.google.common.collect.Sets; +import java.util.Date; +import javax.annotation.Nullable; import org.sonar.api.CoreProperties; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.issue.internal.FieldDiffs; @@ -32,15 +34,12 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.rule.RuleDto; import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.component.ProjectSettingsRepository; import org.sonar.server.user.index.UserDoc; import org.sonar.server.user.index.UserIndex; import org.sonar.server.util.cache.DiskCache; -import javax.annotation.Nullable; - -import java.util.Date; - public class IssueComputation { private static final Logger LOG = Loggers.get(IssueComputation.class); @@ -51,22 +50,24 @@ public class IssueComputation { private final DiskCache.DiskAppender diskIssuesAppender; private final UserIndex userIndex; private final ProjectSettingsRepository projectSettingsRepository; + private final BatchReportReader reportReader; private boolean hasAssigneeBeenComputed = false; private String defaultAssignee = null; public IssueComputation(RuleCache ruleCache, SourceLinesCache linesCache, ScmAccountCache scmAccountCache, - IssueCache issueCache, UserIndex userIndex, ProjectSettingsRepository projectSettingsRepository) { + IssueCache issueCache, UserIndex userIndex, ProjectSettingsRepository projectSettingsRepository, BatchReportReader reportReader) { this.ruleCache = ruleCache; this.linesCache = linesCache; this.scmAccountCache = scmAccountCache; this.userIndex = userIndex; + this.reportReader = reportReader; this.projectSettingsRepository = projectSettingsRepository; this.diskIssuesAppender = issueCache.newAppender(); } public void processComponentIssues(ComputationContext context, Iterable issues, String componentUuid, @Nullable Integer componentReportRef, - String projectKey, String projectUuid) { - linesCache.init(componentUuid, componentReportRef, context.getReportReader()); + String projectKey, String projectUuid) { + linesCache.init(componentUuid, componentReportRef, reportReader); computeDefaultAssignee(projectSettingsRepository.getProjectSettings(projectKey).getString(CoreProperties.DEFAULT_ISSUE_ASSIGNEE)); for (BatchReport.Issue reportIssue : issues) { DefaultIssue issue = toDefaultIssue(context, componentUuid, reportIssue, projectKey, projectUuid); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java index c1052d65fdf..7360cd2b20c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java @@ -17,13 +17,13 @@ * 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.collect.Lists; +import com.google.common.base.Function; +import com.google.common.collect.Iterables; import java.util.Arrays; import java.util.List; -import org.sonar.server.computation.ComputationContainer; +import org.sonar.server.computation.container.CEContainer; /** * Ordered list of steps to be executed @@ -71,30 +71,23 @@ public class ComputationSteps { SendIssueNotificationsStep.class); } - private final List orderedSteps; - - public ComputationSteps(ComputationStep... s) { - this.orderedSteps = order(s); - } - - public List orderedSteps() { - return orderedSteps; - } + private final CEContainer ceContainer; - private static List order(ComputationStep[] steps) { - List result = Lists.newArrayList(); - for (Class clazz : orderedStepClasses()) { - result.add(find(steps, clazz)); - } - return result; + public ComputationSteps(CEContainer ceContainer) { + this.ceContainer = ceContainer; } - private static ComputationStep find(ComputationStep[] steps, Class clazz) { - for (ComputationStep step : steps) { - if (clazz.isInstance(step)) { - return step; + public Iterable instances() { + return Iterables.transform(orderedStepClasses(), new Function, ComputationStep>() { + @Override + public ComputationStep apply(Class input) { + ComputationStep computationStepType = ceContainer.getComponentByType(input); + if (computationStepType == null) { + throw new IllegalStateException(String.format("Component not found: %s", input)); + } + return computationStepType; } - } - throw new IllegalStateException("Component not found: " + clazz + ". Check " + ComputationContainer.class); + }); } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java index f17085e67be..78a46f3c9ec 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java @@ -23,17 +23,19 @@ package org.sonar.server.computation.step; import java.util.List; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.component.Component; import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor; -import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.issue.IssueComputation; public class ParseReportStep implements ComputationStep { private final IssueComputation issueComputation; + private final BatchReportReader reportReader; - public ParseReportStep(IssueComputation issueComputation) { + public ParseReportStep(IssueComputation issueComputation, BatchReportReader reportReader) { this.issueComputation = issueComputation; + this.reportReader = reportReader; } @Override @@ -47,7 +49,7 @@ public class ParseReportStep implements ComputationStep { private void processDeletedComponents(ComputationContext context, IssueDepthTraversalTypeAwareVisitor visitor) { int deletedComponentsCount = context.getReportMetadata().getDeletedComponentsCount(); for (int componentRef = 1; componentRef <= deletedComponentsCount; componentRef++) { - BatchReport.Issues issues = context.getReportReader().readDeletedComponentIssues(componentRef); + BatchReport.Issues issues = reportReader.readDeletedComponentIssues(componentRef); issueComputation.processComponentIssues(context, issues.getIssueList(), issues.getComponentUuid(), null, visitor.projectKey, visitor.projectUuid); } } @@ -60,14 +62,12 @@ public class ParseReportStep implements ComputationStep { private class IssueDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor { private final ComputationContext context; - private final BatchReportReader reportReader; private String projectKey; private String projectUuid; public IssueDepthTraversalTypeAwareVisitor(ComputationContext context) { super(Component.Type.FILE, Order.PRE_ORDER); - this.reportReader = context.getReportReader(); this.context = context; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java index 16c0466c73d..df2dfad32c9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java @@ -42,10 +42,12 @@ public class PersistComponentsStep implements ComputationStep { private final DbClient dbClient; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache) { + public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -55,9 +57,9 @@ public class PersistComponentsStep implements ComputationStep { Component root = context.getRoot(); List components = dbClient.componentDao().selectComponentsFromProjectKey(session, root.getKey()); Map componentDtosByKey = componentDtosByKey(components); - ComponentContext componentContext = new ComponentContext(context.getReportReader(), session, componentDtosByKey); + ComponentContext componentContext = new ComponentContext(session, componentDtosByKey); - ComponentDto projectDto = processProject(root, componentContext.reportReader.readComponent(root.getRef()), componentContext); + ComponentDto projectDto = processProject(root, reportReader.readComponent(root.getRef()), componentContext); processChildren(componentContext, root, projectDto, projectDto); session.commit(); } finally { @@ -66,7 +68,6 @@ public class PersistComponentsStep implements ComputationStep { } private void recursivelyProcessComponent(ComponentContext componentContext, Component component, ComponentDto parentModule, ComponentDto project) { - BatchReportReader reportReader = componentContext.reportReader; BatchReport.Component reportComponent = reportReader.readComponent(component.getRef()); switch (component.getType()) { @@ -94,7 +95,7 @@ public class PersistComponentsStep implements ComputationStep { } public ComponentDto processProject(Component project, BatchReport.Component reportComponent, ComponentContext componentContext) { - ComponentDto componentDto = createComponentDto(reportComponent, project); + ComponentDto componentDto = createComponentDto(project); componentDto.setScope(Scopes.PROJECT); componentDto.setQualifier(Qualifiers.PROJECT); @@ -110,7 +111,7 @@ public class PersistComponentsStep implements ComputationStep { } public ComponentDto processModule(Component module, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) { - ComponentDto componentDto = createComponentDto(reportComponent, module); + ComponentDto componentDto = createComponentDto(module); componentDto.setScope(Scopes.PROJECT); componentDto.setQualifier(Qualifiers.MODULE); @@ -131,7 +132,7 @@ public class PersistComponentsStep implements ComputationStep { } public void processDirectory(Component directory, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) { - ComponentDto componentDto = createComponentDto(reportComponent, directory); + ComponentDto componentDto = createComponentDto(directory); componentDto.setScope(Scopes.DIRECTORY); componentDto.setQualifier(Qualifiers.DIRECTORY); @@ -150,7 +151,7 @@ public class PersistComponentsStep implements ComputationStep { } public void processFile(Component file, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) { - ComponentDto componentDto = createComponentDto(reportComponent, file); + ComponentDto componentDto = createComponentDto(file); componentDto.setScope(Scopes.FILE); componentDto.setQualifier(getFileQualifier(reportComponent)); @@ -171,7 +172,7 @@ public class PersistComponentsStep implements ComputationStep { persistComponent(file.getRef(), componentDto, componentContext); } - private ComponentDto createComponentDto(BatchReport.Component reportComponent, Component component) { + private ComponentDto createComponentDto(Component component) { String componentKey = component.getKey(); String componentUuid = component.getUuid(); @@ -241,12 +242,10 @@ public class PersistComponentsStep implements ComputationStep { } private static class ComponentContext { - private final BatchReportReader reportReader; private final Map componentDtosByKey; private final DbSession dbSession; - public ComponentContext(BatchReportReader reportReader, DbSession dbSession, Map componentDtosByKey) { - this.reportReader = reportReader; + public ComponentContext(DbSession dbSession, Map componentDtosByKey) { this.componentDtosByKey = componentDtosByKey; this.dbSession = dbSession; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java index 3e9ed86b7f8..5c5ba306710 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java @@ -41,10 +41,12 @@ public class PersistDuplicationsStep implements ComputationStep { private final DbClient dbClient; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistDuplicationsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache) { + public PersistDuplicationsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -62,7 +64,6 @@ public class PersistDuplicationsStep implements ComputationStep { } private void recursivelyProcessComponent(DuplicationContext duplicationContext, int componentRef) { - BatchReportReader reportReader = duplicationContext.context().getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); List duplications = reportReader.readComponentDuplications(componentRef); if (!duplications.isEmpty()) { @@ -111,7 +112,7 @@ public class PersistDuplicationsStep implements ComputationStep { } else { if (duplicate.hasOtherFileRef()) { // Duplication is on a different file - BatchReport.Component duplicationComponent = duplicationContext.context().getReportReader().readComponent(duplicate.getOtherFileRef()); + BatchReport.Component duplicationComponent = reportReader.readComponent(duplicate.getOtherFileRef()); DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(duplicationComponent.getRef()); appendDuplication(xml, dbComponent.getKey(), duplicate); } else { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java index 1c7e7229b8f..aa8d40d295c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java @@ -37,11 +37,13 @@ public class PersistEventsStep implements ComputationStep { private final DbClient dbClient; private final System2 system2; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistEventsStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache) { + public PersistEventsStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.system2 = system2; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -57,7 +59,6 @@ public class PersistEventsStep implements ComputationStep { } private void recursivelyProcessComponent(DbSession session, ComputationContext context, int componentRef) { - BatchReportReader reportReader = context.getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); processEvents(session, component, context.getReportMetadata().getAnalysisDate()); saveVersionEvent(session, component, context.getReportMetadata().getAnalysisDate()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java index c9ec5efce69..b06f5a087ca 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java @@ -54,11 +54,13 @@ public class PersistFileSourcesStep implements ComputationStep { private final DbClient dbClient; private final System2 system2; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistFileSourcesStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache) { + public PersistFileSourcesStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.system2 = system2; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -85,7 +87,6 @@ public class PersistFileSourcesStep implements ComputationStep { } private void recursivelyProcessComponent(FileSourcesContext fileSourcesContext, int componentRef) { - BatchReportReader reportReader = fileSourcesContext.context.getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); if (component.getType().equals(Constants.ComponentType.FILE)) { CloseableIterator linesIterator = reportReader.readFileSource(componentRef); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java index cb83e6e2ec2..8c42e477423 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java @@ -48,12 +48,15 @@ public class PersistMeasuresStep implements ComputationStep { private final RuleCache ruleCache; private final MetricCache metricCache; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache, DbComponentsRefCache dbComponentsRefCache) { + public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache, + DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.ruleCache = ruleCache; this.metricCache = metricCache; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -71,7 +74,6 @@ public class PersistMeasuresStep implements ComputationStep { } private void recursivelyProcessComponent(DbSession dbSession, ComputationContext context, int componentRef) { - BatchReportReader reportReader = context.getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); List measures = reportReader.readComponentMeasures(componentRef); persistMeasures(dbSession, measures, component); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java index 6f3ca621fc2..1c794d58e0a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java @@ -48,16 +48,18 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep { private final MetricCache metricCache; private final System2 system; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; private long lastCommitTimestamp = 0L; public PersistNumberOfDaysSinceLastCommitStep(System2 system, DbClient dbClient, SourceLineIndex sourceLineIndex, MetricCache metricCache, - DbComponentsRefCache dbComponentsRefCache) { + DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.sourceLineIndex = sourceLineIndex; this.metricCache = metricCache; this.system = system; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -81,7 +83,6 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep { } private void recursivelyProcessComponent(ComputationContext context, int componentRef) { - BatchReportReader reportReader = context.getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); BatchReport.Changesets scm = reportReader.readChangesets(componentRef); processScm(scm); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java index c56388b1a2d..7fd436b36ee 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java @@ -49,6 +49,7 @@ public class PersistProjectLinksStep implements ComputationStep { private final DbClient dbClient; private final I18n i18n; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; private static final Map typesConverter = ImmutableMap.of( Constants.ComponentLinkType.HOME, ComponentLinkDto.TYPE_HOME_PAGE, @@ -58,10 +59,11 @@ public class PersistProjectLinksStep implements ComputationStep { Constants.ComponentLinkType.ISSUE, ComponentLinkDto.TYPE_ISSUE_TRACKER ); - public PersistProjectLinksStep(DbClient dbClient, I18n i18n, DbComponentsRefCache dbComponentsRefCache) { + public PersistProjectLinksStep(DbClient dbClient, I18n i18n, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.i18n = i18n; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -77,7 +79,6 @@ public class PersistProjectLinksStep implements ComputationStep { } private void recursivelyProcessComponent(DbSession session, ComputationContext context, int componentRef) { - BatchReportReader reportReader = context.getReportReader(); BatchReport.Component component = reportReader.readComponent(componentRef); processLinks(session, component); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java index f7f6b4c136a..fe4a9e3cb08 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java @@ -61,11 +61,13 @@ public class PersistTestsStep implements ComputationStep { private final DbClient dbClient; private final System2 system; private final DbComponentsRefCache dbComponentsRefCache; + private final BatchReportReader reportReader; - public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache) { + public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) { this.dbClient = dbClient; this.system = system; this.dbComponentsRefCache = dbComponentsRefCache; + this.reportReader = reportReader; } @Override @@ -91,7 +93,6 @@ public class PersistTestsStep implements ComputationStep { private class TestDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor { final DbSession session; - final BatchReportReader reader; final DbComponentsRefCache dbComponentsRefCache; final Map existingFileSourcesByUuid; final String projectUuid; @@ -101,7 +102,6 @@ public class PersistTestsStep implements ComputationStep { super(Component.Type.FILE, Order.PRE_ORDER); this.session = session; this.dbComponentsRefCache = dbComponentsRefCache; - this.reader = context.getReportReader(); this.existingFileSourcesByUuid = new HashMap<>(); this.projectUuid = context.getRoot().getUuid(); session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject", @@ -117,7 +117,7 @@ public class PersistTestsStep implements ComputationStep { @Override public void visitFile(Component file) { - BatchReport.Component batchComponent = reader.readComponent(file.getRef()); + BatchReport.Component batchComponent = reportReader.readComponent(file.getRef()); if (batchComponent.getIsTest()) { persistTestResults(batchComponent); } @@ -188,7 +188,7 @@ public class PersistTestsStep implements ComputationStep { private Multimap buildDbTests(BatchReport.Component component) { Multimap tests = ArrayListMultimap.create(); - try (CloseableIterator testIterator = reader.readTests(component.getRef())) { + try (CloseableIterator testIterator = reportReader.readTests(component.getRef())) { while (testIterator.hasNext()) { BatchReport.Test batchTest = testIterator.next(); FileSourceDb.Test.Builder dbTest = FileSourceDb.Test.newBuilder(); @@ -220,7 +220,7 @@ public class PersistTestsStep implements ComputationStep { private Table loadCoverageDetails(int testFileRef) { Table nameToCoveredFiles = HashBasedTable.create(); - try (CloseableIterator coverageIterator = reader.readCoverageDetails(testFileRef)) { + try (CloseableIterator coverageIterator = reportReader.readCoverageDetails(testFileRef)) { while (coverageIterator.hasNext()) { BatchReport.CoverageDetail batchCoverageDetail = coverageIterator.next(); for (BatchReport.CoverageDetail.CoveredFile batchCoveredFile : batchCoverageDetail.getCoveredFileList()) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStep.java index 4249a7097d7..406f50d2c4b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStep.java @@ -41,16 +41,17 @@ import org.sonar.server.db.DbClient; public class PopulateComponentsUuidAndKeyStep implements ComputationStep { private final DbClient dbClient; + private final BatchReportReader reportReader; - public PopulateComponentsUuidAndKeyStep(DbClient dbClient) { + public PopulateComponentsUuidAndKeyStep(DbClient dbClient, BatchReportReader reportReader) { this.dbClient = dbClient; + this.reportReader = reportReader; } @Override public void execute(ComputationContext context) { DbSession session = dbClient.openSession(false); try { - BatchReportReader reportReader = context.getReportReader(); String branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null; BatchReport.Component project = reportReader.readComponent(context.getReportMetadata().getRootComponentRef()); String projectKey = ComponentKeys.createKey(project.getKey(), branch); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java index 3586229fce8..5a9ca7ff37a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java @@ -20,8 +20,12 @@ package org.sonar.server.computation.step; import com.google.common.collect.ImmutableSet; +import java.util.Date; +import java.util.Map; +import java.util.Set; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent; import org.sonar.server.computation.issue.IssueCache; @@ -34,10 +38,6 @@ import org.sonar.server.issue.notification.NewIssuesStatistics; import org.sonar.server.notifications.NotificationService; import org.sonar.server.util.CloseableIterator; -import java.util.Date; -import java.util.Map; -import java.util.Set; - /** * Reads issues from disk cache and send related notifications. For performance reasons, * the standard notification DB queue is not used as a temporary storage. Notifications @@ -53,14 +53,16 @@ public class SendIssueNotificationsStep implements ComputationStep { private final RuleCache rules; private final DbComponentsRefCache dbComponentsRefCache; private final NotificationService service; + private final BatchReportReader reportReader; private NewIssuesNotificationFactory newIssuesNotificationFactory; public SendIssueNotificationsStep(IssueCache issueCache, RuleCache rules, DbComponentsRefCache dbComponentsRefCache, NotificationService service, - NewIssuesNotificationFactory newIssuesNotificationFactory) { + BatchReportReader reportReader, NewIssuesNotificationFactory newIssuesNotificationFactory) { this.issueCache = issueCache; this.rules = rules; this.dbComponentsRefCache = dbComponentsRefCache; this.service = service; + this.reportReader = reportReader; this.newIssuesNotificationFactory = newIssuesNotificationFactory; } @@ -75,7 +77,7 @@ public class SendIssueNotificationsStep implements ComputationStep { private void doExecute(ComputationContext context, DbComponent project) { NewIssuesStatistics newIssuesStats = new NewIssuesStatistics(); CloseableIterator issues = issueCache.traverse(); - String projectName = context.getReportReader().readComponent(context.getReportMetadata().getRootComponentRef()).getName(); + String projectName = reportReader.readComponent(context.getReportMetadata().getRootComponentRef()).getName(); try { while (issues.hasNext()) { DefaultIssue issue = issues.next(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationServiceTest.java index 6e0c2781ba8..eaeaa3dc09f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationServiceTest.java @@ -19,40 +19,28 @@ */ package org.sonar.server.computation; +import com.google.common.collect.ImmutableList; import java.io.File; import java.io.IOException; import java.util.Arrays; -import org.apache.commons.io.FileUtils; +import java.util.Collections; import org.apache.commons.lang.RandomStringUtils; import org.junit.Before; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.utils.System2; -import org.sonar.api.utils.ZipUtils; -import org.sonar.api.utils.internal.JUnitTempFolder; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.batch.protocol.Constants; import org.sonar.batch.protocol.output.BatchReport; -import org.sonar.batch.protocol.output.BatchReportWriter; import org.sonar.core.computation.db.AnalysisReportDto; import org.sonar.core.computation.db.AnalysisReportDto.Status; -import org.sonar.core.persistence.DbTester; -import org.sonar.server.activity.Activity; -import org.sonar.server.activity.ActivityService; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.component.db.SnapshotDao; +import org.sonar.server.computation.activity.CEActivityManager; +import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.language.LanguageRepository; import org.sonar.server.computation.step.ComputationStep; import org.sonar.server.computation.step.ComputationSteps; import org.sonar.server.db.DbClient; -import org.sonar.server.properties.ProjectSettingsFactory; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -62,75 +50,44 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) public class ComputationServiceTest { - @ClassRule - public static DbTester dbTester = new DbTester(); - @Rule - public JUnitTempFolder tempFolder = new JUnitTempFolder(); - + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); @Rule public LogTester logTester = new LogTester(); - @Captor - ArgumentCaptor activityArgumentCaptor; - ComputationStep projectStep1 = mockStep(); ComputationStep projectStep2 = mockStep(); ComputationSteps steps = mock(ComputationSteps.class); - ActivityService activityService = mock(ActivityService.class); + CEActivityManager activityManager = mock(CEActivityManager.class); System2 system = mock(System2.class); + AnalysisReportDto dto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(Status.PENDING); ComputationService sut; - ProjectSettingsFactory settingsFactory = mock(ProjectSettingsFactory.class, Mockito.RETURNS_DEEP_STUBS); @Before - public void setUp() { - dbTester.truncateTables(); - DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao(system)); - sut = new ComputationService(dbClient, steps, activityService, tempFolder, system, mock(LanguageRepository.class)); - } - - @Test - public void process_new_project() throws Exception { - logTester.setLevel(LoggerLevel.INFO); - - when(steps.orderedSteps()).thenReturn(Arrays.asList(projectStep1, projectStep2)); - AnalysisReportDto dto = newDefaultReport(); - File zip = generateZip(); - - sut.process(new ReportQueue.Item(dto, zip)); - - // report is integrated -> status is set to SUCCESS - assertThat(dto.getStatus()).isEqualTo(Status.SUCCESS); - assertThat(dto.getFinishedAt()).isNotNull(); - - // one info log at the end - assertThat(logTester.logs(LoggerLevel.INFO)).hasSize(1); - assertThat(logTester.logs(LoggerLevel.INFO).get(0)).startsWith("Analysis of project P1 (report 1) (done) | time="); - - // execute only the steps supporting the project qualifier - verify(projectStep1).execute(any(ComputationContext.class)); - verify(projectStep2).execute(any(ComputationContext.class)); - verify(activityService).save(activityArgumentCaptor.capture()); + public void setUp() throws IOException { + reportReader.setMetadata(BatchReport.Metadata.newBuilder() + .setRootComponentRef(1) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .setKey("project key") + .setName("Project name") + .build()); - assertThat(activityArgumentCaptor.getValue().getType()).isEqualTo(Activity.Type.ANALYSIS_REPORT); - assertThat(activityArgumentCaptor.getValue().getAction()).isEqualTo("LOG_ANALYSIS_REPORT"); - assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectKey", "P1"); + sut = new ComputationService(new ReportQueue.Item(dto, new File("Do_not_care")), steps, activityManager, system, + reportReader, mock(DbClient.class), mock(LanguageRepository.class)); } @Test - public void process_existing_project() throws Exception { - dbTester.prepareDbUnit(getClass(), "shared.xml"); - + public void process_new_project() throws Exception { logTester.setLevel(LoggerLevel.INFO); - when(steps.orderedSteps()).thenReturn(Arrays.asList(projectStep1, projectStep2)); - AnalysisReportDto dto = newDefaultReport(); - File zip = generateZip(); + when(steps.instances()).thenReturn(Arrays.asList(projectStep1, projectStep2)); - sut.process(new ReportQueue.Item(dto, zip)); + sut.process(); // report is integrated -> status is set to SUCCESS assertThat(dto.getStatus()).isEqualTo(Status.SUCCESS); @@ -143,41 +100,30 @@ public class ComputationServiceTest { // execute only the steps supporting the project qualifier verify(projectStep1).execute(any(ComputationContext.class)); verify(projectStep2).execute(any(ComputationContext.class)); - verify(activityService).save(activityArgumentCaptor.capture()); - - assertThat(activityArgumentCaptor.getValue().getType()).isEqualTo(Activity.Type.ANALYSIS_REPORT); - assertThat(activityArgumentCaptor.getValue().getAction()).isEqualTo("LOG_ANALYSIS_REPORT"); - assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectKey", "P1"); - assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectName", "Project 1"); - assertThat(activityArgumentCaptor.getValue().getData().get("projectUuid")).isEqualTo("ABCD"); - } - - private AnalysisReportDto newDefaultReport() { - return AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(Status.PENDING); + verify(activityManager).saveActivity(dto); } @Test public void debug_logs() throws Exception { + when(steps.instances()).thenReturn(Collections.emptyList()); logTester.setLevel(LoggerLevel.DEBUG); - AnalysisReportDto dto = newDefaultReport(); - File zip = generateZip(); - sut.process(new ReportQueue.Item(dto, zip)); + sut.process(); assertThat(logTester.logs(LoggerLevel.DEBUG)).isNotEmpty(); } @Test - public void fail_if_corrupted_zip() throws Exception { - AnalysisReportDto dto = newDefaultReport(); - File zip = tempFolder.newFile(); - FileUtils.write(zip, "not a file"); + public void fail_if_step_throws_error() throws Exception { + String errorMessage = "Failed to unzip"; + when(steps.instances()).thenReturn(ImmutableList.of(projectStep1)); + doThrow(new IllegalStateException(errorMessage)).when(projectStep1).execute(any(ComputationContext.class)); try { - sut.process(new ReportQueue.Item(dto, zip)); + sut.process(); fail(); } catch (IllegalStateException e) { - assertThat(e.getMessage()).startsWith("Fail to unzip " + zip.getAbsolutePath() + " into "); + assertThat(e.getMessage()).isEqualTo(errorMessage); assertThat(dto.getStatus()).isEqualTo(Status.FAILED); assertThat(dto.getFinishedAt()).isNotNull(); } @@ -185,14 +131,11 @@ public class ComputationServiceTest { @Test public void step_error() throws Exception { - when(steps.orderedSteps()).thenReturn(Arrays.asList(projectStep1)); + when(steps.instances()).thenReturn(Arrays.asList(projectStep1)); doThrow(new IllegalStateException("pb")).when(projectStep1).execute(any(ComputationContext.class)); - AnalysisReportDto dto = newDefaultReport(); - File zip = generateZip(); - try { - sut.process(new ReportQueue.Item(dto, zip)); + sut.process(); fail(); } catch (IllegalStateException e) { assertThat(e.getMessage()).isEqualTo("pb"); @@ -207,27 +150,4 @@ public class ComputationServiceTest { return step; } - private File generateZip() throws IOException { - return generateZip(110L); - } - - private File generateZip(long snapshotId) throws IOException { - File dir = tempFolder.newDir(); - BatchReportWriter writer = new BatchReportWriter(dir); - writer.writeMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey("PROJECT_KEY") - .setAnalysisDate(150000000L) - .setSnapshotId(snapshotId) - .build()); - writer.writeComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .setKey("PROJECT_KEY") - .setSnapshotId(snapshotId) - .build()); - File zip = tempFolder.newFile(); - ZipUtils.zipDir(dir, zip); - return zip; - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/activity/CEActivityManagerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/activity/CEActivityManagerTest.java new file mode 100644 index 00000000000..82b267fcf14 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/activity/CEActivityManagerTest.java @@ -0,0 +1,86 @@ +/* + * 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.activity; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.ArgumentCaptor; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.activity.Activity; +import org.sonar.server.activity.ActivityService; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@Category(DbTests.class) +public class CEActivityManagerTest { + @ClassRule + public static DbTester dbTester = new DbTester(); + + ArgumentCaptor activityArgumentCaptor = ArgumentCaptor.forClass(Activity.class); + + AnalysisReportDto reportDto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(AnalysisReportDto.Status.PENDING); + + ActivityService activityService = mock(ActivityService.class); + CEActivityManager underTest; + + @Before + public void setup() throws Exception { + dbTester.truncateTables(); + DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao()); + + underTest = new CEActivityManager(activityService, dbClient); + } + + @Test + public void process_existing_project() throws Exception { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + + underTest.saveActivity(reportDto); + + verify(activityService).save(activityArgumentCaptor.capture()); + + assertThat(activityArgumentCaptor.getValue().getType()).isEqualTo(Activity.Type.ANALYSIS_REPORT); + assertThat(activityArgumentCaptor.getValue().getAction()).isEqualTo("LOG_ANALYSIS_REPORT"); + assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectKey", "P1"); + assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectName", "Project 1"); + assertThat(activityArgumentCaptor.getValue().getData().get("projectUuid")).isEqualTo("ABCD"); + } + + @Test + public void process_new_project() throws Exception { + underTest.saveActivity(reportDto); + + // execute only the steps supporting the project qualifier + verify(activityService).save(activityArgumentCaptor.capture()); + + assertThat(activityArgumentCaptor.getValue().getType()).isEqualTo(Activity.Type.ANALYSIS_REPORT); + assertThat(activityArgumentCaptor.getValue().getAction()).isEqualTo("LOG_ANALYSIS_REPORT"); + assertThat(activityArgumentCaptor.getValue().getData()).containsEntry("projectKey", "P1"); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java index 4c48e205bc4..baa3f16435b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.junit.rules.TestRule; import org.junit.runner.Description; @@ -100,6 +101,7 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader { } @Override + @CheckForNull public BatchReport.Changesets readChangesets(int componentRef) { return changesets.get(componentRef); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java new file mode 100644 index 00000000000..d25761fde94 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java @@ -0,0 +1,58 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.computation.batch; + +import java.io.File; +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.internal.JUnitTempFolder; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.server.computation.ReportQueue; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; + +public class ReportExtractorTest { + + @Rule + public JUnitTempFolder tempFolder = new JUnitTempFolder(); + + ReportExtractor underTest = new ReportExtractor(tempFolder); + + + @Test + public void fail_if_corrupted_zip() throws Exception { + AnalysisReportDto dto = newDefaultReport(); + File zip = tempFolder.newFile(); + FileUtils.write(zip, "not a file"); + + try { + underTest.extractReportInDir(new ReportQueue.Item(dto, zip)); + fail(); + } catch (IllegalStateException e) { + assertThat(e.getMessage()).startsWith("Fail to unzip " + zip.getAbsolutePath() + " into "); + } + } + + private AnalysisReportDto newDefaultReport() { + return AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(AnalysisReportDto.Status.PENDING); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java index f4e0ff6145a..44759320a3e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueComputationTest.java @@ -21,6 +21,8 @@ package org.sonar.server.computation.issue; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterators; +import java.io.IOException; +import java.util.Arrays; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -37,13 +39,11 @@ import org.sonar.api.utils.log.LogTester; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.rule.RuleDto; import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.component.ProjectSettingsRepository; import org.sonar.server.user.index.UserDoc; import org.sonar.server.user.index.UserIndex; -import java.io.IOException; -import java.util.Arrays; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; @@ -56,9 +56,10 @@ public class IssueComputationTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - @Rule public LogTester logTester = new LogTester(); + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); IssueComputation sut; @@ -86,7 +87,7 @@ public class IssueComputationTest { outputIssues = new IssueCache(temp.newFile(), System2.INSTANCE); projectSettings = new Settings(); when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(projectSettings); - sut = new IssueComputation(ruleCache, lineCache, scmAccountCache, outputIssues, userIndex, projectSettingsRepository); + sut = new IssueComputation(ruleCache, lineCache, scmAccountCache, outputIssues, userIndex, projectSettingsRepository, reportReader); } @After diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java index 188773c5c41..72cf7bb897b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java @@ -20,7 +20,11 @@ package org.sonar.server.computation.step; +import com.google.common.collect.Lists; +import java.util.List; import org.junit.Test; +import org.sonar.core.platform.ComponentContainer; +import org.sonar.server.computation.container.CEContainer; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -30,7 +34,8 @@ public class ComputationStepsTest { @Test public void ordered_steps() { - ComputationSteps registry = new ComputationSteps( + CEContainer ceContainer = new CEContainer(new ComponentContainer()); + ceContainer.add( // unordered mock(ApplyPermissionsStep.class), mock(ParseReportStep.class), @@ -51,20 +56,21 @@ public class ComputationStepsTest { mock(IndexTestsStep.class), mock(PopulateComponentsUuidAndKeyStep.class), mock(PersistComponentsStep.class), - mock(IndexTestsStep.class), mock(QualityProfileEventsStep.class), mock(ValidateProjectStep.class) ); + ComputationSteps computationSteps = new ComputationSteps(ceContainer); - assertThat(registry.orderedSteps()).hasSize(21); - assertThat(registry.orderedSteps().get(0)).isInstanceOf(PopulateComponentsUuidAndKeyStep.class); - assertThat(registry.orderedSteps().get(20)).isInstanceOf(SendIssueNotificationsStep.class); + List steps = Lists.newArrayList(computationSteps.instances()); + assertThat(steps).hasSize(21); + assertThat(steps.get(0)).isInstanceOf(PopulateComponentsUuidAndKeyStep.class); + assertThat(steps.get(20)).isInstanceOf(SendIssueNotificationsStep.class); } @Test public void fail_if_a_step_is_not_registered_in_picocontainer() { try { - new ComputationSteps(mock(ParseReportStep.class)); + Lists.newArrayList(new ComputationSteps(new CEContainer(new ComponentContainer())).instances()); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageContaining("Component not found"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java index 58a94e0fa69..ccf6b1be883 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java @@ -20,27 +20,22 @@ package org.sonar.server.computation.step; +import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.sonar.api.config.Settings; -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.batch.FileBatchReportReader; +import org.sonar.server.computation.batch.BatchReportReaderRule; +import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent; -import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.component.DumbComponent; import org.sonar.server.computation.language.LanguageRepository; import org.sonar.server.db.DbClient; -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; @@ -50,7 +45,7 @@ public class IndexComponentsStepTest extends BaseStepTest { private static final String PROJECT_KEY = "PROJECT_KEY"; @Rule - public TemporaryFolder temp = new TemporaryFolder(); + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); ResourceIndexerDao resourceIndexerDao = mock(ResourceIndexerDao.class); DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache(); @@ -60,15 +55,14 @@ public class IndexComponentsStepTest extends BaseStepTest { 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() + reportReader.setMetadata(BatchReport.Metadata.newBuilder() .setRootComponentRef(1) .build()); ComponentDto project = mock(ComponentDto.class); when(project.getId()).thenReturn(123L); - ComputationContext context = new ComputationContext(new FileBatchReportReader(new BatchReportReader(reportDir)), PROJECT_KEY, new Settings(), mock(DbClient.class), ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), mock(LanguageRepository.class)); + ComputationContext context = new ComputationContext(reportReader, PROJECT_KEY, new Settings(), mock(DbClient.class), ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), + mock(LanguageRepository.class)); sut.execute(context); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java index 24a746723c6..1d7586d2ae7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java @@ -19,7 +19,6 @@ */ package org.sonar.server.computation.step; -import java.io.File; import java.sql.Connection; import java.util.List; import org.elasticsearch.search.SearchHit; @@ -27,14 +26,12 @@ 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.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.DbTester; import org.sonar.server.computation.ComputationContext; -import org.sonar.server.computation.batch.FileBatchReportReader; +import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.DumbComponent; @@ -54,14 +51,12 @@ public class IndexSourceLinesStepTest extends BaseStepTest { private static final String PROJECT_KEY = "PROJECT_KEY"; - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - @ClassRule public static DbTester dbTester = new DbTester(); - @ClassRule public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings())); + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); DbClient dbClient; @@ -89,14 +84,12 @@ public class IndexSourceLinesStepTest extends BaseStepTest { FileSourceTesting.updateDataColumn(connection, "FILE1_UUID", FileSourceTesting.newRandomData(1).build()); connection.close(); - File reportDir = temp.newFolder(); - BatchReportWriter writer = new BatchReportWriter(reportDir); - writer.writeMetadata(BatchReport.Metadata.newBuilder() + reportReader.setMetadata(BatchReport.Metadata.newBuilder() .setRootComponentRef(1) .build()); - step().execute(new ComputationContext(new FileBatchReportReader(new BatchReportReader(reportDir)), PROJECT_KEY, new Settings(), dbClient, - ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), mock(LanguageRepository.class))); + step().execute(new ComputationContext(reportReader, PROJECT_KEY, new Settings(), dbClient, + ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), mock(LanguageRepository.class))); List docs = esTester.getDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE); assertThat(docs).hasSize(1); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java index 2d28cabfbea..edb4ff90efa 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java @@ -20,7 +20,6 @@ package org.sonar.server.computation.step; -import java.io.File; import java.sql.Connection; import java.util.List; import org.elasticsearch.search.SearchHit; @@ -28,14 +27,11 @@ 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.computation.ComputationContext; -import org.sonar.server.computation.batch.FileBatchReportReader; +import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.DumbComponent; @@ -53,17 +49,14 @@ import static org.mockito.Mockito.mock; public class IndexTestsStepTest extends BaseStepTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - @ClassRule public static DbTester dbTester = new DbTester(); - @ClassRule public static EsTester esTester = new EsTester().addDefinitions(new TestIndexDefinition(new Settings())); + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); DbClient dbClient; - ComputationContext underTest; DbComponentsRefCache dbComponentsRefCache; @@ -90,13 +83,11 @@ public class IndexTestsStepTest extends BaseStepTest { TestTesting.updateDataColumn(connection, "FILE1_UUID", TestTesting.newRandomTests(1)); connection.close(); - File reportDir = temp.newFolder(); - BatchReportWriter writer = new BatchReportWriter(reportDir); - writer.writeMetadata(BatchReport.Metadata.newBuilder() + reportReader.setMetadata(BatchReport.Metadata.newBuilder() .setRootComponentRef(1) .build()); - step().execute(new ComputationContext(new FileBatchReportReader(new BatchReportReader(reportDir)), "PROJECT_KEY", new Settings(), dbClient, + step().execute(new ComputationContext(reportReader, "PROJECT_KEY", new Settings(), dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), mock(LanguageRepository.class))); List docs = esTester.getDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java index f4787434a23..c7574ebc8c7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java @@ -62,7 +62,7 @@ public class ParseReportStepTest extends BaseStepTest { IssueComputation issueComputation = mock(IssueComputation.class); - ParseReportStep sut = new ParseReportStep(issueComputation); + ParseReportStep sut = new ParseReportStep(issueComputation, reportReader); @Test public void extract_report_from_db_and_browse_components() throws Exception { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java index be55b3c03e8..cbe6093a88d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java @@ -76,7 +76,7 @@ public class PersistComponentsStepTest extends BaseStepTest { projectSettings = new Settings(); languageRepository = mock(LanguageRepository.class); dbComponentsRefCache = new DbComponentsRefCache(); - sut = new PersistComponentsStep(dbClient, dbComponentsRefCache); + sut = new PersistComponentsStep(dbClient, dbComponentsRefCache, reportReader); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java index 539d3a994a2..28cca616ef2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java @@ -82,7 +82,7 @@ public class PersistDuplicationsStepTest extends BaseStepTest { projectSettings = new Settings(); dbComponentsRefCache = new DbComponentsRefCache(); languageRepository = mock(LanguageRepository.class); - sut = new PersistDuplicationsStep(dbClient, dbComponentsRefCache); + sut = new PersistDuplicationsStep(dbClient, dbComponentsRefCache, reportReader); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java index c455396ee71..b7aa3f9228c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java @@ -83,7 +83,7 @@ public class PersistEventsStepTest extends BaseStepTest { languageRepository = mock(LanguageRepository.class); dbComponentsRefCache = new DbComponentsRefCache(); - step = new PersistEventsStep(dbClient, system2, dbComponentsRefCache); + step = new PersistEventsStep(dbClient, system2, dbComponentsRefCache, reportReader); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java index 10f1c69d330..3e07b59a062 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java @@ -99,7 +99,7 @@ public class PersistFileSourcesStepTest extends BaseStepTest { system2 = mock(System2.class); when(system2.now()).thenReturn(now); dbComponentsRefCache = new DbComponentsRefCache(); - sut = new PersistFileSourcesStep(dbClient, system2, dbComponentsRefCache); + sut = new PersistFileSourcesStep(dbClient, system2, dbComponentsRefCache, reportReader); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java index 661733feef6..49429676dcc 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java @@ -110,7 +110,7 @@ public class PersistMeasuresStepTest extends BaseStepTest { metricCache = new MetricCache(dbClient); session.commit(); - sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbComponentsRefCache); + sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbComponentsRefCache, reportReader); } @After diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java index 2cb1937fe29..16a16f913a4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java @@ -75,7 +75,7 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest { when(metricCache.get(anyString())).thenReturn(new MetricDto().setId(10)); dbComponentsRefCache = new DbComponentsRefCache(); - sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, dbComponentsRefCache); + sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, dbComponentsRefCache, reportReader); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java index 46a5c95cfd9..d273b04c686 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java @@ -88,7 +88,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest { when(i18n.message(Locale.ENGLISH, "project_links.issue", null)).thenReturn("Issues"); dbComponentsRefCache = new DbComponentsRefCache(); - step = new PersistProjectLinksStep(dbClient, i18n, dbComponentsRefCache); + step = new PersistProjectLinksStep(dbClient, i18n, dbComponentsRefCache, reportReader); } @Override @@ -110,26 +110,26 @@ public class PersistProjectLinksStepTest extends BaseStepTest { // project and 1 module reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .setAnalysisDate(150000000L) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .setAnalysisDate(150000000L) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .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()) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM_DEV).setHref("scm:git:git@github.com:SonarSource/sonar.git/sonar").build()) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.ISSUE).setHref("http://jira.sonarsource.com/").build()) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.CI).setHref("http://bamboo.ci.codehaus.org/browse/SONAR").build()) - .build()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .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()) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM_DEV).setHref("scm:git:git@github.com:SonarSource/sonar.git/sonar").build()) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.ISSUE).setHref("http://jira.sonarsource.com/").build()) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.CI).setHref("http://bamboo.ci.codehaus.org/browse/SONAR").build()) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(2) - .setType(Constants.ComponentType.MODULE) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar/server").build()) - .build()); + .setRef(2) + .setType(Constants.ComponentType.MODULE) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.SCM).setHref("https://github.com/SonarSource/sonar/server").build()) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -143,15 +143,15 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) - .build()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -165,15 +165,15 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.FILE) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) - .build()); + .setRef(1) + .setType(Constants.ComponentType.FILE) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -187,15 +187,15 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) - .build()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build()) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -209,14 +209,14 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .build()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -230,14 +230,14 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .build()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .build()); step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); @@ -251,16 +251,16 @@ public class PersistProjectLinksStepTest extends BaseStepTest { dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD")); reportReader.setMetadata(BatchReport.Metadata.newBuilder() - .setRootComponentRef(1) - .setProjectKey(PROJECT_KEY) - .build()); + .setRootComponentRef(1) + .setProjectKey(PROJECT_KEY) + .build()); reportReader.putComponent(BatchReport.Component.newBuilder() - .setRef(1) - .setType(Constants.ComponentType.PROJECT) - .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()); + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .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()); try { step.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(DumbComponent.DUMB_PROJECT), languageRepository)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java index 471c7623c36..259d740444d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java @@ -104,7 +104,7 @@ public class PersistTestsStepTest extends BaseStepTest { when(system2.now()).thenReturn(now); dbComponentsRefCache = new DbComponentsRefCache(); - sut = new PersistTestsStep(dbClient, system2, dbComponentsRefCache); + sut = new PersistTestsStep(dbClient, system2, dbComponentsRefCache, reportReader); initBasicReport(); @@ -227,8 +227,8 @@ public class PersistTestsStepTest extends BaseStepTest { public void aggregate_coverage_details() { reportReader.putTests(TEST_FILE_REF_1, Arrays.asList(newTest(1))); reportReader.putCoverageDetails(TEST_FILE_REF_1, Arrays.asList( - newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3), - newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4))); + newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3), + newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4))); sut.execute(new ComputationContext(reportReader, PROJECT_KEY, projectSettings, dbClient, ComponentTreeBuilders.from(root), languageRepository)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java index 385d00354be..c279f784df6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java @@ -74,7 +74,7 @@ public class PopulateComponentsUuidAndKeyStepTest extends BaseStepTest { dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao()); projectSettings = new Settings(); - sut = new PopulateComponentsUuidAndKeyStep(dbClient); + sut = new PopulateComponentsUuidAndKeyStep(dbClient, reportReader); } @After diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java index a6ffa61757b..8e2c17c2d9c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java @@ -76,7 +76,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { public void setUp() throws Exception { issueCache = new IssueCache(temp.newFile(), System2.INSTANCE); dbComponentsRefCache = new DbComponentsRefCache(); - sut = new SendIssueNotificationsStep(issueCache, ruleCache, dbComponentsRefCache, notifService, newIssuesNotificationFactory); + sut = new SendIssueNotificationsStep(issueCache, ruleCache, dbComponentsRefCache, notifService, reportReader, newIssuesNotificationFactory); dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID)); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ComputationServiceTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/activity/CEActivityManagerTest/shared.xml similarity index 93% rename from server/sonar-server/src/test/resources/org/sonar/server/computation/ComputationServiceTest/shared.xml rename to server/sonar-server/src/test/resources/org/sonar/server/computation/activity/CEActivityManagerTest/shared.xml index 885f3d251d7..2ac38c2fb0b 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/ComputationServiceTest/shared.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/activity/CEActivityManagerTest/shared.xml @@ -7,5 +7,5 @@ period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" scope="PRJ" qualifier="TRK" created_at="1225544280000" build_date="1225544280000" version="[null]" path="" - status="P" islast="false" depth="0"/> + status="P" islast="[false]" depth="0"/> diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java index 3f06b041ec1..e0bafcf8e9c 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java @@ -19,11 +19,10 @@ */ package org.sonar.core.platform; +import com.google.common.collect.Iterables; import java.util.Collection; import java.util.List; - import javax.annotation.Nullable; - import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.DefaultPicoContainer; @@ -32,13 +31,11 @@ import org.picocontainer.behaviors.OptInCaching; import org.picocontainer.lifecycle.ReflectionLifecycleStrategy; import org.picocontainer.monitors.NullComponentMonitor; import org.sonar.api.batch.BatchSide; -import org.sonar.api.server.ServerSide; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.server.ServerSide; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; -import com.google.common.collect.Iterables; - @BatchSide @ServerSide public class ComponentContainer { @@ -66,8 +63,15 @@ public class ComponentContainer { * Create child container */ protected ComponentContainer(ComponentContainer parent) { + this(parent.pico.makeChildContainer(), parent); + } + + /** + * Create child container + */ + protected ComponentContainer(MutablePicoContainer picoContainer, ComponentContainer parent) { this.parent = parent; - this.pico = parent.pico.makeChildContainer(); + this.pico = picoContainer; this.parent.child = this; this.propertyDefinitions = parent.propertyDefinitions; this.componentKeys = new ComponentKeys(); -- 2.39.5