From 1321df4c9bb0af4d43d697cac5c930e7e2711226 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Fri, 29 May 2015 10:59:33 +0200 Subject: [PATCH] SONAR-6589 make ReportExtractor a step called ReportExtractionStep --- .../batch/BatchReportDirectoryHolder.java | 33 +++++ .../batch/BatchReportDirectoryHolderImpl.java | 40 ++++++ .../batch/BatchReportReaderImpl.java | 5 +- .../MutableBatchReportDirectoryHolder.java | 34 +++++ .../container/ComputeEngineContainerImpl.java | 8 +- .../computation/step/ComputationSteps.java | 3 + .../ReportExtractionStep.java} | 28 +++- .../computation/step/ValidateProjectStep.java | 12 +- .../batch/ReportExtractorTest.java | 58 -------- .../ComputeEngineContainerImplTest.java | 2 + .../PopulateComponentsUuidAndKeyStepTest.java | 6 +- .../step/ReportExtractionStepTest.java | 136 ++++++++++++++++++ .../step/ValidateProjectStepTest.java | 55 +++---- .../step/ReportExtractionStepTest/demozip.zip | Bin 0 -> 1390 bytes 14 files changed, 316 insertions(+), 104 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolder.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolderImpl.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/batch/MutableBatchReportDirectoryHolder.java rename server/sonar-server/src/main/java/org/sonar/server/computation/{batch/ReportExtractor.java => step/ReportExtractionStep.java} (65%) delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportExtractionStepTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/computation/step/ReportExtractionStepTest/demozip.zip diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolder.java new file mode 100644 index 00000000000..088dbc56e71 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolder.java @@ -0,0 +1,33 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.computation.batch; + +import java.io.File; +import org.sonar.server.computation.ReportQueue; + +public interface BatchReportDirectoryHolder { + /** + * The File of the directory where the Batch report files for the current {@link ReportQueue.Item} are stored. + * + * @throws IllegalStateException if the holder is empty (ie. there is no directory yet) + */ + File getDirectory(); + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolderImpl.java new file mode 100644 index 00000000000..6477b7aa6a2 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolderImpl.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.batch; + +import java.io.File; +import java.util.Objects; + +public class BatchReportDirectoryHolderImpl implements BatchReportDirectoryHolder, MutableBatchReportDirectoryHolder { + private File directory; + + @Override + public void setDirectory(File newDirectory) { + this.directory = Objects.requireNonNull(newDirectory); + } + + @Override + public File getDirectory() { + if (this.directory == null) { + throw new IllegalStateException("Directory has not been set yet"); + } + return this.directory; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReaderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReaderImpl.java index 7799436b9b2..6c600f37f6c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReaderImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReaderImpl.java @@ -33,14 +33,13 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.sonar.batch.protocol.output.BatchReport; -import org.sonar.server.computation.ReportQueue; import org.sonar.server.util.CloseableIterator; public class BatchReportReaderImpl implements BatchReportReader { private final org.sonar.batch.protocol.output.BatchReportReader delegate; - public BatchReportReaderImpl(ReportExtractor reportExtractor, ReportQueue.Item item) { - this.delegate = new org.sonar.batch.protocol.output.BatchReportReader(reportExtractor.extractReportInDir(item)); + public BatchReportReaderImpl(BatchReportDirectoryHolder batchReportDirectoryHolder) { + this.delegate = new org.sonar.batch.protocol.output.BatchReportReader(batchReportDirectoryHolder.getDirectory()); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/MutableBatchReportDirectoryHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/MutableBatchReportDirectoryHolder.java new file mode 100644 index 00000000000..21a4a1bdb75 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/MutableBatchReportDirectoryHolder.java @@ -0,0 +1,34 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.computation.batch; + +import java.io.File; + +public interface MutableBatchReportDirectoryHolder extends BatchReportDirectoryHolder { + /** + * Sets the File of the directory in the BatchReportDirectoryHolder. Settings a File more than once is allowed but it + * can never be set to {@code null}. + * + * @param newDirectory a {@link File}, can not be {@code null} + * + * @throws NullPointerException if {@code newDirectory} is {@code null} + */ + void setDirectory(File newDirectory); +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java index 1f1f7336c6d..ff9de6a5da4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java @@ -34,8 +34,8 @@ import org.sonar.core.platform.ComponentContainer; import org.sonar.server.computation.ComputationService; import org.sonar.server.computation.ReportQueue; import org.sonar.server.computation.activity.ActivityManager; +import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl; import org.sonar.server.computation.batch.BatchReportReaderImpl; -import org.sonar.server.computation.batch.ReportExtractor; import org.sonar.server.computation.component.DbComponentsRefCache; import org.sonar.server.computation.component.TreeRootHolderImpl; import org.sonar.server.computation.event.EventRepositoryImpl; @@ -111,11 +111,13 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co private static List componentClasses() { return Arrays.asList( ActivityManager.class, - ReportExtractor.class, - BatchReportReaderImpl.class, TreeRootHolderImpl.class, + BatchReportReaderImpl.class, + + BatchReportDirectoryHolderImpl.class, + // repositories PlatformLanguageRepository.class, MeasureRepositoryImpl.class, 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 7d409691a77..a967fd10526 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 @@ -36,6 +36,9 @@ public class ComputationSteps { */ public List> orderedStepClasses() { return Arrays.asList( + // extract report to a temp directory + ReportExtractionStep.class, + // Builds Component tree BuildComponentTreeStep.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportExtractionStep.java similarity index 65% rename from server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java rename to server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportExtractionStep.java index 61aa6a95cfc..f3048e9d1fd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/ReportExtractor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportExtractionStep.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.computation.batch; +package org.sonar.server.computation.step; import java.io.File; import java.io.IOException; @@ -28,17 +28,27 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.server.computation.ReportQueue; +import org.sonar.server.computation.batch.MutableBatchReportDirectoryHolder; -public class ReportExtractor { - private static final Logger LOG = Loggers.get(ReportExtractor.class); +/** + * Extracts the content zip file of the {@link ReportQueue.Item} to a temp directory and adds a {@link File} + * representing that temp directory to the {@link MutableBatchReportDirectoryHolder}. + */ +public class ReportExtractionStep implements ComputationStep { + private static final Logger LOG = Loggers.get(ReportExtractionStep.class); + private final ReportQueue.Item item; private final TempFolder tempFolder; + private final MutableBatchReportDirectoryHolder reportDirectoryHolder; - public ReportExtractor(TempFolder tempFolder) { + public ReportExtractionStep(ReportQueue.Item item, TempFolder tempFolder, MutableBatchReportDirectoryHolder reportDirectoryHolder) { + this.item = item; this.tempFolder = tempFolder; + this.reportDirectoryHolder = reportDirectoryHolder; } - public File extractReportInDir(ReportQueue.Item item) { + @Override + public void execute() { File dir = tempFolder.newDir(); try { Profiler profiler = Profiler.createIfDebug(LOG).start(); @@ -48,9 +58,15 @@ public class ReportExtractor { FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(dir)), item.dto.getProjectKey()); profiler.stopDebug(message); } - return dir; + reportDirectoryHolder.setDirectory(dir); } catch (IOException e) { throw new IllegalStateException(String.format("Fail to unzip %s into %s", item.zipFile, dir), e); } } + + @Override + public String getDescription() { + return "Extracting batch report to temp directory"; + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ValidateProjectStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ValidateProjectStep.java index 747fec66c8e..53c19ad76b7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ValidateProjectStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ValidateProjectStep.java @@ -35,10 +35,10 @@ import org.sonar.core.component.ComponentDto; import org.sonar.core.component.ComponentKeys; import org.sonar.core.persistence.DbSession; import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.computation.ComputationContext; import org.sonar.server.computation.batch.BatchReportReader; import org.sonar.server.computation.component.Component; import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor; +import org.sonar.server.computation.component.TreeRootHolder; import org.sonar.server.db.DbClient; /** @@ -58,18 +58,20 @@ public class ValidateProjectStep implements ComputationStep { private final DbClient dbClient; private final Settings settings; private final BatchReportReader reportReader; + private final TreeRootHolder treeRootHolder; - public ValidateProjectStep(DbClient dbClient, Settings settings, BatchReportReader reportReader) { + public ValidateProjectStep(DbClient dbClient, Settings settings, BatchReportReader reportReader, TreeRootHolder treeRootHolder) { this.dbClient = dbClient; this.settings = settings; this.reportReader = reportReader; + this.treeRootHolder = treeRootHolder; } @Override - public void execute(ComputationContext context) { + public void execute() { DbSession session = dbClient.openSession(false); try { - List modules = dbClient.componentDao().selectModulesFromProjectKey(session, context.getRoot().getKey()); + List modules = dbClient.componentDao().selectModulesFromProjectKey(session, treeRootHolder.getRoot().getKey()); Map modulesByKey = Maps.uniqueIndex(modules, new Function() { @Override public String apply(@Nonnull ComponentDto input) { @@ -77,7 +79,7 @@ public class ValidateProjectStep implements ComputationStep { } }); ValidateProjectsVisitor visitor = new ValidateProjectsVisitor(session, dbClient.componentDao(), settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION), modulesByKey); - visitor.visit(context.getRoot()); + visitor.visit(treeRootHolder.getRoot()); if (!visitor.validationMessages.isEmpty()) { throw new IllegalArgumentException("Validation of project failed:\n o " + MESSAGES_JOINER.join(visitor.validationMessages)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java deleted file mode 100644 index d25761fde94..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ReportExtractorTest.java +++ /dev/null @@ -1,58 +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.batch; - -import java.io.File; -import org.apache.commons.io.FileUtils; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.utils.internal.JUnitTempFolder; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.server.computation.ReportQueue; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public class ReportExtractorTest { - - @Rule - public JUnitTempFolder tempFolder = new JUnitTempFolder(); - - ReportExtractor underTest = new ReportExtractor(tempFolder); - - - @Test - public void fail_if_corrupted_zip() throws Exception { - AnalysisReportDto dto = newDefaultReport(); - File zip = tempFolder.newFile(); - FileUtils.write(zip, "not a file"); - - try { - underTest.extractReportInDir(new ReportQueue.Item(dto, zip)); - fail(); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).startsWith("Fail to unzip " + zip.getAbsolutePath() + " into "); - } - } - - private AnalysisReportDto newDefaultReport() { - return AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(AnalysisReportDto.Status.PENDING); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/container/ComputeEngineContainerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/container/ComputeEngineContainerImplTest.java index 389e3d3d538..6c8c69261d0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/container/ComputeEngineContainerImplTest.java @@ -35,10 +35,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; public class ComputeEngineContainerImplTest { + @Test(expected = NullPointerException.class) public void constructor_fails_fast_on_null_container() { new ComputeEngineContainerImpl(null, mock(ReportQueue.Item.class)); } + @Test(expected = NullPointerException.class) public void constructor_fails_fast_on_null_item() { new ComputeEngineContainerImpl(new ComponentContainer(), null); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java index e436c90de96..da362bbea17 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PopulateComponentsUuidAndKeyStepTest.java @@ -169,7 +169,7 @@ public class PopulateComponentsUuidAndKeyStepTest extends BaseStepTest { .build()); - treeRootHolder.setRoot(ComponentTreeBuilders.from(reportReader).build()); + treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader)); sut.execute(); Map componentsByRef = getComponentsByRef(treeRootHolder.getRoot()); @@ -322,7 +322,7 @@ public class PopulateComponentsUuidAndKeyStepTest extends BaseStepTest { .setPath("pom.xml") .build()); - treeRootHolder.setRoot(ComponentTreeBuilders.from(reportReader).build()); + treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader)); sut.execute(); Map componentsByRef = getComponentsByRef(treeRootHolder.getRoot()); @@ -382,7 +382,7 @@ public class PopulateComponentsUuidAndKeyStepTest extends BaseStepTest { .setPath("src/main/java/dir/Foo.java") .build()); - treeRootHolder.setRoot(ComponentTreeBuilders.from(reportReader).build()); + treeRootHolder.setRoot(ComponentTreeBuilder.from(reportReader)); sut.execute(); Map componentsByRef = getComponentsByRef(treeRootHolder.getRoot()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportExtractionStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportExtractionStepTest.java new file mode 100644 index 00000000000..5f0cefd713f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportExtractionStepTest.java @@ -0,0 +1,136 @@ +/* + * 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 java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.sonar.api.utils.internal.JUnitTempFolder; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.server.computation.ReportQueue; +import org.sonar.server.computation.batch.MutableBatchReportDirectoryHolder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +public class ReportExtractionStepTest { + + @Rule + public JUnitTempFolder tempFolder = new JUnitTempFolder(); + @Rule + public LogTester logTester = new LogTester().setLevel(LoggerLevel.INFO); + + private MutableBatchReportDirectoryHolder reportDirectoryHolder = mock(MutableBatchReportDirectoryHolder.class); + private AnalysisReportDto dto = newDefaultReport(); + private ArgumentCaptor fileCaptor = ArgumentCaptor.forClass(File.class); + + @Test + public void fail_if_corrupted_zip() throws Exception { + File zip = tempFolder.newFile(); + FileUtils.write(zip, "not a file"); + + ReportExtractionStep underTest = new ReportExtractionStep(new ReportQueue.Item(dto, zip), tempFolder, reportDirectoryHolder); + + try { + underTest.execute(); + fail(); + } catch (IllegalStateException e) { + assertThat(e.getMessage()).startsWith("Fail to unzip " + zip.getAbsolutePath() + " into "); + } + verifyNoMoreInteractions(reportDirectoryHolder); + } + + @Test + public void verify_zip_decompression() throws URISyntaxException, IOException { + new ReportExtractionStep(new ReportQueue.Item(dto, demoZipFile()), tempFolder, reportDirectoryHolder).execute(); + + verify(reportDirectoryHolder).setDirectory(fileCaptor.capture()); + verifyNoMoreInteractions(reportDirectoryHolder); + + File createDir = fileCaptor.getValue(); + assertThat(createDir.exists()).isTrue(); + assertThat(createDir.isDirectory()).isTrue(); + verifyFile(createDir, "1.txt", "1\n"); + verifyFile(createDir, "2.txt", "2\n"); + File subDir1 = verifyDir(createDir, "subdir1"); + verifyFile(subDir1, "3.txt", "3\n"); + verifyFile(subDir1, "4.txt", "4\n"); + File subDir2 = verifyDir(createDir, "subdir2"); + verifyFile(subDir2, "5.txt", "5\n"); + File subdir3 = verifyDir(subDir2, "subdir3"); + verifyFile(subdir3, "6.txt", "6\n"); + } + + @Test + public void verify_show_log_at_DEBUG_level() throws URISyntaxException { + logTester.setLevel(LoggerLevel.DEBUG); + + new ReportExtractionStep(new ReportQueue.Item(dto, demoZipFile()), tempFolder, reportDirectoryHolder).execute(); + + List logs = logTester.logs(); + assertThat(logs).hasSize(1); + String log = logs.get(0); + assertThat(log.startsWith("Report extracted | size=")).isTrue(); + assertThat(log.contains(" | project=P1 | time=")).isTrue(); + } + + private File demoZipFile() throws URISyntaxException { + return new File(getClass().getResource(getClass().getSimpleName() + "/" + "demozip.zip").toURI()); + } + + @Test + public void no_log_at_INFO_level() throws URISyntaxException { + logTester.setLevel(LoggerLevel.INFO); + + new ReportExtractionStep(new ReportQueue.Item(dto, demoZipFile()), tempFolder, reportDirectoryHolder).execute(); + + assertThat(logTester.logs()).isEmpty(); + } + + private File verifyDir(File dir, String subDir) { + File file = new File(dir, subDir); + assertThat(file.exists()).isTrue(); + assertThat(file.isDirectory()).isTrue(); + return file; + } + + private void verifyFile(File dir, String filename, String content) throws IOException { + File file = new File(dir, filename); + assertThat(file.exists()).isTrue(); + assertThat(file.isDirectory()).isFalse(); + assertThat(IOUtils.toString(new FileInputStream(file), "UTF-8")).isEqualTo(content); + } + + private static AnalysisReportDto newDefaultReport() { + return AnalysisReportDto.newForTests(1L).setProjectKey("P1").setUuid("U1").setStatus(AnalysisReportDto.Status.PENDING); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ValidateProjectStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ValidateProjectStepTest.java index 3c775d5b11e..290ab589a5f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ValidateProjectStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ValidateProjectStepTest.java @@ -35,10 +35,9 @@ import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.DbTester; import org.sonar.server.component.ComponentTesting; import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.computation.ComputationContext; import org.sonar.server.computation.batch.BatchReportReaderRule; +import org.sonar.server.computation.batch.TreeRootHolderRule; import org.sonar.server.computation.component.Component; -import org.sonar.server.computation.component.ComponentTreeBuilders; import org.sonar.server.computation.component.DumbComponent; import org.sonar.server.db.DbClient; @@ -53,6 +52,8 @@ public class ValidateProjectStepTest { public ExpectedException thrown = ExpectedException.none(); @Rule public BatchReportReaderRule reportReader = new BatchReportReaderRule(); + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); DbClient dbClient; @@ -69,7 +70,7 @@ public class ValidateProjectStepTest { dbSession = dbClient.openSession(false); settings = new Settings(); - sut = new ValidateProjectStep(dbClient, settings, reportReader); + sut = new ValidateProjectStep(dbClient, settings, reportReader, treeRootHolder); } @After @@ -89,8 +90,9 @@ public class ValidateProjectStepTest { settings.appendProperty(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION, "true"); dbClient.componentDao().insert(dbSession, ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY)); dbSession.commit(); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)); - sut.execute(new ComputationContext(ComponentTreeBuilders.from(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)))); + sut.execute(); } @Test @@ -106,8 +108,9 @@ public class ValidateProjectStepTest { .build()); settings.appendProperty(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION, "true"); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)); - sut.execute(new ComputationContext(ComponentTreeBuilders.from(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)))); + sut.execute(); } @Test @@ -120,8 +123,9 @@ public class ValidateProjectStepTest { .build()); settings.appendProperty(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION, "false"); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)); - sut.execute(new ComputationContext(ComponentTreeBuilders.from(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY)))); + sut.execute(); } @Test @@ -134,9 +138,9 @@ public class ValidateProjectStepTest { .setType(Constants.ComponentType.PROJECT) .setKey(PROJECT_KEY) .build()); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY + ":origin/master")); - sut.execute(new ComputationContext( - ComponentTreeBuilders.from(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY + ":origin/master")))); + sut.execute(); } @Test @@ -153,9 +157,9 @@ public class ValidateProjectStepTest { .setType(Constants.ComponentType.PROJECT) .setKey(PROJECT_KEY) .build()); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY + ":bran#ch")); - sut.execute(new ComputationContext( - ComponentTreeBuilders.from(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY + ":bran#ch")))); + sut.execute(); } @Test @@ -179,10 +183,10 @@ public class ValidateProjectStepTest { .setType(Constants.ComponentType.MODULE) .setKey("Module$Key") .build()); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", invalidProjectKey, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", "Module$Key"))); - DumbComponent root = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", invalidProjectKey, - new DumbComponent(Component.Type.MODULE, 2, "BCDE", "Module$Key")); - sut.execute(new ComputationContext(ComponentTreeBuilders.from(root))); + sut.execute(); } @Test @@ -210,10 +214,10 @@ public class ValidateProjectStepTest { dbClient.componentDao().insert(dbSession, project); dbSession.commit(); - DumbComponent root = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, - new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY)); - sut.execute(new ComputationContext( - ComponentTreeBuilders.from(root))); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY))); + + sut.execute(); } @Test @@ -243,10 +247,10 @@ public class ValidateProjectStepTest { dbClient.componentDao().insert(dbSession, module); dbSession.commit(); - DumbComponent root = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, - new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY)); - sut.execute(new ComputationContext( - ComponentTreeBuilders.from(root))); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY))); + + sut.execute(); } @Test @@ -277,10 +281,9 @@ public class ValidateProjectStepTest { dbClient.componentDao().insert(dbSession, module); dbSession.commit(); - DumbComponent root = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, - new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY)); - sut.execute(new ComputationContext( - ComponentTreeBuilders.from(root))); + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", MODULE_KEY))); + + sut.execute(); } - } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/step/ReportExtractionStepTest/demozip.zip b/server/sonar-server/src/test/resources/org/sonar/server/computation/step/ReportExtractionStepTest/demozip.zip new file mode 100644 index 0000000000000000000000000000000000000000..929c0673ef5f88a79bb91209b54d676bd8123279 GIT binary patch literal 1390 zcmajeu}i~16vy#P(@0uT;$RRd4hrIANYWNW9CUEep;CjRpkk}Is4W!f(%Hqq+1<&- z)jvXT62V!VT|~k6de_T~cS%}WI+PE;yMEi)GK*z~kMri!=J11fvsr~*b`OqDE_^TA zEivJ0}K50sC#kYgf z?Wwagnl!DE>T+5NS0~dB0c`&4v__x>pf7<}xMo+qBA)=q0NgzEwj0RGXyaH6cZzKw_a8E7dybnO`J{ zt%8P;2IJ#*Fa&{ h87tMMDYXizi^74z!WGIIgCCHU;Q0n$?&E)h{Q=M+|4#q_ literal 0 HcmV?d00001 -- 2.39.5