From 7df58c2fc0dbab0d82c5587104a9ad1d2fa369ac Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Mon, 13 Oct 2014 15:08:30 +0200 Subject: SONAR-5389 Refactor test coverage API --- .../sonar/batch/mediumtest/BatchMediumTester.java | 25 ++++--- .../org/sonar/batch/scan/SensorContextAdapter.java | 24 +++--- .../org/sonar/batch/scan2/BaseSensorContext.java | 15 +++- .../sonar/batch/scan2/DefaultSensorContext.java | 36 ++++----- .../sonar/batch/scan2/ProjectScanContainer.java | 8 +- .../org/sonar/batch/test/CoveragePerTestCache.java | 66 ----------------- .../test/DefaultTestCaseCoverageValueCoder.java | 81 ++++++++++++++++++++ .../test/DefaultTestCaseExecutionValueCoder.java | 86 ++++++++++++++++++++++ .../batch/test/DefaultTestCaseValueCoder.java | 86 ---------------------- .../java/org/sonar/batch/test/TestCaseCache.java | 69 ----------------- .../sonar/batch/test/TestCaseCoverageCache.java | 65 ++++++++++++++++ .../sonar/batch/test/TestCaseExecutionCache.java | 69 +++++++++++++++++ .../mediumtest/xoo/sample-with-symlink/.gitignore | 1 + 13 files changed, 358 insertions(+), 273 deletions(-) delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java create mode 100644 sonar-batch/src/test/resources/mediumtest/xoo/sample-with-symlink/.gitignore (limited to 'sonar-batch') diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java index 596edcdec5f..ab8ff21c33c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -36,7 +36,8 @@ import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.Symbol; -import org.sonar.api.batch.sensor.test.TestCase; +import org.sonar.api.batch.sensor.test.TestCaseCoverage; +import org.sonar.api.batch.sensor.test.TestCaseExecution; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.platform.PluginMetadata; @@ -61,8 +62,8 @@ import org.sonar.batch.scan2.MeasureCache; import org.sonar.batch.scan2.ProjectScanContainer; import org.sonar.batch.scan2.ScanTaskObserver; import org.sonar.batch.symbol.SymbolData; -import org.sonar.batch.test.CoveragePerTestCache; -import org.sonar.batch.test.TestCaseCache; +import org.sonar.batch.test.TestCaseCoverageCache; +import org.sonar.batch.test.TestCaseExecutionCache; import org.sonar.core.plugins.DefaultPluginMetadata; import org.sonar.core.plugins.RemotePlugin; import org.sonar.core.source.SnapshotDataTypes; @@ -233,7 +234,7 @@ public class BatchMediumTester { private Map inputDirs = new HashMap(); private Map highlightingPerFile = new HashMap(); private Map symbolTablePerFile = new HashMap(); - private Map> testCasesPerFile = new HashMap>(); + private Map> testCasesPerFile = new HashMap>(); private Map>>> coveragePerTest = new HashMap>>>(); private Map> dependencies = new HashMap>(); @@ -258,8 +259,8 @@ public class BatchMediumTester { } private void storeCoveragePerTest(ProjectScanContainer container) { - CoveragePerTestCache coveragePerTestCache = container.getComponentByType(CoveragePerTestCache.class); - for (Entry> entry : coveragePerTestCache.entries()) { + TestCaseCoverageCache testCaseCoverageCache = container.getComponentByType(TestCaseCoverageCache.class); + for (Entry entry : testCaseCoverageCache.entries()) { String testFileKey = entry.key()[0].toString(); if (!coveragePerTest.containsKey(testFileKey)) { coveragePerTest.put(testFileKey, new HashMap>>()); @@ -268,16 +269,16 @@ public class BatchMediumTester { if (!coveragePerTest.get(testFileKey).containsKey(testName)) { coveragePerTest.get(testFileKey).put(testName, new HashMap>()); } - coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), entry.value()); + coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), entry.value().coveredLines()); } } private void storeTestCases(ProjectScanContainer container) { - TestCaseCache testCaseCache = container.getComponentByType(TestCaseCache.class); - for (Entry entry : testCaseCache.entries()) { + TestCaseExecutionCache testCaseCache = container.getComponentByType(TestCaseExecutionCache.class); + for (Entry entry : testCaseCache.entries()) { String effectiveKey = entry.key()[0].toString(); if (!testCasesPerFile.containsKey(effectiveKey)) { - testCasesPerFile.put(effectiveKey, new HashMap()); + testCasesPerFile.put(effectiveKey, new HashMap()); } testCasesPerFile.get(effectiveKey).put(entry.value().name(), entry.value()); } @@ -358,7 +359,7 @@ public class BatchMediumTester { return duplications.get(((DefaultInputFile) inputFile).key()); } - public Collection testCasesFor(InputFile inputFile) { + public Collection testCasesFor(InputFile inputFile) { String key = ((DefaultInputFile) inputFile).key(); if (testCasesPerFile.containsKey(key)) { return testCasesPerFile.get(key).values(); @@ -367,7 +368,7 @@ public class BatchMediumTester { } } - public TestCase testCase(InputFile inputFile, String testCaseName) { + public TestCaseExecution testCase(InputFile inputFile, String testCaseName) { return testCasesPerFile.get(((DefaultInputFile) inputFile).key()).get(testCaseName); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java index e482d8b86e8..db57aa3d589 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java @@ -19,13 +19,11 @@ */ package org.sonar.batch.scan; -import com.google.common.base.Preconditions; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.SensorContext; @@ -33,8 +31,9 @@ import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; +import org.sonar.api.batch.sensor.test.TestCaseCoverage; +import org.sonar.api.batch.sensor.test.TestCaseExecution; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; import org.sonar.api.component.ResourcePerspectives; import org.sonar.api.config.Settings; import org.sonar.api.design.Dependency; @@ -61,8 +60,6 @@ import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.scan2.BaseSensorContext; import org.sonar.core.component.ComponentKeys; -import java.util.List; - /** * Implements {@link SensorContext} but forward everything to {@link org.sonar.api.batch.SensorContext} for backward compatibility. * Will be dropped once old {@link Sensor} API is dropped. @@ -178,8 +175,8 @@ public class SensorContextAdapter extends BaseSensorContext { } @Override - public void store(TestCase testCase) { - File testRes = getTestResource(((DefaultTestCase) testCase).testFile()); + public void store(TestCaseExecution testCase) { + File testRes = getTestResource(((DefaultTestCaseExecution) testCase).testFile()); MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes); if (testPlan != null) { testPlan @@ -193,16 +190,15 @@ public class SensorContextAdapter extends BaseSensorContext { } @Override - public void saveCoveragePerTest(TestCase testCase, InputFile coveredFile, List coveredLines) { - Preconditions.checkArgument(coveredFile.type() == Type.MAIN, "Should be a main file: " + coveredFile); - File testRes = getTestResource(((DefaultTestCase) testCase).testFile()); - File mainRes = getMainResource(coveredFile); + public void store(TestCaseCoverage testCaseCoverage) { + File testRes = getTestResource(testCaseCoverage.testFile()); + File mainRes = getMainResource(testCaseCoverage.coveredFile()); Testable testAbleFile = perspectives.as(MutableTestable.class, mainRes); if (testAbleFile != null) { MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes); if (testPlan != null) { - for (MutableTestCase mutableTestCase : testPlan.testCasesByName(testCase.name())) { - mutableTestCase.setCoverageBlock(testAbleFile, coveredLines); + for (MutableTestCase mutableTestCase : testPlan.testCasesByName(testCaseCoverage.testName())) { + mutableTestCase.setCoverageBlock(testAbleFile, testCaseCoverage.coveredLines()); } } else { throw new IllegalStateException("Unable to get MutableTestPlan perspective from " + testRes); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java index bb81865c4b6..c925f400100 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java @@ -38,8 +38,10 @@ import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; +import org.sonar.api.batch.sensor.test.TestCaseCoverage; +import org.sonar.api.batch.sensor.test.TestCaseExecution; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; import org.sonar.api.config.Settings; import org.sonar.batch.duplication.BlockCache; import org.sonar.batch.duplication.DefaultTokenBuilder; @@ -153,8 +155,13 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage } @Override - public TestCase newTestCase() { - return new DefaultTestCase(this); + public TestCaseExecution newTestCaseExecution() { + return new DefaultTestCaseExecution(this); + } + + @Override + public TestCaseCoverage newTestCaseCoverage() { + return new DefaultTestCaseCoverage(this); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java index 90fc49ca395..58eaf6d5fa2 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java @@ -19,14 +19,12 @@ */ package org.sonar.batch.scan2; -import com.google.common.base.Preconditions; import com.google.common.base.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.rule.ActiveRules; @@ -36,8 +34,9 @@ import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; +import org.sonar.api.batch.sensor.test.TestCaseCoverage; +import org.sonar.api.batch.sensor.test.TestCaseExecution; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; import org.sonar.api.config.Settings; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; @@ -48,8 +47,8 @@ import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.issue.IssueFilters; import org.sonar.batch.scan.SensorContextAdapter; -import org.sonar.batch.test.CoveragePerTestCache; -import org.sonar.batch.test.TestCaseCache; +import org.sonar.batch.test.TestCaseCoverageCache; +import org.sonar.batch.test.TestCaseExecutionCache; import org.sonar.core.component.ComponentKeys; import java.io.Serializable; @@ -89,20 +88,20 @@ public class DefaultSensorContext extends BaseSensorContext { private final ProjectDefinition def; private final ActiveRules activeRules; private final IssueFilters issueFilters; - private final TestCaseCache testCaseCache; - private final CoveragePerTestCache coveragePerTestCache; + private final TestCaseExecutionCache testCaseExecutionCache; + private final TestCaseCoverageCache coveragePerTestCache; private final DependencyCache dependencyCache; public DefaultSensorContext(ProjectDefinition def, MeasureCache measureCache, IssueCache issueCache, Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache, - BlockCache blockCache, DuplicationCache duplicationCache, TestCaseCache testCaseCache, CoveragePerTestCache coveragePerTestCache, DependencyCache dependencyCache) { + BlockCache blockCache, DuplicationCache duplicationCache, TestCaseExecutionCache testCaseCache, TestCaseCoverageCache coveragePerTestCache, DependencyCache dependencyCache) { super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache); this.def = def; this.measureCache = measureCache; this.issueCache = issueCache; this.activeRules = activeRules; this.issueFilters = issueFilters; - this.testCaseCache = testCaseCache; + this.testCaseExecutionCache = testCaseCache; this.coveragePerTestCache = coveragePerTestCache; this.dependencyCache = dependencyCache; } @@ -157,18 +156,19 @@ public class DefaultSensorContext extends BaseSensorContext { } @Override - public void store(TestCase testCase) { - if (testCaseCache.contains(((DefaultTestCase) testCase).testFile(), testCase.name())) { - throw new IllegalArgumentException("There is already a test case with the same name: " + testCase.name()); + public void store(TestCaseExecution testCaseExecution) { + if (testCaseExecutionCache.contains(((DefaultTestCaseExecution) testCaseExecution).testFile(), testCaseExecution.name())) { + throw new IllegalArgumentException("There is already a test case with the same name: " + testCaseExecution.name()); } - testCaseCache.put(((DefaultTestCase) testCase).testFile(), testCase); + testCaseExecutionCache.put(((DefaultTestCaseExecution) testCaseExecution).testFile(), testCaseExecution); } @Override - public void saveCoveragePerTest(TestCase testCase, InputFile coveredFile, List coveredLines) { - Preconditions.checkNotNull(testCase); - Preconditions.checkArgument(coveredFile.type() == Type.MAIN, "Should be a main file: " + coveredFile); - coveragePerTestCache.put(testCase, coveredFile, coveredLines); + public void store(TestCaseCoverage testCaseCoverage) { + if (coveragePerTestCache.getCoverage(testCaseCoverage.testFile(), testCaseCoverage.testName(), testCaseCoverage.coveredFile()) != null) { + throw new IllegalArgumentException("Test coverage already registered for this combination of test file, test name and main file: " + testCaseCoverage); + } + coveragePerTestCache.put(testCaseCoverage); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java index 431529be787..0da1a2f8d0d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java @@ -48,8 +48,8 @@ import org.sonar.batch.scan.ProjectSettings; import org.sonar.batch.scan.filesystem.InputPathCache; import org.sonar.batch.scan.maven.FakeMavenPluginExecutor; import org.sonar.batch.scan.maven.MavenPluginExecutor; -import org.sonar.batch.test.CoveragePerTestCache; -import org.sonar.batch.test.TestCaseCache; +import org.sonar.batch.test.TestCaseCoverageCache; +import org.sonar.batch.test.TestCaseExecutionCache; public class ProjectScanContainer extends ComponentContainer { public ProjectScanContainer(ComponentContainer taskContainer) { @@ -118,8 +118,8 @@ public class ProjectScanContainer extends ComponentContainer { DuplicationCache.class, // Tests - TestCaseCache.class, - CoveragePerTestCache.class, + TestCaseExecutionCache.class, + TestCaseCoverageCache.class, // Dependencies DependencyCache.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java b/sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java deleted file mode 100644 index 211cfb4ca88..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java +++ /dev/null @@ -1,66 +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.batch.test; - -import com.google.common.base.Preconditions; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; -import org.sonar.batch.index.Cache; -import org.sonar.batch.index.Cache.Entry; -import org.sonar.batch.index.Caches; - -import javax.annotation.CheckForNull; - -import java.util.List; - -/** - * Cache of coverage per test. This cache is shared amongst all project modules. - */ -public class CoveragePerTestCache implements BatchComponent { - - private final Cache> cache; - - public CoveragePerTestCache(Caches caches) { - cache = caches.createCache("coveragePerTest"); - } - - public Iterable>> entries() { - return cache.entries(); - } - - @CheckForNull - public List getCoveredLines(InputFile testFile, String testCaseName, InputFile mainFile) { - Preconditions.checkNotNull(testFile); - Preconditions.checkNotNull(testCaseName); - return cache.get(((DefaultInputFile) testFile).key(), testCaseName, ((DefaultInputFile) mainFile).key()); - } - - public CoveragePerTestCache put(TestCase testCase, InputFile mainFile, List coveredLines) { - Preconditions.checkNotNull(testCase); - Preconditions.checkNotNull(mainFile); - Preconditions.checkNotNull(coveredLines); - cache.put(((DefaultInputFile) ((DefaultTestCase) testCase).testFile()).key(), testCase.name(), ((DefaultInputFile) mainFile).key(), coveredLines); - return this; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java new file mode 100644 index 00000000000..69b7845fb68 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java @@ -0,0 +1,81 @@ +/* + * 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.batch.test; + +import com.persistit.Value; +import com.persistit.encoding.CoderContext; +import com.persistit.encoding.ValueCoder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage; +import org.sonar.batch.scan.filesystem.InputPathCache; + +import java.util.ArrayList; +import java.util.List; + +class DefaultTestCaseCoverageValueCoder implements ValueCoder { + + private InputPathCache inputPathCache; + + public DefaultTestCaseCoverageValueCoder(InputPathCache inputPathCache) { + this.inputPathCache = inputPathCache; + } + + @Override + public void put(Value value, Object object, CoderContext context) { + DefaultTestCaseCoverage t = (DefaultTestCaseCoverage) object; + value.putUTF(((DefaultInputFile) t.testFile()).moduleKey()); + value.putUTF(((DefaultInputFile) t.testFile()).relativePath()); + value.putUTF(t.testName()); + value.putUTF(((DefaultInputFile) t.coveredFile()).moduleKey()); + value.putUTF(((DefaultInputFile) t.coveredFile()).relativePath()); + value.put(t.coveredLines().size()); + for (Integer line : t.coveredLines()) { + value.put(line.intValue()); + } + } + + @Override + public Object get(Value value, Class clazz, CoderContext context) { + String testModuleKey = value.getString(); + String testRelativePath = value.getString(); + InputFile testFile = inputPathCache.getFile(testModuleKey, testRelativePath); + if (testFile == null) { + throw new IllegalStateException("Unable to load InputFile " + testModuleKey + ":" + testRelativePath); + } + String name = value.getString(); + String mainModuleKey = value.getString(); + String mainRelativePath = value.getString(); + InputFile mainFile = inputPathCache.getFile(mainModuleKey, mainRelativePath); + if (mainFile == null) { + throw new IllegalStateException("Unable to load InputFile " + mainModuleKey + ":" + mainRelativePath); + } + int size = value.getInt(); + List lines = new ArrayList(size); + for (int i = 0; i < size; i++) { + lines.add(value.getInt()); + } + return new DefaultTestCaseCoverage() + .testFile(testFile) + .testName(name) + .cover(mainFile) + .onLines(lines); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java new file mode 100644 index 00000000000..9b0bcf722db --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java @@ -0,0 +1,86 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.test; + +import com.persistit.Value; +import com.persistit.encoding.CoderContext; +import com.persistit.encoding.ValueCoder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.test.TestCaseExecution; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; +import org.sonar.batch.scan.filesystem.InputPathCache; + +import javax.annotation.Nullable; + +class DefaultTestCaseExecutionValueCoder implements ValueCoder { + + private InputPathCache inputPathCache; + + public DefaultTestCaseExecutionValueCoder(InputPathCache inputPathCache) { + this.inputPathCache = inputPathCache; + } + + @Override + public void put(Value value, Object object, CoderContext context) { + DefaultTestCaseExecution t = (DefaultTestCaseExecution) object; + value.putUTF(((DefaultInputFile) t.testFile()).moduleKey()); + value.putUTF(((DefaultInputFile) t.testFile()).relativePath()); + value.putUTF(t.name()); + putUTFOrNull(value, t.message()); + putUTFOrNull(value, t.stackTrace()); + Long durationInMs = t.durationInMs(); + value.put(durationInMs != null ? durationInMs.longValue() : -1); + value.put(t.type().ordinal()); + value.put(t.status().ordinal()); + } + + private void putUTFOrNull(Value value, @Nullable String utfOrNull) { + if (utfOrNull != null) { + value.putUTF(utfOrNull); + } else { + value.putNull(); + } + } + + @Override + public Object get(Value value, Class clazz, CoderContext context) { + String moduleKey = value.getString(); + String relativePath = value.getString(); + InputFile testFile = inputPathCache.getFile(moduleKey, relativePath); + if (testFile == null) { + throw new IllegalStateException("Unable to load InputFile " + moduleKey + ":" + relativePath); + } + String name = value.getString(); + String message = value.getString(); + String stack = value.getString(); + long duration = value.getLong(); + TestCaseExecution.Type type = TestCaseExecution.Type.values()[value.getInt()]; + TestCaseExecution.Status status = TestCaseExecution.Status.values()[value.getInt()]; + return new DefaultTestCaseExecution() + .inTestFile(testFile) + .ofType(type) + .name(name) + .durationInMs(duration != -1 ? duration : null) + .status(status) + .message(message) + .stackTrace(stack); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java deleted file mode 100644 index 402cc624361..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java +++ /dev/null @@ -1,86 +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.batch.test; - -import com.persistit.Value; -import com.persistit.encoding.CoderContext; -import com.persistit.encoding.ValueCoder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; -import org.sonar.batch.scan.filesystem.InputPathCache; - -import javax.annotation.Nullable; - -class DefaultTestCaseValueCoder implements ValueCoder { - - private InputPathCache inputPathCache; - - public DefaultTestCaseValueCoder(InputPathCache inputPathCache) { - this.inputPathCache = inputPathCache; - } - - @Override - public void put(Value value, Object object, CoderContext context) { - DefaultTestCase t = (DefaultTestCase) object; - value.putUTF(((DefaultInputFile) t.testFile()).moduleKey()); - value.putUTF(((DefaultInputFile) t.testFile()).relativePath()); - value.putUTF(t.name()); - putUTFOrNull(value, t.message()); - putUTFOrNull(value, t.stackTrace()); - Long durationInMs = t.durationInMs(); - value.put(durationInMs != null ? durationInMs.longValue() : -1); - value.put(t.type().ordinal()); - value.put(t.status().ordinal()); - } - - private void putUTFOrNull(Value value, @Nullable String utfOrNull) { - if (utfOrNull != null) { - value.putUTF(utfOrNull); - } else { - value.putNull(); - } - } - - @Override - public Object get(Value value, Class clazz, CoderContext context) { - String moduleKey = value.getString(); - String relativePath = value.getString(); - InputFile testFile = inputPathCache.getFile(moduleKey, relativePath); - if (testFile == null) { - throw new IllegalStateException("Unable to load InputFile " + moduleKey + ":" + relativePath); - } - String name = value.getString(); - String message = value.getString(); - String stack = value.getString(); - long duration = value.getLong(); - TestCase.Type type = TestCase.Type.values()[value.getInt()]; - TestCase.Status status = TestCase.Status.values()[value.getInt()]; - return new DefaultTestCase() - .inTestFile(testFile) - .ofType(type) - .name(name) - .durationInMs(duration != -1 ? duration : null) - .status(status) - .message(message) - .stackTrace(stack); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java b/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java deleted file mode 100644 index e2de947e544..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java +++ /dev/null @@ -1,69 +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.batch.test; - -import com.google.common.base.Preconditions; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.test.TestCase; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCase; -import org.sonar.batch.index.Cache; -import org.sonar.batch.index.Cache.Entry; -import org.sonar.batch.index.Caches; -import org.sonar.batch.scan.filesystem.InputPathCache; - -import javax.annotation.CheckForNull; - -/** - * Cache of all TestCases. This cache is shared amongst all project modules. - */ -public class TestCaseCache implements BatchComponent { - - private final Cache cache; - - public TestCaseCache(Caches caches, InputPathCache inputPathCache) { - caches.registerValueCoder(DefaultTestCase.class, new DefaultTestCaseValueCoder(inputPathCache)); - cache = caches.createCache("testCases"); - } - - public Iterable> entries() { - return cache.entries(); - } - - @CheckForNull - public TestCase get(InputFile testFile, String testCaseName) { - Preconditions.checkNotNull(testFile); - Preconditions.checkNotNull(testCaseName); - return cache.get(((DefaultInputFile) testFile).key(), testCaseName); - } - - public TestCaseCache put(InputFile testFile, TestCase testCase) { - Preconditions.checkNotNull(testFile); - Preconditions.checkNotNull(testCase); - cache.put(((DefaultInputFile) testFile).key(), testCase.name(), testCase); - return this; - } - - public boolean contains(InputFile testFile, String name) { - return cache.containsKey(((DefaultInputFile) testFile).key(), name); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java b/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java new file mode 100644 index 00000000000..7e52932cf2f --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java @@ -0,0 +1,65 @@ +/* + * 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.batch.test; + +import com.google.common.base.Preconditions; +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.test.TestCaseCoverage; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage; +import org.sonar.batch.index.Cache; +import org.sonar.batch.index.Cache.Entry; +import org.sonar.batch.index.Caches; +import org.sonar.batch.scan.filesystem.InputPathCache; + +import javax.annotation.CheckForNull; + +/** + * Cache of coverage per test. This cache is shared amongst all project modules. + */ +public class TestCaseCoverageCache implements BatchComponent { + + private final Cache cache; + + public TestCaseCoverageCache(Caches caches, InputPathCache inputPathCache) { + caches.registerValueCoder(DefaultTestCaseCoverage.class, new DefaultTestCaseCoverageValueCoder(inputPathCache)); + cache = caches.createCache("testCaseCoverage"); + } + + public Iterable> entries() { + return cache.entries(); + } + + @CheckForNull + public TestCaseCoverage getCoverage(InputFile testFile, String testCaseName, InputFile mainFile) { + Preconditions.checkNotNull(testFile); + Preconditions.checkNotNull(testCaseName); + Preconditions.checkNotNull(mainFile); + return cache.get(((DefaultInputFile) testFile).key(), testCaseName, ((DefaultInputFile) mainFile).key()); + } + + public TestCaseCoverageCache put(TestCaseCoverage coverage) { + Preconditions.checkNotNull(coverage); + cache.put(((DefaultInputFile) coverage.testFile()).key(), coverage.testName(), ((DefaultInputFile) coverage.coveredFile()).key(), coverage); + return this; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java b/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java new file mode 100644 index 00000000000..02dab1cfa52 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java @@ -0,0 +1,69 @@ +/* + * 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.batch.test; + +import com.google.common.base.Preconditions; +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.test.TestCaseExecution; +import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; +import org.sonar.batch.index.Cache; +import org.sonar.batch.index.Cache.Entry; +import org.sonar.batch.index.Caches; +import org.sonar.batch.scan.filesystem.InputPathCache; + +import javax.annotation.CheckForNull; + +/** + * Cache of all TestCases. This cache is shared amongst all project modules. + */ +public class TestCaseExecutionCache implements BatchComponent { + + private final Cache cache; + + public TestCaseExecutionCache(Caches caches, InputPathCache inputPathCache) { + caches.registerValueCoder(DefaultTestCaseExecution.class, new DefaultTestCaseExecutionValueCoder(inputPathCache)); + cache = caches.createCache("testCaseExecutions"); + } + + public Iterable> entries() { + return cache.entries(); + } + + @CheckForNull + public TestCaseExecution get(InputFile testFile, String testCaseName) { + Preconditions.checkNotNull(testFile); + Preconditions.checkNotNull(testCaseName); + return cache.get(((DefaultInputFile) testFile).key(), testCaseName); + } + + public TestCaseExecutionCache put(InputFile testFile, TestCaseExecution testCase) { + Preconditions.checkNotNull(testFile); + Preconditions.checkNotNull(testCase); + cache.put(((DefaultInputFile) testFile).key(), testCase.name(), testCase); + return this; + } + + public boolean contains(InputFile testFile, String name) { + return cache.containsKey(((DefaultInputFile) testFile).key(), name); + } + +} diff --git a/sonar-batch/src/test/resources/mediumtest/xoo/sample-with-symlink/.gitignore b/sonar-batch/src/test/resources/mediumtest/xoo/sample-with-symlink/.gitignore new file mode 100644 index 00000000000..ecbefd4f19d --- /dev/null +++ b/sonar-batch/src/test/resources/mediumtest/xoo/sample-with-symlink/.gitignore @@ -0,0 +1 @@ +.sonar -- cgit v1.2.3