From abe0b5d895dc8b1abc60ff645a60cd3c32ee05bd Mon Sep 17 00:00:00 2001 From: Janos Gyerik Date: Mon, 6 Mar 2017 08:44:48 +0100 Subject: [PATCH] Add unit tests to verify behavior depending on sensor strategy (#1745) --- .../ScannerExtensionDictionnaryTest.java | 34 +++--- .../scanner/phases/SensorsExecutorTest.java | 107 ++++++++++++++++++ .../filesystem/InputComponentStoreTest.java | 54 ++++++++- .../ModuleInputComponentStoreTest.java | 53 ++++++++- 4 files changed, 220 insertions(+), 28 deletions(-) create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnaryTest.java index e805f490e2e..c3c8b131b6a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnaryTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerExtensionDictionnaryTest.java @@ -42,7 +42,6 @@ import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.postjob.PostJobOptimizer; import org.sonar.scanner.sensor.DefaultSensorContext; import org.sonar.scanner.sensor.SensorOptimizer; -import org.sonar.scanner.sensor.SensorWrapper; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; @@ -319,27 +318,22 @@ public class ScannerExtensionDictionnaryTest { } @Test - public void querySensors() { - BatchExtension pre = new PreSensorSubclass(); - BatchExtension analyze = new GeneratesSomething("something"); - BatchExtension post = new PostSensorSubclass(); - - FakeSensor fakeSensor = new FakeSensor(); - FakeNewSensor fakeNewSensor = new FakeNewSensor(); - FakeNewGlobalSensor fakeNewGlobalSensor = new FakeNewGlobalSensor(); - ScannerExtensionDictionnary selector = newSelector(fakeSensor, fakeNewSensor, fakeNewGlobalSensor); - List extensions = Lists.newArrayList(selector.selectSensors(null, false)); - + public void selectSensors() { + FakeSensor oldSensor = new FakeSensor(); + FakeNewSensor nonGlobalSensor = new FakeNewSensor(); + FakeNewGlobalSensor globalSensor = new FakeNewGlobalSensor(); + ScannerExtensionDictionnary selector = newSelector(oldSensor, nonGlobalSensor, globalSensor); + + // verify non-global sensors + Collection extensions = selector.selectSensors(null, false); assertThat(extensions).hasSize(2); - assertThat(extensions).contains(fakeSensor); - extensions.remove(fakeSensor); - assertThat(extensions.get(0)).isInstanceOf(SensorWrapper.class); - assertThat(((SensorWrapper) extensions.get(0)).wrappedSensor()).isEqualTo(fakeNewSensor); - - extensions = Lists.newArrayList(selector.selectSensors(null, true)); + assertThat(extensions).contains(oldSensor); + extensions.remove(oldSensor); + assertThat(extensions).extracting("wrappedSensor").containsExactly(nonGlobalSensor); - assertThat(extensions.get(0)).isInstanceOf(SensorWrapper.class); - assertThat(((SensorWrapper) extensions.get(0)).wrappedSensor()).isEqualTo(fakeNewGlobalSensor); + // verify global sensors + extensions = selector.selectSensors(null, true); + assertThat(extensions).extracting("wrappedSensor").containsExactly(globalSensor); } class FakeSensor implements Sensor { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java new file mode 100644 index 00000000000..b7431b1ac7d --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java @@ -0,0 +1,107 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.phases; + +import java.io.IOException; +import java.util.Collections; +import org.junit.*; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.resources.Project; +import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary; +import org.sonar.scanner.events.EventBus; +import org.sonar.scanner.sensor.SensorStrategy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +public class SensorsExecutorTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private SensorsExecutor rootModuleExecutor; + private SensorsExecutor subModuleExecutor; + private SensorContext context; + + private SensorStrategy strategy = new SensorStrategy(); + + private TestSensor perModuleSensor = new TestSensor(strategy); + private TestSensor globalSensor = new TestSensor(strategy); + + static class TestSensor implements Sensor { + final SensorStrategy strategy; + + boolean called; + boolean global; + + TestSensor(SensorStrategy strategy) { + this.strategy = strategy; + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + @Override + public void analyse(Project module, SensorContext context) { + called = true; + global = strategy.isGlobal(); + } + } + + @Before + public void setUp() throws IOException { + context = mock(SensorContext.class); + + ScannerExtensionDictionnary selector = mock(ScannerExtensionDictionnary.class); + when(selector.selectSensors(any(DefaultInputModule.class), eq(false))).thenReturn(Collections.singleton(perModuleSensor)); + when(selector.selectSensors(any(DefaultInputModule.class), eq(true))).thenReturn(Collections.singleton(globalSensor)); + + DefaultInputModule rootModule = TestInputFileBuilder.newDefaultInputModule("root", temp.newFolder()); + rootModuleExecutor = new SensorsExecutor(selector, rootModule, mock(EventBus.class), strategy); + + DefaultInputModule subModule = TestInputFileBuilder.newDefaultInputModule("sub", temp.newFolder()); + rootModule.definition().addSubProject(subModule.definition()); + subModuleExecutor = new SensorsExecutor(selector, subModule, mock(EventBus.class), strategy); + } + + @Test + public void should_not_execute_global_sensor_for_submodule() { + subModuleExecutor.execute(context); + + assertThat(perModuleSensor.called).isTrue(); + assertThat(perModuleSensor.global).isFalse(); + assertThat(globalSensor.called).isFalse(); + } + + @Test + public void should_execute_all_sensors_for_root_module() { + rootModuleExecutor.execute(context); + + assertThat(perModuleSensor.called).isTrue(); + assertThat(perModuleSensor.global).isFalse(); + assertThat(globalSensor.called).isTrue(); + assertThat(globalSensor.global).isTrue(); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java index 6b5a8b1ace1..6bff097acf3 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java @@ -20,10 +20,11 @@ package org.sonar.scanner.scan.filesystem; import java.io.File; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; -import org.junit.Rule; +import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; @@ -38,8 +39,8 @@ import org.sonar.api.scan.filesystem.PathResolver; import static org.assertj.core.api.Assertions.assertThat; public class InputComponentStoreTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); + @ClassRule + public static TemporaryFolder temp = new TemporaryFolder(); @Test public void should_add_input_file() throws Exception { @@ -83,7 +84,7 @@ public class InputComponentStoreTest { List toPublish = new LinkedList<>(); cache.allFilesToPublish().forEach(toPublish::add); - assertThat(toPublish).containsOnly(fooFile); + assertThat(toPublish).containsExactly(fooFile); cache.remove(fooFile); assertThat(cache.allFiles()).hasSize(1); @@ -94,4 +95,49 @@ public class InputComponentStoreTest { assertThat(cache.allFiles()).hasSize(1); } + static class InputComponentStoreTester extends InputComponentStore { + InputComponentStoreTester() throws IOException { + super(new PathResolver()); + DefaultInputModule root = TestInputFileBuilder.newDefaultInputModule("root", temp.newFolder()); + put(root); + } + + InputFile addFile(String moduleKey, String relpath, String language) { + DefaultInputFile file = new TestInputFileBuilder(moduleKey, relpath) + .setLanguage(language) + .build(); + put(file); + return file; + } + } + + @Test + public void should_add_languages_per_module_and_globally() throws IOException { + InputComponentStoreTester tester = new InputComponentStoreTester(); + + String mod1Key = "mod1"; + tester.addFile(mod1Key, "src/main/java/Foo.java", "java"); + + String mod2Key = "mod2"; + tester.addFile(mod2Key, "src/main/groovy/Foo.groovy", "groovy"); + + assertThat(tester.getLanguages(mod1Key)).containsExactly("java"); + assertThat(tester.getLanguages(mod2Key)).containsExactly("groovy"); + assertThat(tester.getLanguages()).containsExactlyInAnyOrder("java", "groovy"); + } + + @Test + public void should_find_files_per_module_and_globally() throws IOException { + InputComponentStoreTester tester = new InputComponentStoreTester(); + + String mod1Key = "mod1"; + InputFile mod1File = tester.addFile(mod1Key, "src/main/java/Foo.java", "java"); + + String mod2Key = "mod2"; + InputFile mod2File = tester.addFile(mod2Key, "src/main/groovy/Foo.groovy", "groovy"); + + assertThat(tester.filesByModule(mod1Key)).containsExactly(mod1File); + assertThat(tester.filesByModule(mod2Key)).containsExactly(mod2File); + assertThat(tester.allFiles()).containsExactlyInAnyOrder(mod1File, mod2File); + } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java index eeb3b951fb1..cb018de8258 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java @@ -31,7 +31,10 @@ import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.scanner.sensor.SensorStrategy; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; public class ModuleInputComponentStoreTest { @Rule @@ -61,7 +64,7 @@ public class ModuleInputComponentStoreTest { InputFile dummyInputFile = new TestInputFileBuilder(moduleKey, "some/path/Dummy.java").build(); store.doAdd(dummyInputFile); - assertThat(store.getFilesByName(filename)).containsOnly(inputFile1, inputFile2); + assertThat(store.getFilesByName(filename)).containsExactlyInAnyOrder(inputFile1, inputFile2); } @Test @@ -77,7 +80,7 @@ public class ModuleInputComponentStoreTest { InputFile dummyInputFile = new TestInputFileBuilder(moduleKey, "some/path/NotJava.cpp").build(); store.doAdd(dummyInputFile); - assertThat(store.getFilesByExtension("java")).containsOnly(inputFile1, inputFile2); + assertThat(store.getFilesByExtension("java")).containsExactlyInAnyOrder(inputFile1, inputFile2); } @Test @@ -91,8 +94,8 @@ public class ModuleInputComponentStoreTest { store.doAdd(inputFile); store.doAdd(inputFile); - assertThat(store.getFilesByName(filename)).containsOnly(inputFile); - assertThat(store.getFilesByExtension(ext)).containsOnly(inputFile); + assertThat(store.getFilesByName(filename)).containsExactly(inputFile); + assertThat(store.getFilesByExtension(ext)).containsExactly(inputFile); } @Test @@ -111,4 +114,46 @@ public class ModuleInputComponentStoreTest { private ModuleInputComponentStore newModuleInputComponentStore() { return new ModuleInputComponentStore(mock(InputModule.class), componentStore, mock(SensorStrategy.class)); } + + @Test + public void should_find_module_components_with_non_global_strategy() { + InputComponentStore inputComponentStore = mock(InputComponentStore.class); + SensorStrategy strategy = new SensorStrategy(); + ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), inputComponentStore, strategy); + + store.inputFiles(); + verify(inputComponentStore).filesByModule(any(String.class)); + + String relativePath = "somepath"; + store.inputFile(relativePath); + verify(inputComponentStore).getFile(any(String.class), eq(relativePath)); + + store.inputDir(relativePath); + verify(inputComponentStore).getDir(any(String.class), eq(relativePath)); + + store.languages(); + verify(inputComponentStore).getLanguages(any(String.class)); + } + + @Test + public void should_find_all_components_with_global_strategy() { + InputComponentStore inputComponentStore = mock(InputComponentStore.class); + SensorStrategy strategy = new SensorStrategy(); + ModuleInputComponentStore store = new ModuleInputComponentStore(mock(InputModule.class), inputComponentStore, strategy); + + strategy.setGlobal(true); + + store.inputFiles(); + verify(inputComponentStore).allFiles(); + + String relativePath = "somepath"; + store.inputFile(relativePath); + verify(inputComponentStore).getFile(relativePath); + + store.inputDir(relativePath); + verify(inputComponentStore).getDir(relativePath); + + store.languages(); + verify(inputComponentStore).getLanguages(); + } } -- 2.39.5