aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-02-25 22:22:20 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-03-02 11:02:08 +0100
commitaf3d0b3c6b555616b3f6207620dd92360a653996 (patch)
tree3f48b9d5324e89e40590a7b67c5cf514ef54839e /server
parent4ea0dd1c85069c253e4dbdc1b7c6e203b5beb082 (diff)
downloadsonarqube-af3d0b3c6b555616b3f6207620dd92360a653996.tar.gz
sonarqube-af3d0b3c6b555616b3f6207620dd92360a653996.zip
Refactor table ANALYSIS_REPORTS because of MySQL packet size limitation
* do not store report zip in table ANALYSIS_REPORTS but in FS dir {home}/data/analysis * do not store snapshot id in table but in protobuf report
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueue.java130
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java (renamed from server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java)32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContext.java30
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ComputationService.java59
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThread.java55
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThreadLauncher.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ReportActivity.java (renamed from server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportLog.java)4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueue.java188
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueueCleaner.java (renamed from server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueueCleaner.java)28
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/db/AnalysisReportDao.java88
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/ParseReportStep.java62
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/SwitchSnapshotStep.java22
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWebService.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java29
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java205
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueMediumTest.java179
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ComputationContainerTest.java (renamed from server/sonar-server/src/test/java/org/sonar/server/computation/ComputationComponentsTest.java)12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ComputationServiceTest.java132
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadLauncherTest.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadTest.java61
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ReportActivityTest.java (renamed from server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportLogMediumTest.java)42
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueCleanerTest.java (renamed from server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueCleanerTest.java)35
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueTest.java205
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/db/AnalysisReportDaoTest.java55
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/BaseStepTest.java42
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java21
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java40
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexViewsStepTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ParseReportStepTest.java56
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepMediumTest.java144
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java23
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java27
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java26
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/SwitchSnapshotStepTest.java19
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java28
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWebServiceTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java42
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java1
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/ComputationServiceTest/shared.xml2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/any-analysis-reports.xml11
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml8
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/insert-result.xml6
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_analysis_report.xml5
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis.xml20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis_but_another_busy_on_same_project.xml20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_busy_report_analysis.xml11
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml11
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_oldest_pending.xml12
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select.xml11
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select_oldest_available_report_with_working_reports_older.xml29
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/three_analysis_reports.xml11
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending-result.xml9
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending.xml9
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/ws/SubmitReportWsActionTest/submit_report.json3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/796_add_uuid_to_analysis_reports.rb32
60 files changed, 1207 insertions, 1212 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueue.java b/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueue.java
deleted file mode 100644
index 3c57b1c5e91..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueue.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.computation;
-
-import org.sonar.api.ServerComponent;
-import org.sonar.api.utils.System2;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.user.UserSession;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import java.io.InputStream;
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING;
-
-public class AnalysisReportQueue implements ServerComponent {
-
- private final DbClient dbClient;
- private final System2 system2;
-
- public AnalysisReportQueue(DbClient dbClient, System2 system2) {
- this.dbClient = dbClient;
- this.system2 = system2;
- }
-
- /**
- * Adds a report to the queue and returns the generated key
- */
- public String add(String projectKey, Long snapshotId, @Nullable InputStream reportData) {
- // TODO security must not be handled here
- UserSession.get().checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
-
- AnalysisReportDto report = newPendingAnalysisReport(projectKey)
- .setSnapshotId(snapshotId)
- .setData(reportData);
- DbSession session = dbClient.openSession(false);
- try {
- checkThatProjectExistsInDatabase(projectKey, session);
- return insertInDb(report, session).getKey();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- private AnalysisReportDto newPendingAnalysisReport(String projectKey) {
- return new AnalysisReportDto()
- .setProjectKey(projectKey)
- .setStatus(PENDING);
- }
-
- private void checkThatProjectExistsInDatabase(String projectKey, DbSession session) {
- dbClient.componentDao().getByKey(session, projectKey);
- }
-
- private AnalysisReportDto insertInDb(AnalysisReportDto reportTemplate, DbSession session) {
- AnalysisReportDto report = dbClient.analysisReportDao().insert(session, reportTemplate);
- session.commit();
-
- return report;
- }
-
- public void remove(AnalysisReportDto report) {
- checkArgument(report.getStatus().isInFinalState());
-
- DbSession session = dbClient.openSession(false);
- try {
- report.setFinishedAt(system2.now());
- dbClient.analysisReportDao().delete(session, report.getId());
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @CheckForNull
- public AnalysisReportDto pop() {
- DbSession session = dbClient.openSession(false);
- try {
- return dbClient.analysisReportDao().pop(session);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- public List<AnalysisReportDto> findByProjectKey(String projectKey) {
- DbSession session = dbClient.openSession(false);
- try {
- return dbClient.analysisReportDao().selectByProjectKey(session, projectKey);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- /**
- * All the reports of the queue, whatever the status
- */
- public List<AnalysisReportDto> all() {
- DbSession session = dbClient.openSession(false);
- try {
- return dbClient.analysisReportDao().selectAll(session);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java
index a26e06d99d4..21e9e7c9cb2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContainer.java
@@ -19,25 +19,45 @@
*/
package org.sonar.server.computation;
+import org.sonar.api.platform.ComponentContainer;
import org.sonar.core.issue.db.UpdateConflictResolver;
-import org.sonar.server.computation.issue.*;
+import org.sonar.server.computation.issue.IssueCache;
+import org.sonar.server.computation.issue.IssueComputation;
+import org.sonar.server.computation.issue.RuleCache;
+import org.sonar.server.computation.issue.RuleCacheLoader;
+import org.sonar.server.computation.issue.ScmAccountCache;
+import org.sonar.server.computation.issue.ScmAccountCacheLoader;
+import org.sonar.server.computation.issue.SourceLinesCache;
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 ComputationComponents {
+public class ComputationContainer {
- private ComputationComponents() {
- // only static stuff
+ public void execute(ReportQueue.Item item) {
+ ComponentContainer container = Platform.getInstance().getContainer();
+ ComponentContainer child = container.createChild();
+ child.addSingletons(componentClasses());
+ child.addSingletons(ComputationSteps.orderedStepClasses());
+ child.startComponents();
+ try {
+ child.getComponentByType(ComputationService.class).process(item);
+ } finally {
+ child.stopComponents();
+ // TODO not possible to have multiple children -> will be
+ // a problem when we will have multiple concurrent computation workers
+ container.removeChild();
+ }
}
/**
- * List of all objects to be injected in the picocontainer dedicated to computation stack.
+ * List of all objects to be injected in the picocontainer dedicated to computation stack.
* Does not contain the steps declared in {@link org.sonar.server.computation.step.ComputationSteps#orderedStepClasses()}.
*/
- public static List nonStepComponents() {
+ static List componentClasses() {
return Arrays.asList(
ComputationService.class,
ComputationSteps.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContext.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContext.java
index a7709c8e139..2e314220aca 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContext.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationContext.java
@@ -20,41 +20,33 @@
package org.sonar.server.computation;
-import com.google.common.base.Preconditions;
import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.step.ParseReportStep;
public class ComputationContext {
- private final AnalysisReportDto reportDto;
+ private final BatchReportReader reportReader;
private final ComponentDto project;
- /**
- * Cache of analysis date as it can be accessed several times
- */
- private BatchReport.Metadata reportMetadata = null;
+ // cache of metadata as it's frequently accessed
+ private final BatchReport.Metadata reportMetadata;
- public ComputationContext(AnalysisReportDto reportDto, ComponentDto project) {
- this.reportDto = reportDto;
+ public ComputationContext(BatchReportReader reportReader, ComponentDto project) {
+ this.reportReader = reportReader;
this.project = project;
+ this.reportMetadata = reportReader.readMetadata();
}
- public AnalysisReportDto getReportDto() {
- return reportDto;
+ public BatchReport.Metadata getReportMetadata() {
+ return reportMetadata;
}
public ComponentDto getProject() {
return project;
}
- public BatchReport.Metadata getReportMetadata() {
- Preconditions.checkState(reportMetadata != null, "Report metadata is available after execution of " + ParseReportStep.class);
- return reportMetadata;
- }
-
- public void setReportMetadata(BatchReport.Metadata m) {
- this.reportMetadata = m;
+ public BatchReportReader getReportReader() {
+ return reportReader;
}
}
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 77ee77fb272..8787e16ec94 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
@@ -21,12 +21,16 @@
package org.sonar.server.computation;
import com.google.common.base.Throwables;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.sonar.api.ServerComponent;
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.batch.protocol.output.BatchReportReader;
import org.sonar.core.activity.Activity;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.computation.db.AnalysisReportDto;
@@ -37,6 +41,9 @@ import org.sonar.server.computation.step.ComputationStep;
import org.sonar.server.computation.step.ComputationSteps;
import org.sonar.server.db.DbClient;
+import java.io.File;
+import java.io.IOException;
+
public class ComputationService implements ServerComponent {
private static final Logger LOG = Loggers.get(ComputationService.class);
@@ -44,43 +51,67 @@ public class ComputationService implements ServerComponent {
private final DbClient dbClient;
private final ComputationSteps steps;
private final ActivityService activityService;
+ private final TempFolder tempFolder;
+ private final System2 system;
- public ComputationService(DbClient dbClient, ComputationSteps steps, ActivityService activityService) {
+ public ComputationService(DbClient dbClient, ComputationSteps steps, ActivityService activityService,
+ TempFolder tempFolder, System2 system) {
this.dbClient = dbClient;
this.steps = steps;
this.activityService = activityService;
+ this.tempFolder = tempFolder;
+ this.system = system;
}
- public void process(AnalysisReportDto report) {
- Profiler profiler = Profiler.create(LOG).startInfo(String.format(
- "#%s - %s - processing analysis report", report.getId(), report.getProjectKey()));
+ public void process(ReportQueue.Item item) {
+ Profiler profiler = Profiler.create(LOG).startDebug(String.format(
+ "Analysis of project %s (report %d)", item.dto.getProjectKey(), item.dto.getId()));
- ComponentDto project = loadProject(report);
+ ComponentDto project = loadProject(item);
try {
- ComputationContext context = new ComputationContext(report, project);
+ File reportDir = extractReportInDir(item);
+ BatchReportReader reader = new BatchReportReader(reportDir);
+ ComputationContext context = new ComputationContext(reader, project);
for (ComputationStep step : steps.orderedSteps()) {
if (ArrayUtils.contains(step.supportedProjectQualifiers(), context.getProject().qualifier())) {
- Profiler stepProfiler = Profiler.create(LOG).startInfo(step.getDescription());
+ Profiler stepProfiler = Profiler.createIfDebug(LOG).startDebug(step.getDescription());
step.execute(context);
- stepProfiler.stopInfo();
+ stepProfiler.stopDebug();
}
}
- report.succeed();
+ item.dto.succeed();
} catch (Exception e) {
- report.fail();
+ item.dto.fail();
throw Throwables.propagate(e);
} finally {
- logActivity(report, project);
+ item.dto.setFinishedAt(system.now());
+ logActivity(item.dto, project);
profiler.stopInfo();
}
}
- private ComponentDto loadProject(AnalysisReportDto report) {
+ 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 ComponentDto loadProject(ReportQueue.Item queueItem) {
DbSession session = dbClient.openSession(false);
try {
- return dbClient.componentDao().getByKey(session, report.getProjectKey());
+ return dbClient.componentDao().getByKey(session, queueItem.dto.getProjectKey());
} finally {
MyBatis.closeQuietly(session);
}
@@ -90,7 +121,7 @@ public class ComputationService implements ServerComponent {
DbSession session = dbClient.openSession(false);
try {
report.setFinishedAt(System2.INSTANCE.now());
- activityService.write(session, Activity.Type.ANALYSIS_REPORT, new AnalysisReportLog(report, project));
+ activityService.write(session, Activity.Type.ANALYSIS_REPORT, new ReportActivity(report, project));
session.commit();
} finally {
MyBatis.closeQuietly(session);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThread.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThread.java
index 07c9a23e3a0..e70b15feb73 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThread.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThread.java
@@ -20,67 +20,56 @@
package org.sonar.server.computation;
-
-import org.sonar.api.platform.ComponentContainer;
+import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.step.ComputationSteps;
-import org.sonar.server.platform.Platform;
/**
- * This thread pops queue of reports and processes the report if present
+ * This thread pops a report from the queue and integrate it.
*/
public class ComputationThread implements Runnable {
+
private static final Logger LOG = Loggers.get(ComputationThread.class);
- private final AnalysisReportQueue queue;
+ private final ReportQueue queue;
+ private final ComputationContainer container;
+
+ public ComputationThread(ReportQueue queue) {
+ this.queue = queue;
+ this.container = new ComputationContainer();
+ }
- public ComputationThread(AnalysisReportQueue queue) {
+ @VisibleForTesting
+ ComputationThread(ReportQueue queue, ComputationContainer container) {
this.queue = queue;
+ this.container = container;
}
@Override
public void run() {
- AnalysisReportDto report = null;
+ ReportQueue.Item item = null;
try {
- report = queue.pop();
+ item = queue.pop();
} catch (Exception e) {
LOG.error("Failed to pop the queue of analysis reports", e);
}
- if (report != null) {
+ if (item != null) {
try {
- process(report);
+ container.execute(item);
} catch (Exception e) {
LOG.error(String.format(
- "Failed to process analysis report %d of project %s", report.getId(), report.getProjectKey()), e);
+ "Failed to process analysis report %d of project %s", item.dto.getId(), item.dto.getProjectKey()), e);
} finally {
- removeSilentlyFromQueue(report);
+ removeSilentlyFromQueue(item);
}
}
}
- private void removeSilentlyFromQueue(AnalysisReportDto report) {
+ private void removeSilentlyFromQueue(ReportQueue.Item item) {
try {
- queue.remove(report);
+ queue.remove(item);
} catch (Exception e) {
- LOG.error(String.format("Failed to remove analysis report %d from queue", report.getId()), e);
- }
- }
-
- private void process(AnalysisReportDto report) {
- ComponentContainer container = Platform.getInstance().getContainer();
- ComponentContainer child = container.createChild();
- child.addSingletons(ComputationSteps.orderedStepClasses());
- child.addSingletons(ComputationComponents.nonStepComponents());
- child.startComponents();
- try {
- child.getComponentByType(ComputationService.class).process(report);
- } finally {
- child.stopComponents();
- // TODO not possible to have multiple children -> will be
- // a problem when we will have multiple concurrent computation workers
- container.removeChild();
+ LOG.error(String.format("Failed to remove analysis report %d from queue", item.dto.getId()), e);
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThreadLauncher.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThreadLauncher.java
index c19b80a0a7b..18bf2a35633 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThreadLauncher.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationThreadLauncher.java
@@ -36,14 +36,14 @@ public class ComputationThreadLauncher implements Startable, ServerComponent, Se
public static final String THREAD_NAME_PREFIX = "computation-";
- private final AnalysisReportQueue queue;
+ private final ReportQueue queue;
private final ScheduledExecutorService executorService;
private final long delayBetweenTasks;
private final long delayForFirstStart;
private final TimeUnit timeUnit;
- public ComputationThreadLauncher(AnalysisReportQueue queue) {
+ public ComputationThreadLauncher(ReportQueue queue) {
this.queue = queue;
this.executorService = Executors.newSingleThreadScheduledExecutor(newThreadFactory());
@@ -53,7 +53,7 @@ public class ComputationThreadLauncher implements Startable, ServerComponent, Se
}
@VisibleForTesting
- ComputationThreadLauncher(AnalysisReportQueue queue, long delayForFirstStart, long delayBetweenTasks, TimeUnit timeUnit) {
+ ComputationThreadLauncher(ReportQueue queue, long delayForFirstStart, long delayBetweenTasks, TimeUnit timeUnit) {
this.queue = queue;
this.executorService = Executors.newSingleThreadScheduledExecutor(newThreadFactory());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportLog.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportActivity.java
index 1b307d69171..b4d7165a82f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportLog.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportActivity.java
@@ -30,14 +30,14 @@ import java.util.Map;
import static org.sonar.api.utils.DateUtils.formatDateTimeNullSafe;
import static org.sonar.api.utils.DateUtils.longToDate;
-public class AnalysisReportLog implements ActivityLog {
+public class ReportActivity implements ActivityLog {
private static final String ACTION = "LOG_ANALYSIS_REPORT";
private final AnalysisReportDto report;
private final ComponentDto project;
- public AnalysisReportLog(AnalysisReportDto report, ComponentDto project) {
+ public ReportActivity(AnalysisReportDto report, ComponentDto project) {
this.report = report;
this.project = project;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueue.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueue.java
new file mode 100644
index 00000000000..8139db0d050
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueue.java
@@ -0,0 +1,188 @@
+/*
+ * 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;
+
+import org.apache.commons.io.FileUtils;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.internal.Uuids;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.computation.db.AnalysisReportDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.process.ProcessConstants;
+import org.sonar.server.db.DbClient;
+
+import javax.annotation.CheckForNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING;
+
+public class ReportQueue implements ServerComponent {
+
+ public static class Item {
+ public final AnalysisReportDto dto;
+ public final File zipFile;
+
+ public Item(AnalysisReportDto dto, File zipFile) {
+ this.dto = dto;
+ this.zipFile = zipFile;
+ }
+ }
+
+ private final DbClient dbClient;
+ private final Settings settings;
+
+ public ReportQueue(DbClient dbClient, Settings settings) {
+ this.dbClient = dbClient;
+ this.settings = settings;
+ }
+
+ public Item add(String projectKey, InputStream reportData) {
+ String uuid = Uuids.create();
+ File file = reportFileForUuid(uuid);
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ checkThatProjectExistsInDatabase(projectKey, session);
+
+ // save report data on file. Directory is created if it does not exist yet.
+ FileUtils.copyInputStreamToFile(reportData, file);
+
+ // add report metadata to the queue
+ AnalysisReportDto dto = new AnalysisReportDto()
+ .setProjectKey(projectKey)
+ .setStatus(PENDING)
+ .setUuid(uuid);
+ dbClient.analysisReportDao().insert(session, dto);
+ session.commit();
+ return new Item(dto, file);
+
+ } catch (Exception e) {
+ FileUtils.deleteQuietly(file);
+ throw new IllegalStateException("Fail to store analysis report of project " + projectKey, e);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ private void checkThatProjectExistsInDatabase(String projectKey, DbSession session) {
+ dbClient.componentDao().getByKey(session, projectKey);
+ }
+
+ public void remove(Item item) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ FileUtils.deleteQuietly(item.zipFile);
+ dbClient.analysisReportDao().delete(session, item.dto.getId());
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @CheckForNull
+ public Item pop() {
+ DbSession session = dbClient.openSession(false);
+ try {
+ AnalysisReportDto dto = dbClient.analysisReportDao().pop(session);
+ if (dto != null) {
+ File file = reportFileForUuid(dto.getUuid());
+ if (file.exists()) {
+ return new Item(dto, file);
+ }
+ Loggers.get(getClass()).error("Analysis report not found: " + file.getAbsolutePath());
+ dbClient.analysisReportDao().delete(session, dto.getId());
+ session.commit();
+ }
+ return null;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<AnalysisReportDto> findByProjectKey(String projectKey) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.analysisReportDao().selectByProjectKey(session, projectKey);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ /**
+ * Truncates table ANALYSIS_REPORTS and delete all files from directory {data}/analysis
+ */
+ public void clear() {
+ File dir = reportsDir();
+ try {
+ FileUtils.deleteDirectory(dir);
+ } catch (IOException e) {
+ throw new IllegalStateException("Fail to delete directory: " + dir.getAbsolutePath(), e);
+ }
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ dbClient.analysisReportDao().truncate(session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void resetToPendingStatus() {
+ DbSession session = dbClient.openSession(false);
+ try {
+ dbClient.analysisReportDao().resetAllToPendingStatus(session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ /**
+ * All the reports of the queue, whatever the status
+ */
+ public List<AnalysisReportDto> all() {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.analysisReportDao().selectAll(session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ /**
+ * This directory is a flat list of the reports referenced in table ANALYSIS_REPORTS.
+ * Never return null but the directory may not exist.
+ */
+ private File reportsDir() {
+ return new File(settings.getString(ProcessConstants.PATH_DATA), "analysis");
+ }
+
+ private File reportFileForUuid(String uuid) {
+ return new File(reportsDir(), String.format("%s.zip", uuid));
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueueCleaner.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueueCleaner.java
index 9e660b68c7e..7abc9f1953e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/AnalysisReportQueueCleaner.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportQueueCleaner.java
@@ -23,10 +23,6 @@ package org.sonar.server.computation;
import org.picocontainer.Startable;
import org.sonar.api.ServerComponent;
import org.sonar.api.platform.ServerUpgradeStatus;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.server.computation.db.AnalysisReportDao;
-import org.sonar.server.db.DbClient;
/**
* Clean-up queue of reports at server startup:
@@ -36,30 +32,22 @@ import org.sonar.server.db.DbClient;
* <li>reset reports that were in status WORKING while server stopped</li>
* </ul>
*/
-public class AnalysisReportQueueCleaner implements Startable, ServerComponent {
+public class ReportQueueCleaner implements Startable, ServerComponent {
private final ServerUpgradeStatus serverUpgradeStatus;
- private final DbClient dbClient;
+ private final ReportQueue queue;
- public AnalysisReportQueueCleaner(ServerUpgradeStatus serverUpgradeStatus, DbClient dbClient) {
+ public ReportQueueCleaner(ServerUpgradeStatus serverUpgradeStatus, ReportQueue queue) {
this.serverUpgradeStatus = serverUpgradeStatus;
- this.dbClient = dbClient;
+ this.queue = queue;
}
@Override
public void start() {
- AnalysisReportDao dao = dbClient.analysisReportDao();
- DbSession session = dbClient.openSession(false);
- try {
- if (serverUpgradeStatus.isUpgraded()) {
- dao.truncate(session);
- } else {
- dao.resetAllToPendingStatus(session);
- }
-
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
+ if (serverUpgradeStatus.isUpgraded()) {
+ queue.clear();
+ } else {
+ queue.resetToPendingStatus();
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/db/AnalysisReportDao.java b/server/sonar-server/src/main/java/org/sonar/server/computation/db/AnalysisReportDao.java
index 11f22499c5f..f08edbf5b3a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/db/AnalysisReportDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/db/AnalysisReportDao.java
@@ -21,27 +21,14 @@
package org.sonar.server.computation.db;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.ByteStreams;
-import org.apache.commons.io.IOUtils;
import org.sonar.api.utils.System2;
-import org.sonar.api.utils.ZipUtils;
import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.computation.db.AnalysisReportMapper;
import org.sonar.core.persistence.DaoComponent;
-import org.sonar.core.persistence.DatabaseUtils;
import org.sonar.core.persistence.DbSession;
import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
+
import java.util.List;
import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING;
@@ -55,8 +42,7 @@ public class AnalysisReportDao implements DaoComponent {
this(System2.INSTANCE);
}
- @VisibleForTesting
- AnalysisReportDao(System2 system2) {
+ public AnalysisReportDao(System2 system2) {
this.system2 = system2;
}
@@ -111,78 +97,10 @@ public class AnalysisReportDao implements DaoComponent {
public AnalysisReportDto insert(DbSession session, AnalysisReportDto report) {
report.setCreatedAt(system2.now());
report.setUpdatedAt(system2.now());
-
- Connection connection = session.getConnection();
- PreparedStatement ps = null;
- try {
- ps = connection.prepareStatement(
- "insert into analysis_reports " +
- " (project_key, snapshot_id, report_status, report_data, created_at, updated_at, started_at, finished_at)" +
- " values (?, ?, ?, ?, ?, ?, ?, ?)");
- ps.setString(1, report.getProjectKey());
- ps.setLong(2, report.getSnapshotId());
- ps.setString(3, report.getStatus().toString());
- setData(ps, 4, report.getData());
- ps.setLong(5, report.getCreatedAt());
- setLong(ps, 6, report.getUpdatedAt());
- setLong(ps, 7, report.getStartedAt());
- setLong(ps, 8, report.getFinishedAt());
- ps.executeUpdate();
- connection.commit();
- } catch (SQLException | IOException e) {
- throw new IllegalStateException(String.format("Failed to insert %s in the database", report), e);
- } finally {
- DatabaseUtils.closeQuietly(ps);
- }
-
+ mapper(session).insert(report);
return report;
}
- private void setLong(PreparedStatement ps, int index, @Nullable Long time) throws SQLException {
- if (time == null) {
- ps.setNull(index, Types.BIGINT);
- } else {
- ps.setLong(index, time);
- }
- }
-
- private void setData(PreparedStatement ps, int parameterIndex, @Nullable InputStream reportDataStream) throws IOException, SQLException {
- if (reportDataStream == null) {
- ps.setBytes(parameterIndex, null);
- } else {
- ps.setBytes(parameterIndex, ByteStreams.toByteArray(reportDataStream));
- }
- }
-
- @CheckForNull
- public void selectAndDecompressToDir(DbSession session, long id, File toDir) {
- Connection connection = session.getConnection();
- InputStream stream = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- ps = connection.prepareStatement("select report_data from analysis_reports where id=?");
- ps.setLong(1, id);
-
- rs = ps.executeQuery();
- if (rs.next()) {
- stream = rs.getBinaryStream(1);
- if (stream != null) {
- ZipUtils.unzip(stream, toDir);
- }
- }
- // TODO what to do if id not found or no stream ?
- } catch (SQLException e) {
- throw new IllegalStateException(String.format("Failed to read report '%d' in the database", id), e);
- } catch (IOException e) {
- throw new IllegalStateException(String.format("Failed to decompress report '%d'", id), e);
- } finally {
- IOUtils.closeQuietly(stream);
- DatabaseUtils.closeQuietly(rs);
- DatabaseUtils.closeQuietly(ps);
- }
- }
-
public void delete(DbSession session, long id) {
mapper(session).delete(id);
}
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 d73706b7060..973c5dadf55 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
@@ -21,11 +21,14 @@
package org.sonar.server.computation.step;
import com.google.common.collect.Lists;
-import org.sonar.server.computation.ComputationComponents;
+import org.sonar.server.computation.ComputationContainer;
import java.util.Arrays;
import java.util.List;
+/**
+ * Ordered list of steps to be executed
+ */
public class ComputationSteps {
/**
@@ -77,6 +80,6 @@ public class ComputationSteps {
return step;
}
}
- throw new IllegalStateException("Component not found: " + clazz + ". Check " + ComputationComponents.class);
+ 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 9d6f4a547e4..0eff6e32988 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
@@ -20,34 +20,17 @@
package org.sonar.server.computation.step;
-import org.apache.commons.io.FileUtils;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.utils.TempFolder;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.batch.protocol.output.BatchOutputReader;
import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.issue.IssueComputation;
-import org.sonar.server.db.DbClient;
-
-import java.io.File;
public class ParseReportStep implements ComputationStep {
- private static final Logger LOG = Loggers.get(ParseReportStep.class);
-
private final IssueComputation issueComputation;
- private final DbClient dbClient;
- private final TempFolder tempFolder;
- public ParseReportStep(IssueComputation issueComputation, DbClient dbClient, TempFolder tempFolder) {
+ public ParseReportStep(IssueComputation issueComputation) {
this.issueComputation = issueComputation;
- this.dbClient = dbClient;
- this.tempFolder = tempFolder;
}
@Override
@@ -57,45 +40,18 @@ public class ParseReportStep implements ComputationStep {
@Override
public void execute(ComputationContext context) {
- File reportDir = tempFolder.newDir();
- try {
- // extract compressed report from database and uncompress it in temporary directory
- extractReport(context.getReportDto(), reportDir);
-
- // prepare parsing of report
- BatchOutputReader reader = new BatchOutputReader(reportDir);
- BatchReport.Metadata reportMetadata = reader.readMetadata();
- context.setReportMetadata(reportMetadata);
-
- // and parse!
- int rootComponentRef = reportMetadata.getRootComponentRef();
- recursivelyProcessComponent(reader, context, rootComponentRef);
- issueComputation.afterReportProcessing();
-
- } finally {
- FileUtils.deleteQuietly(reportDir);
- }
- }
-
- private void extractReport(AnalysisReportDto report, File toDir) {
- long startTime = System.currentTimeMillis();
- DbSession session = dbClient.openSession(false);
- try {
- dbClient.analysisReportDao().selectAndDecompressToDir(session, report.getId(), toDir);
- } finally {
- MyBatis.closeQuietly(session);
- }
- long stopTime = System.currentTimeMillis();
- LOG.info(String.format("Report extracted in %dms | uncompressed size=%s | project=%s",
- stopTime - startTime, FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(toDir)), report.getProjectKey()));
+ int rootComponentRef = context.getReportMetadata().getRootComponentRef();
+ recursivelyProcessComponent(context, rootComponentRef);
+ issueComputation.afterReportProcessing();
}
- private void recursivelyProcessComponent(BatchOutputReader reportReader, ComputationContext context, int componentRef) {
- BatchReport.Component component = reportReader.readComponent(componentRef);
+ private void recursivelyProcessComponent(ComputationContext context, int componentRef) {
+ BatchReport.Component component = context.getReportReader().readComponent(componentRef);
if (component != null) {
- issueComputation.processComponentIssues(context, component.getUuid(), reportReader.readComponentIssues(componentRef));
+ Iterable<BatchReport.Issue> issues = context.getReportReader().readComponentIssues(componentRef);
+ issueComputation.processComponentIssues(context, component.getUuid(), issues);
for (Integer childRef : component.getChildRefsList()) {
- recursivelyProcessComponent(reportReader, context, childRef);
+ recursivelyProcessComponent(context, childRef);
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SwitchSnapshotStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SwitchSnapshotStep.java
index 1be36deb720..b073cd53ca1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SwitchSnapshotStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SwitchSnapshotStep.java
@@ -22,7 +22,6 @@ package org.sonar.server.computation.step;
import org.sonar.api.resources.Qualifiers;
import org.sonar.core.component.SnapshotDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.component.db.SnapshotDao;
@@ -48,8 +47,9 @@ public class SwitchSnapshotStep implements ComputationStep {
public void execute(ComputationContext context) {
DbSession session = dbClient.openSession(true);
try {
- disablePreviousSnapshot(session, context.getReportDto());
- enableCurrentSnapshot(session, context.getReportDto());
+ long snapshotId = context.getReportMetadata().getSnapshotId();
+ disablePreviousSnapshot(session, snapshotId);
+ enableCurrentSnapshot(session, snapshotId);
} finally {
MyBatis.closeQuietly(session);
}
@@ -60,16 +60,8 @@ public class SwitchSnapshotStep implements ComputationStep {
return "Switch last snapshot flag";
}
- private void disablePreviousSnapshot(DbSession session, AnalysisReportDto report) {
- SnapshotDto referenceSnapshot;
-
- try {
- referenceSnapshot = dbClient.snapshotDao().getByKey(session, report.getSnapshotId());
- } catch (Exception exception) {
- throw new IllegalStateException(String.format("Unexpected error while trying to retrieve snapshot of analysis %s", report), exception);
- }
-
- List<SnapshotDto> snapshots = dbClient.snapshotDao().findSnapshotAndChildrenOfProjectScope(session, referenceSnapshot);
+ private void disablePreviousSnapshot(DbSession session, long reportSnapshotId) {
+ List<SnapshotDto> snapshots = dbClient.snapshotDao().findSnapshotAndChildrenOfProjectScope(session, dbClient.snapshotDao().getByKey(session, reportSnapshotId));
for (SnapshotDto snapshot : snapshots) {
SnapshotDto previousLastSnapshot = dbClient.snapshotDao().getLastSnapshot(session, snapshot);
if (previousLastSnapshot != null) {
@@ -79,9 +71,9 @@ public class SwitchSnapshotStep implements ComputationStep {
}
}
- private void enableCurrentSnapshot(DbSession session, AnalysisReportDto report) {
+ private void enableCurrentSnapshot(DbSession session, long reportSnapshotId) {
SnapshotDao dao = dbClient.snapshotDao();
- SnapshotDto snapshot = dao.getByKey(session, report.getSnapshotId());
+ SnapshotDto snapshot = dao.getByKey(session, reportSnapshotId);
SnapshotDto previousLastSnapshot = dao.getLastSnapshot(session, snapshot);
boolean isLast = dao.isLast(snapshot, previousLastSnapshot);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java
index b1448a53792..eec1336a157 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java
@@ -42,21 +42,19 @@ public class HistoryWsAction implements ComputationWsAction, RequestHandler {
public static final String PARAM_TYPE = "type";
- public static final String SEARCH_ACTION = "history";
-
- private final ActivityService logService;
+ private final ActivityService activityService;
private final ActivityMapping mapping;
- public HistoryWsAction(ActivityService logService, ActivityMapping mapping) {
- this.logService = logService;
+ public HistoryWsAction(ActivityService activityService, ActivityMapping mapping) {
+ this.activityService = activityService;
this.mapping = mapping;
}
@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller
- .createAction(SEARCH_ACTION)
- .setDescription("Search for activities")
+ .createAction("history")
+ .setDescription("Past integrations of analysis reports")
.setSince("5.0")
.setInternal(true)
.setHandler(this);
@@ -70,13 +68,13 @@ public class HistoryWsAction implements ComputationWsAction, RequestHandler {
public void handle(Request request, Response response) {
checkUserRights();
- ActivityQuery query = logService.newActivityQuery();
+ ActivityQuery query = activityService.newActivityQuery();
query.setTypes(Arrays.asList(Activity.Type.ANALYSIS_REPORT));
SearchOptions searchOptions = SearchOptions.create(request);
QueryContext queryContext = mapping.newQueryOptions(searchOptions);
- Result<Activity> results = logService.search(query, queryContext);
+ Result<Activity> results = activityService.search(query, queryContext);
JsonWriter json = response.newJsonWriter().beginObject();
searchOptions.writeStatistics(json, results);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWebService.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWebService.java
index 986438a7883..611043076e6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWebService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWebService.java
@@ -26,7 +26,7 @@ import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.server.computation.ReportQueue;
import java.util.List;
@@ -38,7 +38,7 @@ public class IsQueueEmptyWebService implements WebService {
private final IsQueueEmptyWsAction action;
- public IsQueueEmptyWebService(AnalysisReportQueue queue) {
+ public IsQueueEmptyWebService(ReportQueue queue) {
this.action = new IsQueueEmptyWsAction(queue);
}
@@ -52,9 +52,9 @@ public class IsQueueEmptyWebService implements WebService {
}
static class IsQueueEmptyWsAction implements RequestHandler {
- private final AnalysisReportQueue queue;
+ private final ReportQueue queue;
- public IsQueueEmptyWsAction(AnalysisReportQueue queue) {
+ public IsQueueEmptyWsAction(ReportQueue queue) {
this.queue = queue;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java
index cf9f54029cc..39e6d3dcff4 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java
@@ -26,7 +26,7 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.server.computation.ReportQueue;
import java.util.List;
@@ -36,9 +36,9 @@ import static org.sonar.api.utils.DateUtils.longToDate;
* @since 5.0
*/
public class QueueWsAction implements ComputationWsAction, RequestHandler {
- private final AnalysisReportQueue queue;
+ private final ReportQueue queue;
- public QueueWsAction(AnalysisReportQueue queue) {
+ public QueueWsAction(ReportQueue queue) {
this.queue = queue;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java
index d474e73bb3b..eb3e7d93259 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java
@@ -20,12 +20,15 @@
package org.sonar.server.computation.ws;
+import org.apache.commons.io.IOUtils;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.server.computation.ComputationThreadLauncher;
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.user.UserSession;
import java.io.InputStream;
@@ -33,13 +36,12 @@ public class SubmitReportWsAction implements ComputationWsAction, RequestHandler
public static final String ACTION = "submit_report";
public static final String PARAM_PROJECT_KEY = "projectKey";
- public static final String PARAM_SNAPSHOT = "snapshot";
public static final String PARAM_REPORT_DATA = "report";
- private final AnalysisReportQueue queue;
+ private final ReportQueue queue;
private final ComputationThreadLauncher workerLauncher;
- public SubmitReportWsAction(AnalysisReportQueue queue, ComputationThreadLauncher workerLauncher) {
+ public SubmitReportWsAction(ReportQueue queue, ComputationThreadLauncher workerLauncher) {
this.queue = queue;
this.workerLauncher = workerLauncher;
}
@@ -59,12 +61,6 @@ public class SubmitReportWsAction implements ComputationWsAction, RequestHandler
.setExampleValue("org.codehaus.sonar:sonar");
action
- .createParam(PARAM_SNAPSHOT)
- .setRequired(true)
- .setDescription("Snapshot ID")
- .setExampleValue("123");
-
- action
.createParam(PARAM_REPORT_DATA)
.setRequired(false)
.setDescription("Report file. Format is not an API, it changes among SonarQube versions.");
@@ -72,16 +68,21 @@ public class SubmitReportWsAction implements ComputationWsAction, RequestHandler
@Override
public void handle(Request request, Response response) throws Exception {
+ UserSession.get().checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
String projectKey = request.mandatoryParam(PARAM_PROJECT_KEY);
- long snapshotId = request.mandatoryParamAsLong(PARAM_SNAPSHOT);
- try (InputStream reportData = request.paramAsInputStream(PARAM_REPORT_DATA)) {
- String reportKey = queue.add(projectKey, snapshotId, reportData);
+ InputStream reportData = request.paramAsInputStream(PARAM_REPORT_DATA);
+ try {
+ ReportQueue.Item item = queue.add(projectKey, reportData);
workerLauncher.startAnalysisTaskNow();
response.newJsonWriter()
.beginObject()
- .prop("key", reportKey)
+ // do not write integer for forward-compatibility, for example
+ // if we want to write UUID later
+ .prop("key", String.valueOf(item.dto.getId()))
.endObject()
.close();
+ } finally {
+ IOUtils.closeQuietly(reportData);
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index 959fe205322..cf8302be667 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -53,7 +53,12 @@ import org.sonar.core.measure.db.MeasureFilterDao;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.*;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.purge.PurgeProfiler;
import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
import org.sonar.core.qualitygate.db.QualityGateConditionDao;
@@ -77,7 +82,12 @@ import org.sonar.server.activity.index.ActivityNormalizer;
import org.sonar.server.activity.ws.ActivitiesWebService;
import org.sonar.server.activity.ws.ActivityMapping;
import org.sonar.server.authentication.ws.AuthenticationWs;
-import org.sonar.server.batch.*;
+import org.sonar.server.batch.BatchIndex;
+import org.sonar.server.batch.BatchWs;
+import org.sonar.server.batch.GlobalRepositoryAction;
+import org.sonar.server.batch.IssuesAction;
+import org.sonar.server.batch.ProjectRepositoryAction;
+import org.sonar.server.batch.ProjectRepositoryLoader;
import org.sonar.server.charts.ChartFactory;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentService;
@@ -86,12 +96,20 @@ import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.component.db.ComponentIndexDao;
import org.sonar.server.component.db.SnapshotDao;
-import org.sonar.server.component.ws.*;
-import org.sonar.server.computation.AnalysisReportQueue;
-import org.sonar.server.computation.AnalysisReportQueueCleaner;
+import org.sonar.server.component.ws.ComponentAppAction;
+import org.sonar.server.component.ws.ComponentsWs;
+import org.sonar.server.component.ws.EventsWs;
+import org.sonar.server.component.ws.ProjectsWs;
+import org.sonar.server.component.ws.ResourcesWs;
import org.sonar.server.computation.ComputationThreadLauncher;
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.computation.ReportQueueCleaner;
import org.sonar.server.computation.db.AnalysisReportDao;
-import org.sonar.server.computation.ws.*;
+import org.sonar.server.computation.ws.ComputationWebService;
+import org.sonar.server.computation.ws.HistoryWsAction;
+import org.sonar.server.computation.ws.IsQueueEmptyWebService;
+import org.sonar.server.computation.ws.QueueWsAction;
+import org.sonar.server.computation.ws.SubmitReportWsAction;
import org.sonar.server.config.ws.PropertiesWs;
import org.sonar.server.dashboard.db.DashboardDao;
import org.sonar.server.dashboard.db.WidgetDao;
@@ -103,7 +121,14 @@ import org.sonar.server.db.DbClient;
import org.sonar.server.db.EmbeddedDatabaseFactory;
import org.sonar.server.db.migrations.DatabaseMigrations;
import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.debt.*;
+import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
+import org.sonar.server.debt.DebtModelBackup;
+import org.sonar.server.debt.DebtModelLookup;
+import org.sonar.server.debt.DebtModelOperations;
+import org.sonar.server.debt.DebtModelPluginRepository;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.debt.DebtModelXMLExporter;
+import org.sonar.server.debt.DebtRulesXMLImporter;
import org.sonar.server.design.FileDesignWidget;
import org.sonar.server.duplication.ws.DuplicationsJsonWriter;
import org.sonar.server.duplication.ws.DuplicationsParser;
@@ -111,7 +136,22 @@ import org.sonar.server.duplication.ws.DuplicationsWs;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.IndexCreator;
import org.sonar.server.es.IndexRegistry;
-import org.sonar.server.issue.*;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AddTagsAction;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogFormatter;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueQueryService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.RemoveTagsAction;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.issue.actionplan.ActionPlanWs;
import org.sonar.server.issue.db.IssueDao;
@@ -122,8 +162,16 @@ import org.sonar.server.issue.index.IssueAuthorizationIndexer;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.issue.notification.*;
-import org.sonar.server.issue.ws.*;
+import org.sonar.server.issue.notification.ChangesOnMyIssueNotificationDispatcher;
+import org.sonar.server.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.server.issue.notification.NewFalsePositiveNotificationDispatcher;
+import org.sonar.server.issue.notification.NewIssuesEmailTemplate;
+import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher;
+import org.sonar.server.issue.ws.ComponentTagsAction;
+import org.sonar.server.issue.ws.IssueActionsWriter;
+import org.sonar.server.issue.ws.IssueShowAction;
+import org.sonar.server.issue.ws.IssuesWs;
+import org.sonar.server.issue.ws.SetTagsAction;
import org.sonar.server.language.ws.LanguageWs;
import org.sonar.server.language.ws.ListAction;
import org.sonar.server.measure.MeasureFilterEngine;
@@ -140,44 +188,141 @@ import org.sonar.server.permission.InternalPermissionService;
import org.sonar.server.permission.InternalPermissionTemplateService;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.permission.ws.PermissionsWs;
-import org.sonar.server.platform.monitoring.*;
-import org.sonar.server.platform.ws.*;
-import org.sonar.server.plugins.*;
+import org.sonar.server.platform.monitoring.DatabaseMonitor;
+import org.sonar.server.platform.monitoring.EsMonitor;
+import org.sonar.server.platform.monitoring.JvmPropertiesMonitor;
+import org.sonar.server.platform.monitoring.PluginsMonitor;
+import org.sonar.server.platform.monitoring.SonarQubeMonitor;
+import org.sonar.server.platform.monitoring.SystemMonitor;
+import org.sonar.server.platform.ws.L10nWs;
+import org.sonar.server.platform.ws.ServerWs;
+import org.sonar.server.platform.ws.SystemInfoWsAction;
+import org.sonar.server.platform.ws.SystemRestartWsAction;
+import org.sonar.server.platform.ws.SystemWs;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginJarInstaller;
+import org.sonar.server.plugins.ServerPluginJarsInstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.properties.ProjectSettingsFactory;
import org.sonar.server.qualitygate.QgateProjectFinder;
import org.sonar.server.qualitygate.QualityGates;
import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualitygate.ws.*;
-import org.sonar.server.qualityprofile.*;
+import org.sonar.server.qualitygate.ws.QGatesAppAction;
+import org.sonar.server.qualitygate.ws.QGatesCopyAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeselectAction;
+import org.sonar.server.qualitygate.ws.QGatesDestroyAction;
+import org.sonar.server.qualitygate.ws.QGatesListAction;
+import org.sonar.server.qualitygate.ws.QGatesRenameAction;
+import org.sonar.server.qualitygate.ws.QGatesSearchAction;
+import org.sonar.server.qualitygate.ws.QGatesSelectAction;
+import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesShowAction;
+import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesWs;
+import org.sonar.server.qualityprofile.BuiltInProfiles;
+import org.sonar.server.qualityprofile.QProfileBackuper;
+import org.sonar.server.qualityprofile.QProfileCopier;
+import org.sonar.server.qualityprofile.QProfileExporters;
+import org.sonar.server.qualityprofile.QProfileFactory;
+import org.sonar.server.qualityprofile.QProfileLoader;
+import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.QProfileProjectLookup;
+import org.sonar.server.qualityprofile.QProfileProjectOperations;
+import org.sonar.server.qualityprofile.QProfileReset;
+import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.QProfiles;
+import org.sonar.server.qualityprofile.RegisterQualityProfiles;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
import org.sonar.server.qualityprofile.db.ActiveRuleDao;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.qualityprofile.ws.*;
-import org.sonar.server.rule.*;
+import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
+import org.sonar.server.qualityprofile.ws.ProfilesWs;
+import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction;
+import org.sonar.server.qualityprofile.ws.QProfilesWs;
+import org.sonar.server.qualityprofile.ws.RuleActivationActions;
+import org.sonar.server.rule.DefaultRuleFinder;
+import org.sonar.server.rule.DeprecatedRulesDefinitionLoader;
+import org.sonar.server.rule.RegisterRules;
+import org.sonar.server.rule.RubyRuleService;
+import org.sonar.server.rule.RuleCreator;
+import org.sonar.server.rule.RuleDefinitionsLoader;
+import org.sonar.server.rule.RuleDeleter;
+import org.sonar.server.rule.RuleOperations;
+import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.rule.RuleService;
+import org.sonar.server.rule.RuleUpdater;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleNormalizer;
-import org.sonar.server.rule.ws.*;
+import org.sonar.server.rule.ws.ActiveRuleCompleter;
+import org.sonar.server.rule.ws.AppAction;
+import org.sonar.server.rule.ws.DeleteAction;
+import org.sonar.server.rule.ws.RepositoriesAction;
+import org.sonar.server.rule.ws.RuleMapping;
+import org.sonar.server.rule.ws.RulesWebService;
import org.sonar.server.rule.ws.SearchAction;
import org.sonar.server.rule.ws.TagsAction;
-import org.sonar.server.search.*;
+import org.sonar.server.rule.ws.UpdateAction;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.search.IndexQueue;
+import org.sonar.server.search.IndexSynchronizer;
+import org.sonar.server.search.SearchClient;
import org.sonar.server.source.HtmlSourceDecorator;
import org.sonar.server.source.SourceService;
import org.sonar.server.source.index.SourceLineIndex;
import org.sonar.server.source.index.SourceLineIndexDefinition;
import org.sonar.server.source.index.SourceLineIndexer;
-import org.sonar.server.source.ws.*;
+import org.sonar.server.source.ws.HashAction;
+import org.sonar.server.source.ws.IndexAction;
+import org.sonar.server.source.ws.LinesAction;
+import org.sonar.server.source.ws.RawAction;
+import org.sonar.server.source.ws.ScmAction;
+import org.sonar.server.source.ws.ScmWriter;
import org.sonar.server.source.ws.ShowAction;
-import org.sonar.server.startup.*;
+import org.sonar.server.source.ws.SourcesWs;
+import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterDashboards;
+import org.sonar.server.startup.RegisterDebtModel;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
import org.sonar.server.test.CoverageService;
-import org.sonar.server.test.ws.*;
+import org.sonar.server.test.ws.CoverageShowAction;
+import org.sonar.server.test.ws.CoverageWs;
+import org.sonar.server.test.ws.TestsCoveredFilesAction;
+import org.sonar.server.test.ws.TestsShowAction;
+import org.sonar.server.test.ws.TestsTestCasesAction;
+import org.sonar.server.test.ws.TestsWs;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
import org.sonar.server.ui.JRubyI18n;
import org.sonar.server.ui.PageDecorations;
import org.sonar.server.ui.Views;
import org.sonar.server.updatecenter.ws.UpdateCenterWs;
-import org.sonar.server.user.*;
+import org.sonar.server.user.DefaultUserService;
+import org.sonar.server.user.DoPrivileged;
+import org.sonar.server.user.GroupMembershipFinder;
+import org.sonar.server.user.GroupMembershipService;
+import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.user.SecurityRealmFactory;
+import org.sonar.server.user.UserService;
+import org.sonar.server.user.UserUpdater;
import org.sonar.server.user.db.GroupDao;
import org.sonar.server.user.db.UserDao;
import org.sonar.server.user.db.UserGroupDao;
@@ -187,7 +332,13 @@ import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.user.ws.FavoritesWs;
import org.sonar.server.user.ws.UserPropertiesWs;
import org.sonar.server.user.ws.UsersWs;
-import org.sonar.server.util.*;
+import org.sonar.server.util.BooleanTypeValidation;
+import org.sonar.server.util.FloatTypeValidation;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringListTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TextTypeValidation;
+import org.sonar.server.util.TypeValidations;
import org.sonar.server.view.index.ViewIndex;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.sonar.server.view.index.ViewIndexer;
@@ -642,10 +793,10 @@ class ServerComponents {
PluginsMonitor.class,
JvmPropertiesMonitor.class,
DatabaseMonitor.class
- ));
+ ));
// Compute engine
- pico.addSingleton(AnalysisReportQueue.class);
+ pico.addSingleton(ReportQueue.class);
pico.addSingleton(ComputationThreadLauncher.class);
pico.addSingleton(ComputationWebService.class);
pico.addSingleton(IsQueueEmptyWebService.class);
@@ -688,7 +839,7 @@ class ServerComponents {
startupContainer.addSingleton(LogServerId.class);
startupContainer.addSingleton(RegisterServletFilters.class);
startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class);
- startupContainer.addSingleton(AnalysisReportQueueCleaner.class);
+ startupContainer.addSingleton(ReportQueueCleaner.class);
DoPrivileged.execute(new DoPrivileged.Task() {
@Override
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueMediumTest.java
deleted file mode 100644
index 2b76903a7ca..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueMediumTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.computation;
-
-import org.apache.commons.io.IOUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.user.UserDto;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.user.MockUserSession;
-
-import java.io.InputStream;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.core.computation.db.AnalysisReportDto.Status.SUCCESS;
-import static org.sonar.core.computation.db.AnalysisReportDto.Status.WORKING;
-
-public class AnalysisReportQueueMediumTest {
- private static final String DEFAULT_PROJECT_KEY = "123456789-987654321";
-
- @ClassRule
- public static ServerTester tester = new ServerTester();
-
- private AnalysisReportQueue sut;
-
- private DbClient db;
- private DbSession session;
- private MockUserSession userSession;
-
- @Before
- public void setUp() throws Exception {
- tester.clearDbAndIndexes();
- db = tester.get(DbClient.class);
- session = db.openSession(false);
-
- sut = tester.get(AnalysisReportQueue.class);
-
- UserDto connectedUser = new UserDto().setLogin("gandalf").setName("Gandalf");
- db.userDao().insert(session, connectedUser);
-
- userSession = MockUserSession.set()
- .setLogin(connectedUser.getLogin())
- .setUserId(connectedUser.getId().intValue())
- .setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- session.commit();
- }
-
- @After
- public void after() {
- MyBatis.closeQuietly(session);
- }
-
- @Test
- public void create_analysis_report_and_retrieve_it() {
- insertPermissionsForProject(DEFAULT_PROJECT_KEY);
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
-
- List<AnalysisReportDto> reports = sut.findByProjectKey(DEFAULT_PROJECT_KEY);
- AnalysisReportDto report = reports.get(0);
-
- assertThat(reports).hasSize(1);
- assertThat(report.getProjectKey()).isEqualTo(DEFAULT_PROJECT_KEY);
- assertThat(report.getSnapshotId()).isEqualTo(123L);
- assertThat(report.getCreatedAt()).isNotNull();
- }
-
- private ComponentDto insertPermissionsForProject(String projectKey) {
- ComponentDto project = new ComponentDto().setKey(projectKey);
- db.componentDao().insert(session, project);
-
- tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
- userSession.addProjectPermissions(UserRole.USER, project.key());
-
- session.commit();
-
- return project;
- }
-
- @Test
- public void create_and_book_oldest_available_analysis_report_thrice() {
- insertPermissionsForProject(DEFAULT_PROJECT_KEY);
- insertPermissionsForProject("2");
- insertPermissionsForProject("3");
-
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
- sut.add("2", 123L, defaultReportData());
- sut.add("3", 123L, defaultReportData());
-
- AnalysisReportDto firstBookedReport = sut.pop();
- AnalysisReportDto secondBookedReport = sut.pop();
- AnalysisReportDto thirdBookedReport = sut.pop();
-
- assertThat(firstBookedReport.getProjectKey()).isEqualTo(DEFAULT_PROJECT_KEY);
- assertThat(firstBookedReport.getStatus()).isEqualTo(WORKING);
- assertThat(firstBookedReport.getStartedAt()).isNotNull();
- assertThat(secondBookedReport.getProjectKey()).isEqualTo("2");
- assertThat(thirdBookedReport.getProjectKey()).isEqualTo("3");
- }
-
- @Test
- public void search_for_available_report_when_no_report_available() {
- AnalysisReportDto nullAnalysisReport = sut.pop();
-
- assertThat(nullAnalysisReport).isNull();
- }
-
- @Test
- public void all() {
- insertPermissionsForProject(DEFAULT_PROJECT_KEY);
-
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
-
- List<AnalysisReportDto> reports = sut.all();
-
- assertThat(reports).hasSize(3);
- }
-
- @Test
- public void remove_remove_from_queue() {
- insertPermissionsForProject(DEFAULT_PROJECT_KEY);
- sut.add(DEFAULT_PROJECT_KEY, 123L, defaultReportData());
- AnalysisReportDto report = sut.pop();
- report.setStatus(SUCCESS);
-
- sut.remove(report);
-
- assertThat(sut.all()).isEmpty();
- }
-
- @Test(expected = ForbiddenException.class)
- public void cannot_add_report_when_not_the_right_rights() {
- ComponentDto project = new ComponentDto()
- .setKey("MyProject");
- db.componentDao().insert(session, project);
- session.commit();
-
- MockUserSession.set().setLogin("gandalf").addProjectPermissions(UserRole.USER, project.key());
-
- sut.add(project.getKey(), 123L, defaultReportData());
- }
-
- private InputStream defaultReportData() {
- return IOUtils.toInputStream("default-project");
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationComponentsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationContainerTest.java
index ae7590ce6fe..bd391ffbed2 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationComponentsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationContainerTest.java
@@ -20,19 +20,13 @@
package org.sonar.server.computation;
import org.junit.Test;
-import org.sonar.test.TestUtils;
import static org.assertj.core.api.Assertions.assertThat;
-public class ComputationComponentsTest {
+public class ComputationContainerTest {
@Test
- public void nonStepComponents() throws Exception {
- assertThat(ComputationComponents.nonStepComponents()).isNotEmpty();
- }
-
- @Test
- public void util_class() throws Exception {
- assertThat(TestUtils.hasOnlyPrivateConstructors(ComputationComponents.class)).isTrue();
+ public void componentClasses() throws Exception {
+ assertThat(ComputationContainer.componentClasses()).isNotEmpty();
}
}
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 e983b901cef..61d9cc7ab88 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
@@ -17,13 +17,41 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+/*
+ * 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;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.resources.Qualifiers;
+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.output.BatchOutputWriter;
+import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.activity.Activity;
import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.persistence.DbSession;
@@ -34,6 +62,8 @@ import org.sonar.server.computation.step.ComputationStep;
import org.sonar.server.computation.step.ComputationSteps;
import org.sonar.server.db.DbClient;
+import java.io.File;
+import java.io.IOException;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
@@ -46,62 +76,97 @@ public class ComputationServiceTest {
@ClassRule
public static DbTester dbTester = new DbTester();
+ @Rule
+ public JUnitTempFolder tempFolder = new JUnitTempFolder();
+
+ @Rule
+ public LogTester logTester = new LogTester();
+
ComputationStep projectStep1 = mockStep(Qualifiers.PROJECT);
ComputationStep projectStep2 = mockStep(Qualifiers.PROJECT);
ComputationStep viewStep = mockStep(Qualifiers.VIEW);
ComputationSteps steps = mock(ComputationSteps.class);
ActivityService activityService = mock(ActivityService.class);
+ System2 system = mock(System2.class);
+ ComputationService sut;
@Before
public void setUp() throws Exception {
- dbTester.truncateTables();
+ DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+ sut = new ComputationService(dbClient, steps, activityService, tempFolder, system);
+
+ // db contains project with key "P1"
+ dbTester.prepareDbUnit(getClass(), "shared.xml");
}
@Test
public void process_project() throws Exception {
- // db contains project with key "PROJECT_KEY"
- dbTester.prepareDbUnit(getClass(), "shared.xml");
- DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+ logTester.setLevel(LoggerLevel.INFO);
+ // view step is not supposed to be executed
when(steps.orderedSteps()).thenReturn(Arrays.asList(projectStep1, projectStep2, viewStep));
+ AnalysisReportDto dto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1");
+ File zip = generateZip();
+
+ sut.process(new ReportQueue.Item(dto, zip));
- // load report from db and parse it
- ComputationService sut = new ComputationService(dbClient, steps, activityService);
- AnalysisReportDto report = AnalysisReportDto.newForTests(1L);
- report.setProjectKey("PROJECT_KEY");
- assertThat(report.getStatus()).isNull();
- sut.process(report);
+ // report is integrated -> status is set to SUCCESS
+ assertThat(dto.getStatus()).isEqualTo(AnalysisReportDto.Status.SUCCESS);
+ assertThat(dto.getFinishedAt()).isNotNull();
- // status of report is set
- assertThat(report.getStatus()).isEqualTo(AnalysisReportDto.Status.SUCCESS);
+ // 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(viewStep, never()).execute(any(ComputationContext.class));
- verify(activityService).write(any(DbSession.class), eq(Activity.Type.ANALYSIS_REPORT), any(AnalysisReportLog.class));
+ verify(activityService).write(any(DbSession.class), eq(Activity.Type.ANALYSIS_REPORT), any(ReportActivity.class));
}
@Test
- public void fail_to_parse_report() throws Exception {
- // db contains project with key "PROJECT_KEY"
- dbTester.prepareDbUnit(getClass(), "shared.xml");
- DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+ public void debug_logs() throws Exception {
+ logTester.setLevel(LoggerLevel.DEBUG);
+
+ AnalysisReportDto dto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1");
+ File zip = generateZip();
+ sut.process(new ReportQueue.Item(dto, zip));
+ assertThat(logTester.logs(LoggerLevel.DEBUG)).isNotEmpty();
+ }
+
+ @Test
+ public void fail_if_corrupted_zip() throws Exception {
+ AnalysisReportDto dto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1");
+ File zip = tempFolder.newFile();
+ FileUtils.write(zip, "not a file");
+
+ try {
+ sut.process(new ReportQueue.Item(dto, zip));
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).startsWith("Fail to unzip " + zip.getAbsolutePath() + " into ");
+ assertThat(dto.getStatus()).isEqualTo(AnalysisReportDto.Status.FAILED);
+ assertThat(dto.getFinishedAt()).isNotNull();
+ }
+ }
+
+ @Test
+ public void step_error() throws Exception {
when(steps.orderedSteps()).thenReturn(Arrays.asList(projectStep1));
- doThrow(new UnsupportedOperationException()).when(projectStep1).execute(any(ComputationContext.class));
+ doThrow(new IllegalStateException("pb")).when(projectStep1).execute(any(ComputationContext.class));
+
+ AnalysisReportDto dto = AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1");
+ File zip = generateZip();
- // load report from db and parse it
- ComputationService sut = new ComputationService(dbClient, steps, activityService);
- AnalysisReportDto report = AnalysisReportDto.newForTests(1L);
- report.setProjectKey("PROJECT_KEY");
try {
- sut.process(report);
+ sut.process(new ReportQueue.Item(dto, zip));
fail();
- } catch (UnsupportedOperationException e) {
- // status of report is set
- assertThat(report.getStatus()).isEqualTo(AnalysisReportDto.Status.FAILED);
- verify(activityService).write(any(DbSession.class), eq(Activity.Type.ANALYSIS_REPORT), any(AnalysisReportLog.class));
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).isEqualTo("pb");
+ assertThat(dto.getStatus()).isEqualTo(AnalysisReportDto.Status.FAILED);
+ assertThat(dto.getFinishedAt()).isNotNull();
}
}
@@ -111,4 +176,17 @@ public class ComputationServiceTest {
when(step.getDescription()).thenReturn(RandomStringUtils.randomAscii(5));
return step;
}
+
+ private File generateZip() throws IOException {
+ File dir = tempFolder.newDir();
+ BatchOutputWriter writer = new BatchOutputWriter(dir);
+ writer.writeMetadata(BatchReport.Metadata.newBuilder()
+ .setRootComponentRef(1)
+ .setProjectKey("PROJECT_KEY")
+ .setAnalysisDate(150000000L)
+ .build());
+ File zip = tempFolder.newFile();
+ ZipUtils.zipDir(dir, zip);
+ return zip;
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadLauncherTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadLauncherTest.java
index 61379a03b03..09f80a61872 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadLauncherTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadLauncherTest.java
@@ -39,11 +39,11 @@ public class ComputationThreadLauncherTest {
public TestRule timeout = new DisableOnDebug(Timeout.seconds(5));
ComputationThreadLauncher sut;
- AnalysisReportQueue queue;
+ ReportQueue queue;
@Before
public void before() {
- this.queue = mock(AnalysisReportQueue.class);
+ this.queue = mock(ReportQueue.class);
}
@After
@@ -74,6 +74,12 @@ public class ComputationThreadLauncherTest {
verify(queue, atLeastOnce()).pop();
}
+ @Test
+ public void test_real_constructor() throws Exception {
+ sut = new ComputationThreadLauncher(queue);
+ sut.start();
+ }
+
private void sleep() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(500L);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadTest.java
index d3ecf46306e..43cac0b1700 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ComputationThreadTest.java
@@ -20,44 +20,81 @@
package org.sonar.server.computation;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.utils.log.LogTester;
import org.sonar.core.computation.db.AnalysisReportDto;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
public class ComputationThreadTest {
- private ComputationThread sut;
- private AnalysisReportQueue queue;
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
- @Before
- public void before() {
- this.queue = mock(AnalysisReportQueue.class);
- this.sut = new ComputationThread(queue);
- }
+ @Rule
+ public LogTester logTester = new LogTester();
+
+ ComputationContainer container = mock(ComputationContainer.class);
+ ReportQueue queue = mock(ReportQueue.class);
+ ComputationThread sut = new ComputationThread(queue, container);
@Test
- public void call_findAndBook_and_no_call_to_analyze_if_no_report_found() {
+ public void do_nothing_if_queue_empty() {
+ when(queue.pop()).thenReturn(null);
+
sut.run();
verify(queue).pop();
+ verifyZeroInteractions(container);
}
@Test
- public void call_findAndBook_and_then_analyze_if_there_is_a_report() {
+ public void pop_queue_and_integrate_report() throws IOException {
AnalysisReportDto report = AnalysisReportDto.newForTests(1L);
- when(queue.pop()).thenReturn(report);
+ ReportQueue.Item item = new ReportQueue.Item(report, temp.newFile());
+ when(queue.pop()).thenReturn(item);
sut.run();
verify(queue).pop();
+ verify(container).execute(item);
}
@Test
- public void when_the_analysis_throws_an_exception_it_does_not_break_the_task() throws Exception {
+ public void handle_error_during_queue_pop() throws Exception {
when(queue.pop()).thenThrow(new IllegalStateException());
sut.run();
+
+ assertThat(logTester.logs()).contains("Failed to pop the queue of analysis reports");
+ }
+
+ @Test
+ public void handle_error_during_integration() throws Exception {
+ AnalysisReportDto report = AnalysisReportDto.newForTests(1L).setProjectKey("P1");
+ ReportQueue.Item item = new ReportQueue.Item(report, temp.newFile());
+ when(queue.pop()).thenReturn(item);
+ doThrow(new IllegalStateException("pb")).when(container).execute(item);
+
+ sut.run();
+
+ assertThat(logTester.logs()).contains("Failed to process analysis report 1 of project P1");
+ }
+
+ @Test
+ public void handle_error_during_removal_from_queue() throws Exception {
+ AnalysisReportDto report = AnalysisReportDto.newForTests(1L).setProjectKey("P1");
+ ReportQueue.Item item = new ReportQueue.Item(report, temp.newFile());
+ when(queue.pop()).thenReturn(item);
+ doThrow(new IllegalStateException("pb")).when(queue).remove(item);
+
+ sut.run();
+
+ assertThat(logTester.logs()).contains("Failed to remove analysis report 1 from queue");
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportLogMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportActivityTest.java
index 986a364c59c..82ca71f828a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportLogMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportActivityTest.java
@@ -20,48 +20,18 @@
package org.sonar.server.computation;
-import com.google.common.collect.Iterables;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
-import org.sonar.core.activity.Activity;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.server.activity.ActivityService;
-import org.sonar.server.activity.index.ActivityIndex;
import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.tester.ServerTester;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.core.activity.Activity.Type.ANALYSIS_REPORT;
import static org.sonar.core.computation.db.AnalysisReportDto.Status.FAILED;
-public class AnalysisReportLogMediumTest {
- @ClassRule
- public static ServerTester tester = new ServerTester();
-
- private ActivityService service = tester.get(ActivityService.class);
- private ActivityIndex index = tester.get(ActivityIndex.class);
- private DbSession dbSession;
-
- private AnalysisReportLog sut;
-
- @Before
- public void before() {
- tester.clearDbAndIndexes();
- dbSession = tester.get(DbClient.class).openSession(false);
- }
-
- @After
- public void after() {
- dbSession.close();
- }
+public class ReportActivityTest {
@Test
public void insert_find_analysis_report_log() {
@@ -74,15 +44,9 @@ public class AnalysisReportLogMediumTest {
.setFinishedAt(DateUtils.parseDate("2014-10-18").getTime());
ComponentDto project = ComponentTesting.newProjectDto();
- service.write(dbSession, ANALYSIS_REPORT, new AnalysisReportLog(report, project));
- dbSession.commit();
-
- // 0. AssertBase case
- assertThat(index.findAll().getHits()).hasSize(1);
+ ReportActivity activity = new ReportActivity(report, project);
- Activity activity = Iterables.getFirst(index.findAll().getHits(), null);
- assertThat(activity).isNotNull();
- Map<String, String> details = activity.details();
+ Map<String, String> details = activity.getDetails();
assertThat(details.get("key")).isEqualTo(String.valueOf(report.getId()));
assertThat(details.get("projectKey")).isEqualTo(project.key());
assertThat(details.get("projectName")).isEqualTo(project.name());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueCleanerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueCleanerTest.java
index 1a8f5aa55ad..dde45514bd4 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/AnalysisReportQueueCleanerTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueCleanerTest.java
@@ -20,48 +20,29 @@
package org.sonar.server.computation;
-import org.junit.Before;
import org.junit.Test;
import org.sonar.api.platform.ServerUpgradeStatus;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.server.computation.db.AnalysisReportDao;
-import org.sonar.server.db.DbClient;
import static org.mockito.Mockito.*;
-public class AnalysisReportQueueCleanerTest {
+public class ReportQueueCleanerTest {
- AnalysisReportQueueCleaner sut;
- ServerUpgradeStatus serverUpgradeStatus;
- DbClient dbClient;
- AnalysisReportDao analysisReportDao;
- DbSession session;
-
- @Before
- public void before() {
- analysisReportDao = mock(AnalysisReportDao.class);
- serverUpgradeStatus = mock(ServerUpgradeStatus.class);
- dbClient = mock(DbClient.class);
- session = mock(DbSession.class);
-
- when(dbClient.analysisReportDao()).thenReturn(analysisReportDao);
- when(dbClient.openSession(false)).thenReturn(session);
-
- sut = new AnalysisReportQueueCleaner(serverUpgradeStatus, dbClient);
- }
+ ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class);
+ ReportQueue queue = mock(ReportQueue.class);
+ ReportQueueCleaner sut = new ReportQueueCleaner(serverUpgradeStatus, queue);
@Test
- public void start_must_call_dao_clean_update_to_pending_by_default() {
+ public void reset_reports_on_restart() {
sut.start();
- verify(analysisReportDao).resetAllToPendingStatus(any(DbSession.class));
+ verify(queue).resetToPendingStatus();
sut.stop();
}
@Test
- public void start_must_call_dao_truncate_when_upgrading() {
+ public void delete_all_reports_on_upgrade() {
when(serverUpgradeStatus.isUpgraded()).thenReturn(Boolean.TRUE);
sut.start();
- verify(analysisReportDao).truncate(any(DbSession.class));
+ verify(queue).clear();
sut.stop();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueTest.java
new file mode 100644
index 00000000000..6db7d0c9eb8
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportQueueTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.System2;
+import org.sonar.core.computation.db.AnalysisReportDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.process.ProcessConstants;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.computation.db.AnalysisReportDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.test.DbTests;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING;
+import static org.sonar.core.computation.db.AnalysisReportDto.Status.WORKING;
+
+@Category(DbTests.class)
+public class ReportQueueTest {
+
+ static final long NOW = 1_500_000_000_000L;
+
+ @Rule
+ public DbTester dbTester = new DbTester();
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ Settings settings = new Settings();
+ File dataDir;
+ System2 system = mock(System2.class);
+ ReportQueue sut;
+
+ @Before
+ public void setUp() throws Exception {
+ dataDir = temp.newFolder();
+ settings.setProperty(ProcessConstants.PATH_DATA, dataDir.getAbsolutePath());
+ when(system.now()).thenReturn(NOW);
+
+ DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new AnalysisReportDao(system));
+ sut = new ReportQueue(dbClient, settings);
+
+ try (DbSession session = dbClient.openSession(false)) {
+ dbClient.componentDao().insert(session, ComponentTesting.newProjectDto().setKey("P1"));
+ dbClient.componentDao().insert(session, ComponentTesting.newProjectDto().setKey("P2"));
+ dbClient.componentDao().insert(session, ComponentTesting.newProjectDto().setKey("P3"));
+ session.commit();
+ }
+ }
+
+ @Test
+ public void add_report_to_queue() throws IOException {
+ // must:
+ // 1. insert metadata in db
+ // 2. copy report content to directory /data/analysis
+ ReportQueue.Item item = sut.add("P1", generateData());
+
+ assertThat(item).isNotNull();
+ assertThat(item.zipFile).isFile().exists().hasContent("some data").hasParent(new File(dataDir, "analysis"));
+ assertThat(item.dto.getUuid()).isNotEmpty();
+ assertThat(item.dto.getId()).isGreaterThan(0L);
+
+ List<AnalysisReportDto> reports = sut.findByProjectKey("P1");
+ assertThat(reports).hasSize(1);
+ AnalysisReportDto report = reports.get(0);
+
+ assertThat(reports).hasSize(1);
+ assertThat(report.getStatus()).isEqualTo(PENDING);
+ assertThat(report.getProjectKey()).isEqualTo("P1");
+ assertThat(report.getUuid()).isNotEmpty();
+ assertThat(report.getId()).isGreaterThan(0L);
+ assertThat(report.getCreatedAt()).isEqualTo(NOW);
+ assertThat(report.getUpdatedAt()).isEqualTo(NOW);
+ assertThat(report.getStartedAt()).isNull();
+ assertThat(report.getFinishedAt()).isNull();
+
+ assertThat(FileUtils.listFiles(analysisDir(), new String[] {"zip"}, false)).hasSize(1);
+ }
+
+ @Test
+ public void find_by_project_key() throws Exception {
+ sut.add("P1", generateData());
+ assertThat(sut.findByProjectKey("P1")).hasSize(1).extracting("projectKey").containsExactly("P1");
+ assertThat(sut.findByProjectKey("P2")).isEmpty();
+ }
+
+ @Test
+ public void pop_pending_items_in_fifo_order() {
+ sut.add("P1", generateData());
+ sut.add("P2", generateData());
+ sut.add("P3", generateData());
+
+ ReportQueue.Item item = sut.pop();
+ assertThat(item.dto.getProjectKey()).isEqualTo("P1");
+ assertThat(item.zipFile).exists().isFile().hasExtension("zip");
+
+ // status changed from PENDING to WORKING
+ assertThat(item.dto.getStatus()).isEqualTo(WORKING);
+
+ assertThat(sut.pop().dto.getProjectKey()).isEqualTo("P2");
+ assertThat(sut.pop().dto.getProjectKey()).isEqualTo("P3");
+
+ // queue is empty
+ assertThat(sut.pop()).isNull();
+
+ // items are still in db, but in WORKING status
+ List<AnalysisReportDto> reports = sut.all();
+ assertThat(reports).hasSize(3);
+ assertThat(reports).extracting("status").containsOnly(WORKING);
+ }
+
+ @Test
+ public void remove() {
+ ReportQueue.Item item = sut.add("P1", generateData());
+ assertThat(dbTester.countRowsOfTable("analysis_reports")).isEqualTo(1);
+
+ sut.remove(item);
+ assertThat(dbTester.countRowsOfTable("analysis_reports")).isEqualTo(0);
+ assertThat(item.zipFile).doesNotExist();
+ }
+
+ @Test
+ public void do_not_pop_corrupted_item() throws Exception {
+ ReportQueue.Item item = sut.add("P1", generateData());
+
+ // emulate corruption: file is missing on FS
+ FileUtils.deleteQuietly(item.zipFile);
+
+ assertThat(sut.pop()).isNull();
+
+ // table sanitized
+ assertThat(dbTester.countRowsOfTable("analysis_reports")).isEqualTo(0);
+ }
+
+ @Test
+ public void clear() throws Exception {
+ sut.add("P1", generateData());
+ sut.add("P2", generateData());
+ assertThat(analysisDir()).exists().isDirectory();
+
+ sut.clear();
+
+ assertThat(dbTester.countRowsOfTable("analysis_reports")).isEqualTo(0);
+ assertThat(analysisDir()).doesNotExist();
+ }
+
+ @Test
+ public void reset_to_pending_status() throws Exception {
+ // 2 pending
+ sut.add("P1", generateData());
+ sut.add("P2", generateData());
+
+ // pop 1 -> 1 pending and 1 working
+ ReportQueue.Item workingItem = sut.pop();
+ assertThat(workingItem.dto.getStatus()).isEqualTo(WORKING);
+ assertThat(sut.all()).extracting("status").contains(PENDING, WORKING);
+
+ sut.resetToPendingStatus();
+ assertThat(sut.all()).extracting("status").containsOnly(PENDING).hasSize(2);
+
+ }
+
+ private InputStream generateData() {
+ return IOUtils.toInputStream("some data");
+ }
+
+ private File analysisDir() {
+ return new File(dataDir, "analysis");
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/db/AnalysisReportDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/db/AnalysisReportDaoTest.java
index eddb4326798..bf4456f66ab 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/db/AnalysisReportDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/db/AnalysisReportDaoTest.java
@@ -20,8 +20,11 @@
package org.sonar.server.computation.db;
-import org.apache.commons.io.IOUtils;
-import org.junit.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.utils.System2;
@@ -31,8 +34,6 @@ import org.sonar.core.persistence.DbTester;
import org.sonar.core.persistence.MyBatis;
import org.sonar.test.DbTests;
-import java.io.File;
-import java.io.InputStream;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@@ -46,7 +47,6 @@ import static org.sonar.core.computation.db.AnalysisReportDto.Status.WORKING;
public class AnalysisReportDaoTest {
private static final String DEFAULT_PROJECT_KEY = "123456789-987654321";
- private static final long DEFAULT_SNAPSHOT_ID = 123L;
@ClassRule
public static DbTester db = new DbTester();
@@ -54,13 +54,12 @@ public class AnalysisReportDaoTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- private AnalysisReportDao sut;
- private DbSession session;
- private System2 system2;
+ AnalysisReportDao sut;
+ DbSession session;
+ System2 system2;
@Before
public void before() {
- db.truncateTables();
this.session = db.myBatis().openSession(false);
this.system2 = mock(System2.class);
this.sut = new AnalysisReportDao(system2);
@@ -78,8 +77,8 @@ public class AnalysisReportDaoTest {
public void insert_multiple_reports() throws Exception {
db.prepareDbUnit(getClass(), "empty.xml");
- AnalysisReportDto report1 = newDefaultAnalysisReport();
- AnalysisReportDto report2 = newDefaultAnalysisReport();
+ AnalysisReportDto report1 = newDefaultAnalysisReport().setUuid("UUID_1");
+ AnalysisReportDto report2 = newDefaultAnalysisReport().setUuid("UUID_2");
sut.insert(session, report1);
sut.insert(session, report2);
@@ -89,15 +88,6 @@ public class AnalysisReportDaoTest {
}
@Test
- public void insert_report_data_do_not_throw_exception() throws Exception {
- db.prepareDbUnit(getClass(), "empty.xml");
- AnalysisReportDto report = newDefaultAnalysisReport()
- .setData(getClass().getResource("/org/sonar/server/computation/db/AnalysisReportDaoTest/zip.zip").openStream());
-
- sut.insert(session, report);
- }
-
- @Test
public void resetAllToPendingStatus() {
db.prepareDbUnit(getClass(), "update-all-to-status-pending.xml");
@@ -171,8 +161,6 @@ public class AnalysisReportDaoTest {
assertThat(report.getStartedAt()).isEqualTo(parseDate("2014-09-26").getTime());
assertThat(report.getFinishedAt()).isEqualTo(parseDate("2014-09-27").getTime());
assertThat(report.getStatus()).isEqualTo(WORKING);
- assertThat(report.getData()).isNull();
- assertThat(report.getKey()).isEqualTo("1");
}
@Test
@@ -221,31 +209,10 @@ public class AnalysisReportDaoTest {
assertThat(reports).hasSize(3);
}
- @Test
- public void insert_and_then_retrieve_report_data_with_decompressed_files_medium_test() throws Exception {
- // ARRANGE
- db.prepareDbUnit(getClass(), "empty.xml");
- AnalysisReportDto report = newDefaultAnalysisReport();
- InputStream zip = getClass().getResource("/org/sonar/server/computation/db/AnalysisReportDaoTest/zip.zip").openStream();
- report.setData(zip);
-
- File toDir = temp.newFolder();
- sut.insert(session, report);
- session.commit();
- IOUtils.closeQuietly(zip);
-
- // ACT
- sut.selectAndDecompressToDir(session, 1L, toDir);
-
- // ASSERT
- assertThat(toDir.list()).hasSize(3);
- }
-
private AnalysisReportDto newDefaultAnalysisReport() {
return AnalysisReportDto.newForTests(1L)
.setProjectKey(DEFAULT_PROJECT_KEY)
- .setSnapshotId(DEFAULT_SNAPSHOT_ID)
- .setData(null)
+ .setUuid("REPORT_UUID")
.setStatus(PENDING);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java
index a7554148090..938a2d49d48 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java
@@ -20,17 +20,25 @@
package org.sonar.server.computation.step;
import org.junit.Test;
+import org.sonar.server.computation.ComputationContext;
import org.sonar.server.issue.index.IssueAuthorizationIndexer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-public class ApplyPermissionsStepTest {
+public class ApplyPermissionsStepTest extends BaseStepTest {
+
+ IssueAuthorizationIndexer indexer = mock(IssueAuthorizationIndexer.class);
+ ApplyPermissionsStep step = new ApplyPermissionsStep(indexer);
@Test
public void index_issue_permissions() throws Exception {
- IssueAuthorizationIndexer indexer = mock(IssueAuthorizationIndexer.class);
- new ApplyPermissionsStep(indexer).execute(null);
+ step.execute(mock(ComputationContext.class));
verify(indexer).index();
}
+
+ @Override
+ protected ComputationStep step() {
+ return step;
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/BaseStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/BaseStepTest.java
new file mode 100644
index 00000000000..6515c697fe7
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/BaseStepTest.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.step;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Temporary solution to test metadata. Should be replaced by a medium test of
+ * all computation stack
+ */
+public abstract class BaseStepTest {
+
+ protected abstract ComputationStep step() throws IOException;
+
+ @Test
+ public void test_metadata() throws Exception {
+ assertThat(step().toString()).isNotEmpty();
+ assertThat(step().supportedProjectQualifiers().length).isGreaterThan(0);
+
+ }
+}
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 bd6fb0263d8..ccb4223c2a5 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,10 +20,9 @@
package org.sonar.server.computation.step;
-import org.junit.Before;
import org.junit.Test;
+import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.computation.ComputationContext;
@@ -31,26 +30,24 @@ import java.io.IOException;
import static org.mockito.Mockito.*;
-public class IndexComponentsStepTest {
+public class IndexComponentsStepTest extends BaseStepTest {
- IndexComponentsStep sut;
- ResourceIndexerDao resourceIndexerDao;
-
- @Before
- public void before() {
- this.resourceIndexerDao = mock(ResourceIndexerDao.class);
- this.sut = new IndexComponentsStep(resourceIndexerDao);
- }
+ ResourceIndexerDao resourceIndexerDao = mock(ResourceIndexerDao.class);
+ IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao);
@Test
public void call_indexProject_of_dao() throws IOException {
ComponentDto project = mock(ComponentDto.class);
when(project.getId()).thenReturn(123L);
- ComputationContext context = new ComputationContext(mock(AnalysisReportDto.class), project);
+ ComputationContext context = new ComputationContext(mock(BatchReportReader.class), project);
sut.execute(context);
verify(resourceIndexerDao).indexProject(123L);
}
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
}
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
new file mode 100644
index 00000000000..fb0042ba9ea
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.step;
+
+import org.junit.Test;
+import org.sonar.server.source.index.SourceLineIndexer;
+
+import java.io.IOException;
+
+import static org.mockito.Mockito.mock;
+
+public class IndexSourceLinesStepTest extends BaseStepTest {
+
+ @Test
+ public void supportedProjectQualifiers() throws Exception {
+
+ }
+
+ @Override
+ protected ComputationStep step() throws IOException {
+ return new IndexSourceLinesStep(mock(SourceLineIndexer.class));
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexViewsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexViewsStepTest.java
index 8c8fbd5409f..fc1c913232a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexViewsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexViewsStepTest.java
@@ -28,7 +28,7 @@ import org.sonar.server.view.index.ViewIndexer;
import static org.mockito.Mockito.*;
-public class IndexViewsStepTest {
+public class IndexViewsStepTest extends BaseStepTest {
ComputationContext context = mock(ComputationContext.class);
ViewIndexer indexer = mock(ViewIndexer.class);
@@ -43,4 +43,8 @@ public class IndexViewsStepTest {
verify(indexer).index("ABCD");
}
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
}
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 2d3c8204029..fe354e79ff7 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
@@ -19,27 +19,20 @@
*/
package org.sonar.server.computation.step;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.ZipUtils;
-import org.sonar.api.utils.internal.DefaultTempFolder;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchOutputWriter;
import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.computation.db.AnalysisReportDao;
import org.sonar.server.computation.issue.IssueComputation;
-import org.sonar.server.db.DbClient;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
@@ -47,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-public class ParseReportStepTest {
+public class ParseReportStepTest extends BaseStepTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@@ -55,21 +48,15 @@ public class ParseReportStepTest {
@ClassRule
public static DbTester dbTester = new DbTester();
- @Before
- public void setUp() throws Exception {
- dbTester.truncateTables();
- }
+ IssueComputation issueComputation = mock(IssueComputation.class);
+ ParseReportStep sut = new ParseReportStep(issueComputation);
@Test
public void extract_report_from_db_and_browse_components() throws Exception {
- AnalysisReportDto reportDto = prepareAnalysisReportInDb();
-
+ File reportDir = generateReport();
- IssueComputation issueComputation = mock(IssueComputation.class);
- DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new AnalysisReportDao());
- ParseReportStep step = new ParseReportStep(issueComputation, dbClient, new DefaultTempFolder(temp.newFolder()));
- ComputationContext context = new ComputationContext(reportDto, mock(ComponentDto.class));
- step.execute(context);
+ ComputationContext context = new ComputationContext(new BatchReportReader(reportDir), mock(ComponentDto.class));
+ sut.execute(context);
// verify that all components are processed (currently only for issues)
verify(issueComputation).processComponentIssues(context, "PROJECT_UUID", Collections.<BatchReport.Issue>emptyList());
@@ -79,7 +66,7 @@ public class ParseReportStepTest {
assertThat(context.getReportMetadata().getRootComponentRef()).isEqualTo(1);
}
- private AnalysisReportDto prepareAnalysisReportInDb() throws IOException {
+ private File generateReport() throws IOException {
File dir = temp.newFolder();
// project and 2 files
BatchOutputWriter writer = new BatchOutputWriter(dir);
@@ -105,28 +92,11 @@ public class ParseReportStepTest {
.setType(Constants.ComponentType.FILE)
.setUuid("FILE2_UUID")
.build());
- File zipFile = temp.newFile();
- ZipUtils.zipDir(dir, zipFile);
-
- AnalysisReportDto dto = new AnalysisReportDto();
- DbSession dbSession = dbTester.myBatis().openSession(false);
- try {
- dto.setProjectKey("PROJECT_KEY");
- dto.setCreatedAt(System.currentTimeMillis());
- dto.setSnapshotId(1L);
- dto.setStatus(AnalysisReportDto.Status.PENDING);
- FileInputStream inputStream = new FileInputStream(zipFile);
- dto.setData(inputStream);
- AnalysisReportDao dao = new AnalysisReportDao();
- dao.insert(dbSession, dto);
- inputStream.close();
- dbSession.commit();
+ return dir;
+ }
- // dao#insert() does not set the generated id, so the row
- // is loaded again to get its id
- return dao.selectByProjectKey(dbSession, "PROJECT_KEY").get(0);
- } finally {
- dbSession.close();
- }
+ @Override
+ protected ComputationStep step() {
+ return sut;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepMediumTest.java
deleted file mode 100644
index 004265d841c..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepMediumTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.computation.step;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.component.SnapshotDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.computation.db.AnalysisReportDto.Status;
-import org.sonar.core.computation.dbcleaner.DbCleanerConstants;
-import org.sonar.core.computation.dbcleaner.ProjectCleaner;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.properties.PropertyDto;
-import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
-import org.sonar.server.computation.ComputationContext;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.tester.ServerTester;
-
-import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class PurgeDatastoresStepMediumTest {
-
- @ClassRule
- public static ServerTester tester = new ServerTester();
-
- private PurgeDatastoresStep sut;
- private DbClient dbClient;
- private DbSession dbSession;
- private ProjectCleaner purgeTask;
-
- @Before
- public void before() throws Exception {
- this.dbClient = tester.get(DbClient.class);
- this.dbSession = dbClient.openSession(false);
-
- this.purgeTask = tester.get(ProjectCleaner.class);
-
- this.sut = new PurgeDatastoresStep(dbClient, purgeTask);
- }
-
- @After
- public void after() throws Exception {
- MyBatis.closeQuietly(dbSession);
- }
-
- @Test
- public void use_global_settings_when_no_other_specified() throws Exception {
- // ARRANGE
- Date now = new Date();
- Date aWeekAgo = DateUtils.addDays(now, -7);
-
- ComponentDto project = ComponentTesting.newProjectDto()
- .setId(1L)
- .setKey("123")
- .setCreatedAt(aWeekAgo)
- .setUpdatedAt(aWeekAgo);
- dbClient.componentDao().insert(dbSession, project);
-
- SnapshotDto snapshot = SnapshotTesting.createForProject(project)
- .setCreatedAt(aWeekAgo.getTime());
- dbClient.snapshotDao().insert(dbSession, snapshot);
-
- AnalysisReportDto report = AnalysisReportDto.newForTests(1L)
- .setProjectKey("123")
- .setSnapshotId(snapshot.getId())
- .setStatus(Status.PENDING);
- dbClient.analysisReportDao().insert(dbSession, report);
-
- dbClient.propertiesDao().setProperty(new PropertyDto().setKey(DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS).setValue("52"));
- dbSession.commit();
- ComputationContext context = new ComputationContext(report, project);
-
- // ACT
- sut.execute(context);
-
- // ASSERT
- assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshot.getId())).isNotNull();
- }
-
- @Test
- public void use_project_settings_if_specified() throws Exception {
- // ARRANGE
- Date now = new Date();
- Date twoWeeksAgo = DateUtils.addDays(now, -2 * 7);
- Date aLongTimeAgo = DateUtils.addDays(now, -365 * 7);
-
- ComponentDto project = ComponentTesting.newProjectDto()
- .setKey("123")
- .setCreatedAt(aLongTimeAgo)
- .setUpdatedAt(aLongTimeAgo);
- dbClient.componentDao().insert(dbSession, project);
-
- SnapshotDto snapshot = SnapshotTesting.createForProject(project)
- .setCreatedAt(twoWeeksAgo.getTime())
- .setStatus("P")
- .setLast(true);
-
- dbClient.snapshotDao().insert(dbSession, snapshot);
-
- AnalysisReportDto report = new AnalysisReportDto()
- .setProjectKey("123")
- .setSnapshotId(snapshot.getId())
- .setStatus(Status.PENDING);
- dbClient.analysisReportDao().insert(dbSession, report);
-
- dbClient.propertiesDao().setProperty(new PropertyDto().setKey(DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS).setValue("4"));
- dbClient.propertiesDao().setProperty(new PropertyDto().setKey(DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS).setValue("1").setResourceId(project.getId()));
- dbSession.commit();
- ComputationContext context = new ComputationContext(report, project);
-
- // ACT
- sut.execute(context);
- dbSession.commit();
-
- // ASSERT
- assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshot.getId())).isNull();
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
index a98bb1ddb00..bcf9fccc33c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
@@ -20,13 +20,12 @@
package org.sonar.server.computation.step;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
+import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.computation.dbcleaner.ProjectCleaner;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.purge.IdUuidPair;
@@ -38,30 +37,28 @@ import java.io.IOException;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
-public class PurgeDatastoresStepTest {
+public class PurgeDatastoresStepTest extends BaseStepTest {
- PurgeDatastoresStep sut;
- ProjectCleaner projectCleaner;
+ ProjectCleaner projectCleaner = mock(ProjectCleaner.class);;
+ PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner);
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- @Before
- public void before() {
- this.projectCleaner = mock(ProjectCleaner.class);
-
- this.sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner);
- }
-
@Test
public void call_purge_method_of_the_purge_task() throws IOException {
ComponentDto project = mock(ComponentDto.class);
when(project.getId()).thenReturn(123L);
when(project.uuid()).thenReturn("UUID-1234");
- ComputationContext context = new ComputationContext(mock(AnalysisReportDto.class), project);
+ ComputationContext context = new ComputationContext(mock(BatchReportReader.class), project);
sut.execute(context);
verify(projectCleaner).purge(any(DbSession.class), any(IdUuidPair.class));
}
+
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java
index 0fd843bf5ca..a490894a654 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java
@@ -23,6 +23,7 @@ package org.sonar.server.computation.step;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Qualifiers;
@@ -45,31 +46,25 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class PurgeRemovedViewsStepTest {
+public class PurgeRemovedViewsStepTest extends BaseStepTest {
@ClassRule
public static EsTester esTester = new EsTester().addDefinitions(new ViewIndexDefinition(new Settings()));
- @ClassRule
- public static DbTester db = new DbTester();
-
- ComputationContext context;
+ @Rule
+ public DbTester db = new DbTester();
+ ComputationContext context = mock(ComputationContext.class);
DbSession session;
-
DbClient dbClient;
-
- PurgeRemovedViewsStep step;
+ PurgeRemovedViewsStep sut;
@Before
public void setUp() {
esTester.truncateIndices();
- db.truncateTables();
-
- context = mock(ComputationContext.class);
session = db.myBatis().openSession(false);
dbClient = new DbClient(db.database(), db.myBatis(), new IssueDao(db.myBatis()), new ComponentDao());
- step = new PurgeRemovedViewsStep(new ViewIndex(esTester.client()), dbClient);
+ sut = new PurgeRemovedViewsStep(new ViewIndex(esTester.client()), dbClient);
}
@After
@@ -92,7 +87,7 @@ public class PurgeRemovedViewsStepTest {
dbClient.componentDao().insert(session, view, subView);
session.commit();
- step.execute(context);
+ sut.execute(context);
List<String> viewUuids = esTester.getDocumentFields(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, ViewIndexDefinition.FIELD_UUID);
assertThat(viewUuids).containsOnly("ABCD", "BCDE");
@@ -100,7 +95,11 @@ public class PurgeRemovedViewsStepTest {
@Test
public void only_support_views() throws Exception {
- assertThat(step.supportedProjectQualifiers()).containsOnly(Qualifiers.VIEW);
+ assertThat(sut.supportedProjectQualifiers()).containsOnly(Qualifiers.VIEW);
}
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
}
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 9f0f7b982d7..e0797f9ee94 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
@@ -19,6 +19,7 @@
*/
package org.sonar.server.computation.step;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -35,10 +36,12 @@ import org.sonar.server.issue.notification.IssueChangeNotification;
import org.sonar.server.issue.notification.NewIssuesNotification;
import org.sonar.server.notifications.NotificationService;
+import java.io.IOException;
+
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
-public class SendIssueNotificationsStepTest {
+public class SendIssueNotificationsStepTest extends BaseStepTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@@ -46,32 +49,41 @@ public class SendIssueNotificationsStepTest {
RuleCache ruleCache = mock(RuleCache.class);
NotificationService notifService = mock(NotificationService.class);
ComputationContext context = mock(ComputationContext.class, Mockito.RETURNS_DEEP_STUBS);
+ IssueCache issueCache;
+ SendIssueNotificationsStep sut;
+
+ @Before
+ public void setUp() throws Exception {
+ issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
+ sut = new SendIssueNotificationsStep(issueCache, ruleCache, notifService);
+ }
@Test
public void do_not_send_notifications_if_no_subscribers() throws Exception {
- IssueCache issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
when(context.getProject().uuid()).thenReturn("PROJECT_UUID");
when(notifService.hasProjectSubscribersForTypes("PROJECT_UUID", SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(false);
- SendIssueNotificationsStep step = new SendIssueNotificationsStep(issueCache, ruleCache, notifService);
- step.execute(context);
+ sut.execute(context);
verify(notifService, never()).deliver(any(Notification.class));
}
@Test
public void send_notifications_if_subscribers() throws Exception {
- IssueCache issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
issueCache.newAppender().append(new DefaultIssue().setSeverity(Severity.BLOCKER)).close();
when(context.getProject().uuid()).thenReturn("PROJECT_UUID");
when(context.getReportMetadata()).thenReturn(BatchReport.Metadata.newBuilder().build());
when(notifService.hasProjectSubscribersForTypes("PROJECT_UUID", SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);
- SendIssueNotificationsStep step = new SendIssueNotificationsStep(issueCache, ruleCache, notifService);
- step.execute(context);
+ sut.execute(context);
verify(notifService).deliver(any(NewIssuesNotification.class));
verify(notifService, atLeastOnce()).deliver(any(IssueChangeNotification.class));
}
+
+ @Override
+ protected ComputationStep step() throws IOException {
+ return sut;
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SwitchSnapshotStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SwitchSnapshotStepTest.java
index dbf46f40a74..cc4dfa9be6b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SwitchSnapshotStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SwitchSnapshotStepTest.java
@@ -26,9 +26,8 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
-import org.sonar.core.computation.db.AnalysisReportDto;
+import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.persistence.DbTester;
-import org.sonar.server.component.ComponentTesting;
import org.sonar.server.component.db.SnapshotDao;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.db.DbClient;
@@ -58,20 +57,14 @@ public class SwitchSnapshotStepTest {
@Test
public void one_switch_with_a_snapshot_and_his_children() throws IOException {
db.prepareDbUnit(getClass(), "snapshots.xml");
- ComputationContext context = new ComputationContext(AnalysisReportDto.newForTests(1L).setSnapshotId(1L),
- ComponentTesting.newProjectDto());
+
+ BatchReport.Metadata metadata = BatchReport.Metadata.newBuilder()
+ .setSnapshotId(1L).build();
+ ComputationContext context = mock(ComputationContext.class);
+ when(context.getReportMetadata()).thenReturn(metadata);
sut.execute(context);
db.assertDbUnit(getClass(), "snapshots-result.xml", "snapshots");
}
-
- @Test(expected = IllegalStateException.class)
- public void throw_IllegalStateException_when_not_finding_snapshot() throws IOException {
- db.prepareDbUnit(getClass(), "empty.xml");
- ComputationContext context = new ComputationContext(AnalysisReportDto.newForTests(1L).setSnapshotId(1L),
- ComponentTesting.newProjectDto());
-
- sut.execute(context);
- }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java
index 51e8ca6c117..6852087e43f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java
@@ -37,8 +37,8 @@ import org.sonar.core.persistence.MyBatis;
import org.sonar.core.user.UserDto;
import org.sonar.server.activity.ActivityService;
import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.computation.AnalysisReportLog;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.server.computation.ReportActivity;
+import org.sonar.server.computation.ReportQueue;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.tester.ServerTester;
@@ -50,8 +50,8 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * TODO replace this medium test by a small test
- */
+* TODO replace this medium test by a small test
+*/
public class HistoryWsActionMediumTest {
private static final String DEFAULT_PROJECT_KEY = "DefaultProjectKey";
private static final String DEFAULT_PROJECT_NAME = "DefaultProjectName";
@@ -63,7 +63,7 @@ public class HistoryWsActionMediumTest {
private DbClient dbClient;
private DbSession session;
private WsTester wsTester;
- private AnalysisReportQueue queue;
+ private ReportQueue queue;
private MockUserSession userSession;
private ActivityService activityService;
@@ -73,7 +73,7 @@ public class HistoryWsActionMediumTest {
dbClient = tester.get(DbClient.class);
wsTester = tester.get(WsTester.class);
session = dbClient.openSession(false);
- queue = tester.get(AnalysisReportQueue.class);
+ queue = tester.get(ReportQueue.class);
activityService = tester.get(ActivityService.class);
UserDto connectedUser = new UserDto().setLogin("gandalf").setName("Gandalf");
@@ -93,9 +93,9 @@ public class HistoryWsActionMediumTest {
@Test
public void add_and_try_to_retrieve_activities() throws Exception {
insertPermissionsForProject(DEFAULT_PROJECT_KEY);
- queue.add(DEFAULT_PROJECT_KEY, 123L, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
- queue.add(DEFAULT_PROJECT_KEY, 123L, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
- queue.add(DEFAULT_PROJECT_KEY, 123L, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
+ queue.add(DEFAULT_PROJECT_KEY, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
+ queue.add(DEFAULT_PROJECT_KEY, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
+ queue.add(DEFAULT_PROJECT_KEY, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
List<AnalysisReportDto> reports = queue.all();
ComponentDto project = ComponentTesting.newProjectDto()
@@ -103,13 +103,13 @@ public class HistoryWsActionMediumTest {
.setKey(DEFAULT_PROJECT_KEY);
for (AnalysisReportDto report : reports) {
report.succeed();
- activityService.write(session, Activity.Type.ANALYSIS_REPORT, new AnalysisReportLog(report, project));
+ activityService.write(session, Activity.Type.ANALYSIS_REPORT, new ReportActivity(report, project));
}
session.commit();
userSession.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
- WsTester.TestRequest request = wsTester.newGetRequest(ComputationWebService.API_ENDPOINT, HistoryWsAction.SEARCH_ACTION);
+ WsTester.TestRequest request = wsTester.newGetRequest(ComputationWebService.API_ENDPOINT, "history");
WsTester.Result result = request.execute();
assertThat(result).isNotNull();
@@ -132,14 +132,14 @@ public class HistoryWsActionMediumTest {
@Test(expected = ForbiddenException.class)
public void user_rights_is_not_enough_throw_ForbiddenException() throws Exception {
insertPermissionsForProject(DEFAULT_PROJECT_KEY);
- queue.add(DEFAULT_PROJECT_KEY, 123L, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
+ queue.add(DEFAULT_PROJECT_KEY, IOUtils.toInputStream(DEFAULT_REPORT_DATA));
AnalysisReportDto report = queue.all().get(0);
report.succeed();
- queue.remove(report);
+ // queue.remove(report);
userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- WsTester.TestRequest sut = wsTester.newGetRequest(ComputationWebService.API_ENDPOINT, HistoryWsAction.SEARCH_ACTION);
+ WsTester.TestRequest sut = wsTester.newGetRequest(ComputationWebService.API_ENDPOINT, "history");
sut.execute();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWebServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWebServiceTest.java
index 346d871631f..2be42fa3111 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWebServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWebServiceTest.java
@@ -26,7 +26,7 @@ import org.junit.Test;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.server.computation.ReportQueue;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
@@ -39,12 +39,12 @@ import static org.mockito.Mockito.when;
public class IsQueueEmptyWebServiceTest {
IsQueueEmptyWebService.IsQueueEmptyWsAction sut;
- AnalysisReportQueue queue;
+ ReportQueue queue;
Response response;
@Before
public void before() throws Exception {
- queue = mock(AnalysisReportQueue.class);
+ queue = mock(ReportQueue.class);
sut = new IsQueueEmptyWebService.IsQueueEmptyWsAction(queue);
response = mock(Response.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java
index f3821946deb..846f8d095b3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java
@@ -25,7 +25,7 @@ import org.junit.Before;
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.server.computation.ReportQueue;
import org.sonar.server.ws.WsTester;
import java.util.List;
@@ -38,11 +38,11 @@ import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING;
public class QueueWsActionTest {
WsTester tester;
- private AnalysisReportQueue queue;
+ private ReportQueue queue;
@Before
public void setup() throws Exception {
- queue = mock(AnalysisReportQueue.class);
+ queue = mock(ReportQueue.class);
tester = new WsTester(new ComputationWebService(new QueueWsAction(queue)));
}
@@ -52,7 +52,7 @@ public class QueueWsActionTest {
.newForTests(1L)
.setProjectKey("project-key")
.setStatus(PENDING)
- .setData(null)
+ .setUuid("PROJECT_UUID")
.setCreatedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime())
.setStartedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime())
.setFinishedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java
index 44e5bfe2936..e88d651d591 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java
@@ -23,8 +23,12 @@ package org.sonar.server.computation.ws;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.computation.AnalysisReportQueue;
+import org.sonar.core.computation.db.AnalysisReportDto;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.server.computation.ComputationThreadLauncher;
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.user.MockUserSession;
import org.sonar.server.ws.WsTester;
import java.io.InputStream;
@@ -34,16 +38,13 @@ import static org.mockito.Mockito.*;
public class SubmitReportWsActionTest {
- private static final String DEFAULT_PROJECT_KEY = "123456789-987654321";
- private SubmitReportWsAction sut;
-
- private WsTester wsTester;
- private ComputationThreadLauncher workerLauncher = mock(ComputationThreadLauncher.class);
- private AnalysisReportQueue queue;
+ ComputationThreadLauncher workerLauncher = mock(ComputationThreadLauncher.class);
+ ReportQueue queue = mock(ReportQueue.class);
+ WsTester wsTester;
+ SubmitReportWsAction sut;
@Before
public void before() {
- queue = mock(AnalysisReportQueue.class);
sut = new SubmitReportWsAction(queue, workerLauncher);
wsTester = new WsTester(new ComputationWebService(sut));
}
@@ -57,33 +58,36 @@ public class SubmitReportWsActionTest {
WebService.Action action = context.controller("api/computation").action("submit_report");
assertThat(action).isNotNull();
- assertThat(action.params()).hasSize(3);
+ assertThat(action.params()).hasSize(2);
}
@Test
public void add_element_to_queue_and_launch_analysis_task() throws Exception {
- when(queue.add(any(String.class), anyLong(), any(InputStream.class))).thenReturn("P1");
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ AnalysisReportDto dto = mock(AnalysisReportDto.class);
+ when(dto.getId()).thenReturn(42L);
+ when(queue.add(any(String.class), any(InputStream.class))).thenReturn(new ReportQueue.Item(dto, null));
WsTester.TestRequest request = wsTester
.newGetRequest(ComputationWebService.API_ENDPOINT, "submit_report")
.setParam(SubmitReportWsAction.PARAM_PROJECT_KEY, "P1")
- .setParam(SubmitReportWsAction.PARAM_SNAPSHOT, "456")
.setParam(SubmitReportWsAction.PARAM_REPORT_DATA, null);
- request.execute();
+ WsTester.Result response = request.execute();
- verify(queue).add(eq("P1"), eq(456L), any(InputStream.class));
+ verify(queue).add(eq("P1"), any(InputStream.class));
verify(workerLauncher).startAnalysisTaskNow();
+ assertThat(response.outputAsString()).isEqualTo("{\"key\":\"42\"}");
}
- @Test
- public void return_report_key() throws Exception {
- when(queue.add(any(String.class), anyLong(), any(InputStream.class))).thenReturn("P1");
+ @Test(expected = ForbiddenException.class)
+ public void requires_scan_permission() throws Exception {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.DASHBOARD_SHARING);
WsTester.TestRequest request = wsTester
- .newPostRequest(ComputationWebService.API_ENDPOINT, "submit_report")
+ .newGetRequest(ComputationWebService.API_ENDPOINT, "submit_report")
.setParam(SubmitReportWsAction.PARAM_PROJECT_KEY, "P1")
- .setParam(SubmitReportWsAction.PARAM_SNAPSHOT, "456")
.setParam(SubmitReportWsAction.PARAM_REPORT_DATA, null);
- request.execute().assertJson(getClass(), "submit_report.json", false);
+ request.execute();
+
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java b/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java
index 3d8f2e1ccdd..ea8f9785964 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java
@@ -85,6 +85,7 @@ public class ServerTester extends ExternalResource {
properties.setProperty(ProcessConstants.CLUSTER_NODE_NAME, esServerHolder.getNodeName());
properties.setProperty(ProcessConstants.SEARCH_PORT, String.valueOf(esServerHolder.getPort()));
properties.setProperty(ProcessConstants.PATH_HOME, homeDir.getAbsolutePath());
+ properties.setProperty(ProcessConstants.PATH_DATA, new File(homeDir, "data").getAbsolutePath());
properties.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:" + homeDir.getAbsolutePath() + "/h2");
for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {
String key = entry.getKey().toString();
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/ComputationServiceTest/shared.xml
index d01512aa559..66bd86524aa 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/ComputationServiceTest/shared.xml
@@ -1,3 +1,3 @@
<dataset>
- <projects id="10" kee="PROJECT_KEY" qualifier="TRK"/>
+ <projects id="10" kee="P1" qualifier="TRK"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/any-analysis-reports.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/any-analysis-reports.xml
index b72284f5d10..dba17d047a4 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/any-analysis-reports.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/any-analysis-reports.xml
@@ -1,29 +1,26 @@
<dataset>
<analysis_reports
id="1"
+ uuid="REPORT_1"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411509600000"
/>
<analysis_reports
id="2"
+ uuid="REPORT_2"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411596000000"
/>
<analysis_reports
id="3"
+ uuid="REPORT_3"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
report_status="PENDING"
created_at="1411682400000"
updated_at="1411682400000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml
index 26126affff8..ae28befd603 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/book_available_report_analysis_while_having_one_working_on_another_project.xml
@@ -2,8 +2,7 @@
<analysis_reports
id="1"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="REPORT_1"
report_status="PENDING"
created_at="1411509600000"
updated_at="1411596000000"
@@ -11,10 +10,9 @@
<analysis_reports
id="2"
project_key="987654321-123456789"
- snapshot_id="123"
- report_data="data-project"
+ uuid="REPORT_2"
report_status="WORKING"
created_at="1411423200000"
updated_at="1411682400000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/insert-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/insert-result.xml
index a3043ec3238..bc6bbc5b63e 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/insert-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/insert-result.xml
@@ -3,8 +3,7 @@
id="1"
project_key="123456789-987654321"
project_name="[null]"
- snapshot_id="123"
- report_data="[null]"
+ uuid="UUID_1"
report_status="PENDING"
started_at="[null]"
finished_at="[null]"
@@ -15,8 +14,7 @@
id="2"
project_key="123456789-987654321"
project_name="[null]"
- snapshot_id="123"
- report_data="[null]"
+ uuid="UUID_2"
report_status="PENDING"
started_at="[null]"
finished_at="[null]"
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_analysis_report.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_analysis_report.xml
index ca3013e2f84..a4e07b73029 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_analysis_report.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_analysis_report.xml
@@ -2,12 +2,11 @@
<analysis_reports
id="1"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="REPORT_1"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411596000000"
started_at="1411682400000"
finished_at="1411768800000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis.xml
deleted file mode 100644
index b26ec14839a..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<dataset>
- <analysis_reports
- id="1"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="PENDING"
- created_at="1411509600000"
- updated_at="1411596000000"
- />
- <analysis_reports
- id="2"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="PENDING"
- created_at="1411509600000"
- updated_at="1411596000000"
- />
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis_but_another_busy_on_same_project.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis_but_another_busy_on_same_project.xml
deleted file mode 100644
index f48e5e111b1..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_available_analysis_but_another_busy_on_same_project.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<dataset>
- <analysis_reports
- id="1"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="PENDING"
- created_at="1411509600000"
- updated_at="1411596000000"
- />
- <analysis_reports
- id="2"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="WORKING"
- created_at="1411423200000"
- updated_at="1411682400000"
- />
-</dataset> \ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_busy_report_analysis.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_busy_report_analysis.xml
deleted file mode 100644
index f853e443a39..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/one_busy_report_analysis.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<dataset>
- <analysis_reports
- id="1"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="WORKING"
- created_at="1411509600000"
- updated_at="1411596000000"
- />
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml
index 21eb7f1fb43..82f93e9fec5 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_null_if_no_pending_reports.xml
@@ -2,8 +2,7 @@
<analysis_reports
id="1"
project_key="111111111-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_1"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411682400000"
@@ -11,8 +10,7 @@
<analysis_reports
id="2"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_2"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411682400000"
@@ -21,10 +19,9 @@
<analysis_reports
id="3"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411596000000"
updated_at="1411682400000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_oldest_pending.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_oldest_pending.xml
index cae6dec371c..972fde88fd7 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_oldest_pending.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/pop_oldest_pending.xml
@@ -3,8 +3,7 @@
<analysis_reports
id="1"
project_key="P1"
- snapshot_id="1"
- report_data="data-project"
+ uuid="UUID_1"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411682400000"
@@ -14,8 +13,7 @@
<analysis_reports
id="2"
project_key="P1"
- snapshot_id="2"
- report_data="data-project"
+ uuid="UUID_2"
report_status="PENDING"
created_at="1411509600000"
updated_at="1411682400000"
@@ -23,8 +21,7 @@
<analysis_reports
id="3"
project_key="P2"
- snapshot_id="3"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411596000000"
updated_at="1411682400000"
@@ -32,8 +29,7 @@
<analysis_reports
id="4"
project_key="P2"
- snapshot_id="4"
- report_data="data-project"
+ uuid="UUID_4"
report_status="PENDING"
created_at="1420066800000"
updated_at="1420066800000"
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select.xml
index 8fff6461280..c1e3284f108 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select.xml
@@ -2,8 +2,7 @@
<analysis_reports
id="1"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_1"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411596000000"
@@ -11,8 +10,7 @@
<analysis_reports
id="2"
project_key="987654321-123456789"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_2"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411596000000"
@@ -20,10 +18,9 @@
<analysis_reports
id="3"
project_key="987654321-123456789"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411682400000"
updated_at="1411682400000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select_oldest_available_report_with_working_reports_older.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select_oldest_available_report_with_working_reports_older.xml
deleted file mode 100644
index 282458ef695..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/select_oldest_available_report_with_working_reports_older.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<dataset>
- <analysis_reports
- id="1"
- project_key="111111111-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="WORKING"
- created_at="1411423200000"
- updated_at="1411682400000"
- />
- <analysis_reports
- id="2"
- project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
- report_status="PENDING"
- created_at="1411509600000"
- updated_at="1411682400000"
- />
- <analysis_reports
- id="3"
- project_key="333333333-123456789"
- snapshot_id="123"
- report_data="data-project"
- report_status="WORKING"
- created_at="1411596000000"
- updated_at="1411682400000"
- />
-</dataset> \ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/three_analysis_reports.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/three_analysis_reports.xml
index 8fff6461280..c1e3284f108 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/three_analysis_reports.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/three_analysis_reports.xml
@@ -2,8 +2,7 @@
<analysis_reports
id="1"
project_key="123456789-987654321"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_1"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411596000000"
@@ -11,8 +10,7 @@
<analysis_reports
id="2"
project_key="987654321-123456789"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_2"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411596000000"
@@ -20,10 +18,9 @@
<analysis_reports
id="3"
project_key="987654321-123456789"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411682400000"
updated_at="1411682400000"
/>
-</dataset> \ No newline at end of file
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending-result.xml
index a57c6282dd1..2c240ea4bc4 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending-result.xml
@@ -4,8 +4,7 @@
id="1"
project_key="P1"
project_name="Project1"
- snapshot_id="1"
- report_data="data-project"
+ uuid="UUID_1"
report_status="PENDING"
created_at="1411509600000"
updated_at="1411682400000"
@@ -16,8 +15,7 @@
id="2"
project_key="P2"
project_name="Project2"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_2"
report_status="PENDING"
created_at="1411596000000"
updated_at="1411682400000"
@@ -28,8 +26,7 @@
id="3"
project_key="P1"
project_name="Project1"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411682400000"
updated_at="1411682400000"
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending.xml
index 50edcc5da97..a630cb4ec4b 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/db/AnalysisReportDaoTest/update-all-to-status-pending.xml
@@ -3,8 +3,7 @@
id="1"
project_key="P1"
project_name="Project1"
- snapshot_id="1"
- report_data="data-project"
+ uuid="UUID_1"
report_status="WORKING"
created_at="1411509600000"
updated_at="1411509600000"
@@ -15,8 +14,7 @@
id="2"
project_key="P2"
project_name="Project2"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_2"
report_status="WORKING"
created_at="1411596000000"
updated_at="1411596000000"
@@ -27,8 +25,7 @@
id="3"
project_key="P1"
project_name="Project1"
- snapshot_id="123"
- report_data="data-project"
+ uuid="UUID_3"
report_status="PENDING"
created_at="1411682400000"
updated_at="1411682400000"
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/SubmitReportWsActionTest/submit_report.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/SubmitReportWsActionTest/submit_report.json
deleted file mode 100644
index 40062f5b580..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/SubmitReportWsActionTest/submit_report.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "key": "P1"
-}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/796_add_uuid_to_analysis_reports.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/796_add_uuid_to_analysis_reports.rb
new file mode 100644
index 00000000000..06fba16976d
--- /dev/null
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/796_add_uuid_to_analysis_reports.rb
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+#
+# SonarQube 5.1
+#
+class AddUuidToAnalysisReports < ActiveRecord::Migration
+
+ def self.up
+ add_column 'analysis_reports', 'uuid', :string, :limit => 50, :null => false
+ remove_column 'analysis_reports', 'report_data'
+ remove_column 'analysis_reports', 'snapshot_id'
+ end
+
+end