diff options
11 files changed, 294 insertions, 2 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReader.java index fec1660d8ab..a7455e6bda1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportReader.java @@ -27,6 +27,8 @@ import org.sonar.core.util.CloseableIterator; public interface BatchReportReader { BatchReport.Metadata readMetadata(); + CloseableIterator<String> readScannerLogs(); + CloseableIterator<BatchReport.ActiveRule> readActiveRules(); CloseableIterator<BatchReport.Measure> readComponentMeasures(int componentRef); 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 c2dee4402bb..5b1ab44e92f 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 @@ -26,6 +26,7 @@ import com.google.protobuf.Parser; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.NoSuchElementException; import javax.annotation.CheckForNull; @@ -34,6 +35,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.util.CloseableIterator; +import org.sonar.core.util.LineReaderIterator; public class BatchReportReaderImpl implements BatchReportReader { private final org.sonar.batch.protocol.output.BatchReportReader delegate; @@ -53,6 +55,20 @@ public class BatchReportReaderImpl implements BatchReportReader { } @Override + public CloseableIterator<String> readScannerLogs() { + File file = delegate.getFileStructure().analysisLog(); + if (!file.exists()) { + return CloseableIterator.emptyCloseableIterator(); + } + try { + InputStreamReader reader = new InputStreamReader(FileUtils.openInputStream(file), StandardCharsets.UTF_8); + return new LineReaderIterator(reader); + } catch (IOException e) { + throw new IllegalStateException("Fail to open file " + file, e); + } + } + + @Override public CloseableIterator<BatchReport.ActiveRule> readActiveRules() { return delegate.readActiveRules(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/LogScannerContextStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LogScannerContextStep.java new file mode 100644 index 00000000000..4978b2fa468 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LogScannerContextStep.java @@ -0,0 +1,53 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.computation.step; + +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.core.util.CloseableIterator; +import org.sonar.server.computation.batch.BatchReportReader; + +public class LogScannerContextStep implements ComputationStep { + + private static final Logger LOGGER = Loggers.get(LogScannerContextStep.class); + + private final BatchReportReader reportReader; + + public LogScannerContextStep(BatchReportReader reportReader) { + this.reportReader = reportReader; + } + + @Override + public void execute() { + CloseableIterator<String> logs = reportReader.readScannerLogs(); + try { + while (logs.hasNext()) { + LOGGER.info(logs.next()); + } + } finally { + logs.close(); + } + } + + @Override + public String getDescription() { + return "Log scanner context"; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportComputationSteps.java index a59b2635c4b..3813fa5e4b0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ReportComputationSteps.java @@ -38,8 +38,8 @@ public class ReportComputationSteps implements ComputationSteps { @Override public List<Class<? extends ComputationStep>> orderedStepClasses() { return Arrays.asList( - // extract report to a temp directory ExtractReportStep.class, + LogScannerContextStep.class, // Builds Component tree BuildComponentTreeStep.class, diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderImplTest.java index d30f27b9e69..d2fd81b9a4b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderImplTest.java @@ -81,6 +81,21 @@ public class BatchReportReaderImplTest { } @Test + public void readScannerLogs() throws IOException { + File scannerLogFile = writer.getFileStructure().analysisLog(); + FileUtils.write(scannerLogFile, "log1\nlog2"); + + CloseableIterator<String> logs = underTest.readScannerLogs(); + assertThat(logs).containsExactly("log1", "log2"); + } + + @Test + public void readScannerLogs_no_logs() { + CloseableIterator<String> logs = underTest.readScannerLogs(); + assertThat(logs.hasNext()).isFalse(); + } + + @Test public void readComponentMeasures_returns_empty_list_if_there_is_no_measure() { assertThat(underTest.readComponentMeasures(COMPONENT_REF)).isEmpty(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java index ea65d2c1cdc..420f59c60c2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/BatchReportReaderRule.java @@ -36,6 +36,7 @@ import org.sonar.core.util.CloseableIterator; public class BatchReportReaderRule implements TestRule, BatchReportReader { private BatchReport.Metadata metadata; + private List<String> scannerLogs; private List<BatchReport.ActiveRule> activeRules = new ArrayList<>(); private Map<Integer, List<BatchReport.Measure>> measures = new HashMap<>(); private Map<Integer, BatchReport.Changesets> changesets = new HashMap<>(); @@ -65,6 +66,7 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader { private void clear() { this.metadata = null; + this.scannerLogs = null; this.measures.clear(); this.changesets.clear(); this.components.clear(); @@ -91,6 +93,18 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader { } @Override + public CloseableIterator<String> readScannerLogs() { + if (scannerLogs == null) { + throw new IllegalStateException("Scanner logs are missing"); + } + return CloseableIterator.from(scannerLogs.iterator()); + } + + public void setScannerLogs(@Nullable List<String> logs) { + this.scannerLogs = logs; + } + + @Override public CloseableIterator<BatchReport.ActiveRule> readActiveRules() { if (activeRules == null) { throw new IllegalStateException("Active rules are not set"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/LogScannerContextStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/LogScannerContextStepTest.java new file mode 100644 index 00000000000..760303ddf0b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/LogScannerContextStepTest.java @@ -0,0 +1,50 @@ +/* + * 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.Rule; +import org.junit.Test; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.server.computation.batch.BatchReportReaderRule; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; + +public class LogScannerContextStepTest { + + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); + + @Rule + public LogTester logTester = new LogTester(); + + LogScannerContextStep underTest = new LogScannerContextStep(reportReader); + + @Test + public void log_scanner_logs() { + reportReader.setScannerLogs(asList("log1", "log2")); + + underTest.execute(); + + assertThat(logTester.logs(LoggerLevel.INFO)).containsExactly("log1", "log2"); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputationStepsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputationStepsTest.java index 3c8bc5db711..6bcddb92f0d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputationStepsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputationStepsTest.java @@ -52,7 +52,7 @@ public class ReportComputationStepsTest { @Test public void instances_throws_ISE_if_container_does_not_have_second_step() throws Exception { expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Component not found: class org.sonar.server.computation.step.BuildComponentTreeStep"); + expectedException.expectMessage("Component not found: class org.sonar.server.computation.step.LogScannerContextStep"); final ExtractReportStep reportExtractionStep = mock(ExtractReportStep.class); ComponentContainer componentContainer = new ComponentContainer() { diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportReader.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportReader.java index 7a650438204..b8d1fb2d42e 100644 --- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportReader.java +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportReader.java @@ -152,4 +152,8 @@ public class BatchReportReader { private static boolean fileExists(File file) { return file.exists() && file.isFile(); } + + public FileStructure getFileStructure() { + return fileStructure; + } } diff --git a/sonar-core/src/main/java/org/sonar/core/util/LineReaderIterator.java b/sonar-core/src/main/java/org/sonar/core/util/LineReaderIterator.java new file mode 100644 index 00000000000..5c6a57a2700 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/util/LineReaderIterator.java @@ -0,0 +1,55 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.core.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Read lines from a {@link Reader} + * @see BufferedReader + */ +public class LineReaderIterator extends CloseableIterator<String> { + + private final BufferedReader reader; + + public LineReaderIterator(Reader reader) { + if (reader instanceof BufferedReader) { + this.reader = (BufferedReader) reader; + } else { + this.reader = new BufferedReader(reader); + } + } + + @Override + protected String doNext() { + try { + return reader.readLine(); + } catch (IOException e) { + throw new IllegalStateException("Fail to read line", e); + } + } + + @Override + protected void doClose() throws IOException { + reader.close(); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/util/LineReaderIteratorTest.java b/sonar-core/src/test/java/org/sonar/core/util/LineReaderIteratorTest.java new file mode 100644 index 00000000000..7d143aabc3b --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/util/LineReaderIteratorTest.java @@ -0,0 +1,83 @@ +/* + * 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.core.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class LineReaderIteratorTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void read_lines() { + LineReaderIterator it = new LineReaderIterator(new StringReader("line1\nline2")); + assertThat(it.hasNext()).isTrue(); + assertThat(it.next()).isEqualTo("line1"); + assertThat(it.hasNext()).isTrue(); + assertThat(it.next()).isEqualTo("line2"); + assertThat(it.hasNext()).isFalse(); + } + + @Test + public void ignore_last_newline() { + LineReaderIterator it = new LineReaderIterator(new StringReader("line1\nline2\n")); + assertThat(it.hasNext()).isTrue(); + assertThat(it.next()).isEqualTo("line1"); + assertThat(it.hasNext()).isTrue(); + assertThat(it.next()).isEqualTo("line2"); + assertThat(it.hasNext()).isFalse(); + } + + @Test + public void no_lines() { + LineReaderIterator it = new LineReaderIterator(new StringReader("")); + assertThat(it.hasNext()).isFalse(); + } + + @Test + public void do_not_wrap_BufferedReader_in_BufferedReader() { + // TODO how to verify that constructor does not build new BufferedReader(BufferedReader) ? + LineReaderIterator it = new LineReaderIterator(new BufferedReader(new StringReader("line"))); + assertThat(it.next()).isEqualTo("line"); + assertThat(it.hasNext()).isFalse(); + } + + @Test + public void fail_if_cannot_read() throws IOException { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Fail to read line"); + + BufferedReader reader = mock(BufferedReader.class); + when(reader.readLine()).thenThrow(new IOException()); + LineReaderIterator it = new LineReaderIterator(reader); + + it.hasNext(); + } +} |