aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2022-02-01 15:16:25 -0600
committersonartech <sonartech@sonarsource.com>2022-02-22 20:02:46 +0000
commit60c1a4038e041a342dda9810e6fd761d66b01bdb (patch)
tree0e76b4252e4d7d257cf4ddcb6f081996bb1e03ab /sonar-scanner-engine
parent9694d4113bf401b84e86e0223dbea8f5339388d8 (diff)
downloadsonarqube-60c1a4038e041a342dda9810e6fd761d66b01bdb.tar.gz
sonarqube-60c1a4038e041a342dda9810e6fd761d66b01bdb.zip
SONAR-15994 Migrate Sonarqube IOC framework from Pico to Spring
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/build.gradle2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java62
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java61
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java35
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java123
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java227
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java1
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java60
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java3
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java36
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java3
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java36
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java2
-rw-r--r--sonar-scanner-engine/src/main/resources/org/sonar/batch/bootstrapper/logback.xml2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java14
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessorTest.java41
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java113
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java42
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PriorityBeanFactoryTest.java103
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java217
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessorTest.java64
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java19
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumTest.java4
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java55
27 files changed, 174 insertions, 1160 deletions
diff --git a/sonar-scanner-engine/build.gradle b/sonar-scanner-engine/build.gradle
index f3fa9ffdad9..3aa87f8962b 100644
--- a/sonar-scanner-engine/build.gradle
+++ b/sonar-scanner-engine/build.gradle
@@ -29,7 +29,6 @@ dependencies {
compile 'javax.annotation:javax.annotation-api'
compile 'org.eclipse.jgit:org.eclipse.jgit'
compile 'org.tmatesoft.svnkit:svnkit'
- compile 'org.picocontainer:picocontainer'
compile 'org.slf4j:jcl-over-slf4j'
compile 'org.slf4j:jul-to-slf4j'
compile 'org.slf4j:log4j-over-slf4j'
@@ -60,7 +59,6 @@ dependencies {
testCompile 'org.mockito:mockito-core'
testCompile project(':plugins:sonar-xoo-plugin')
testCompile project(':sonar-plugin-api').sourceSets.test.output
-
}
license {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java
index 753a6f3b711..8bc4ec75ce5 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java
@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Bean;
public class AnalysisTempFolderProvider {
static final String TMP_NAME = ".sonartmp";
- @Bean("TempFolder")
+ @Bean("AnalysisTempFolder")
public TempFolder provide(DefaultInputProject project) {
Path workingDir = project.getWorkDir();
Path tempDir = workingDir.normalize().resolve(TMP_NAME);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java
deleted file mode 100644
index 0743b81f1f6..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ClassDerivedBeanDefinition.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import java.lang.reflect.Constructor;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.lang.Nullable;
-
-/**
- * Taken from Spring's GenericApplicationContext.ClassDerivedBeanDefinition.
- */
-public class ClassDerivedBeanDefinition extends RootBeanDefinition {
- public ClassDerivedBeanDefinition(Class<?> beanClass) {
- super(beanClass);
- }
-
- public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) {
- super(original);
- }
-
- /**
- * This method gets called from AbstractAutowireCapableBeanFactory#createBeanInstance when a bean is instantiated.
- * It first tries to look at annotations or any other methods provided by bean post processors. If a constructor can't be determined, it will fallback to this method.
- */
- @Override
- @Nullable
- public Constructor<?>[] getPreferredConstructors() {
- Class<?> clazz = getBeanClass();
- Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
- if (primaryCtor != null) {
- return new Constructor<?>[] {primaryCtor};
- }
- Constructor<?>[] publicCtors = clazz.getConstructors();
- if (publicCtors.length > 0) {
- return publicCtors;
- }
- return null;
- }
-
- @Override
- public RootBeanDefinition cloneBeanDefinition() {
- return new ClassDerivedBeanDefinition(this);
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java
index 4cc825c1930..7eb63a5b9a0 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalTempFolderProvider.java
@@ -19,32 +19,30 @@
*/
package org.sonar.scanner.bootstrap;
-import java.io.IOException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
-import org.sonar.api.Startable;
import org.sonar.api.impl.utils.DefaultTempFolder;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.TempFolder;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import static org.sonar.core.util.FileUtils.deleteQuietly;
import org.springframework.context.annotation.Bean;
-import static org.sonar.core.util.FileUtils.deleteQuietly;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.concurrent.TimeUnit;
-public class GlobalTempFolderProvider implements Startable {
+public class GlobalTempFolderProvider {
private static final Logger LOG = Loggers.get(GlobalTempFolderProvider.class);
private static final long CLEAN_MAX_AGE = TimeUnit.DAYS.toMillis(21);
static final String TMP_NAME_PREFIX = ".sonartmp_";
private System2 system;
- private DefaultTempFolder tempFolder;
public GlobalTempFolderProvider() {
this(new System2());
@@ -54,26 +52,24 @@ public class GlobalTempFolderProvider implements Startable {
this.system = system;
}
- @Bean("TempFolder")
+ @Bean("GlobalTempFolder")
public TempFolder provide(ScannerProperties scannerProps) {
- if (tempFolder == null) {
- String workingPathName = StringUtils.defaultIfBlank(scannerProps.property(CoreProperties.GLOBAL_WORKING_DIRECTORY), CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE);
- Path workingPath = Paths.get(workingPathName);
+ String workingPathName = StringUtils.defaultIfBlank(scannerProps.property(CoreProperties.GLOBAL_WORKING_DIRECTORY), CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE);
+ Path workingPath = Paths.get(workingPathName);
- if (!workingPath.isAbsolute()) {
- Path home = findSonarHome(scannerProps);
- workingPath = home.resolve(workingPath).normalize();
- }
- try {
- cleanTempFolders(workingPath);
- } catch (IOException e) {
- LOG.error(String.format("failed to clean global working directory: %s", workingPath), e);
- }
- Path tempDir = createTempFolder(workingPath);
- tempFolder = new DefaultTempFolder(tempDir.toFile(), true);
+ if (!workingPath.isAbsolute()) {
+ Path home = findSonarHome(scannerProps);
+ workingPath = home.resolve(workingPath).normalize();
}
- return tempFolder;
+ try {
+ cleanTempFolders(workingPath);
+ } catch (IOException e) {
+ LOG.error(String.format("failed to clean global working directory: %s", workingPath), e);
+ }
+ Path tempDir = createTempFolder(workingPath);
+ return new DefaultTempFolder(tempDir.toFile(), true);
+
}
private static Path createTempFolder(Path workingPath) {
@@ -148,15 +144,4 @@ public class GlobalTempFolderProvider implements Startable {
}
}
- @Override
- public void start() {
- // nothing to do
- }
-
- @Override
- public void stop() {
- if (tempFolder != null) {
- tempFolder.stop();
- }
- }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java
deleted file mode 100644
index 61fcb419d60..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-
-public class LazyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
- for (String beanName : beanFactory.getBeanDefinitionNames()) {
- BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
- beanDefinition.setLazyInit(true);
- }
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java
deleted file mode 100644
index 6d5a73b2369..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PriorityBeanFactory.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-
-public class PriorityBeanFactory extends DefaultListableBeanFactory {
- /**
- * Determines highest priority of the bean candidates.
- * Does not take into account the @Primary annotations.
- * This gets called from {@link DefaultListableBeanFactory#determineAutowireCandidate} when the bean factory is finding the beans to autowire. That method
- * checks for @Primary before calling this method.
- *
- * The strategy is to look at the @Priority annotations. If there are ties, we give priority to components that were added to child containers over their parents.
- * If there are still ties, null is returned, which will ultimately cause Spring to throw a NoUniqueBeanDefinitionException.
- */
- @Override
- @Nullable
- protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
- List<Bean> candidateBeans = candidates.entrySet().stream()
- .filter(e -> e.getValue() != null)
- .map(e -> new Bean(e.getKey(), e.getValue()))
- .collect(Collectors.toUnmodifiableList());
-
- List<Bean> beansAfterPriority = highestPriority(candidateBeans, b -> getPriority(b.getInstance()));
- if (beansAfterPriority.isEmpty()) {
- return null;
- } else if (beansAfterPriority.size() == 1) {
- return beansAfterPriority.get(0).getName();
- }
-
- List<Bean> beansAfterHierarchy = highestPriority(beansAfterPriority, b -> getHierarchyPriority(b.getName()));
- if (beansAfterHierarchy.size() == 1) {
- return beansAfterHierarchy.get(0).getName();
- }
-
- return null;
- }
-
- private static List<Bean> highestPriority(List<Bean> candidates, PriorityFunction function) {
- List<Bean> highestPriorityBeans = new ArrayList<>();
- Integer highestPriority = null;
-
- for (Bean candidate : candidates) {
- Integer candidatePriority = function.classify(candidate);
- if (candidatePriority == null) {
- candidatePriority = Integer.MAX_VALUE;
- }
- if (highestPriority == null) {
- highestPriority = candidatePriority;
- highestPriorityBeans.add(candidate);
- } else if (candidatePriority < highestPriority) {
- highestPriorityBeans.clear();
- highestPriority = candidatePriority;
- highestPriorityBeans.add(candidate);
- } else if (candidatePriority.equals(highestPriority)) {
- highestPriorityBeans.add(candidate);
- }
- }
- return highestPriorityBeans;
- }
-
- @CheckForNull
- private Integer getHierarchyPriority(String beanName) {
- DefaultListableBeanFactory factory = this;
- int i = 1;
- while (factory != null) {
- if (factory.containsBeanDefinition(beanName)) {
- return i;
- }
- factory = (DefaultListableBeanFactory) factory.getParentBeanFactory();
- i++;
- }
- return null;
- }
-
- private static class Bean {
- private final String name;
- private final Object instance;
-
- public Bean(String name, Object instance) {
- this.name = name;
- this.instance = instance;
- }
-
- public String getName() {
- return name;
- }
-
- public Object getInstance() {
- return instance;
- }
- }
-
- @FunctionalInterface
- private interface PriorityFunction {
- @Nullable
- Integer classify(Bean candidate);
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java
deleted file mode 100644
index 17325193d5b..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-import javax.annotation.CheckForNull;
-import org.jetbrains.annotations.Nullable;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.utils.System2;
-import org.sonar.core.platform.ComponentKeys;
-import org.sonar.core.platform.Container;
-import org.sonar.core.platform.ExtensionContainer;
-import org.sonar.core.platform.PluginInfo;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static java.util.Collections.emptyList;
-import static java.util.Optional.ofNullable;
-
-public class SpringComponentContainer implements ExtensionContainer {
- protected final AnnotationConfigApplicationContext context;
- @Nullable
- protected final SpringComponentContainer parent;
-
- private final PropertyDefinitions propertyDefinitions;
- private final ComponentKeys componentKeys = new ComponentKeys();
-
- protected SpringComponentContainer() {
- this(null, new PropertyDefinitions(System2.INSTANCE), emptyList());
- }
-
- protected SpringComponentContainer(List<?> externalExtensions) {
- this(null, new PropertyDefinitions(System2.INSTANCE), externalExtensions);
- }
-
- protected SpringComponentContainer(SpringComponentContainer parent) {
- this(parent, parent.propertyDefinitions, emptyList());
- }
-
- private SpringComponentContainer(@Nullable SpringComponentContainer parent, PropertyDefinitions propertyDefinitions, List<?> externalExtensions) {
- this.parent = parent;
- this.propertyDefinitions = propertyDefinitions;
- this.context = new AnnotationConfigApplicationContext(new PriorityBeanFactory());
- if (parent != null) {
- context.setParent(parent.context);
- }
- add(this);
- add(new StartableBeanPostProcessor());
- add(externalExtensions);
- add(propertyDefinitions);
- }
-
- /**
- * Beans need to have a unique name, otherwise they'll override each other.
- * The strategy is:
- * - For classes, use the classloader + fully qualified class name as the name of the bean
- * - For instances, use the Classloader + FQCN + toString()
- * - If the object is a collection, iterate through the elements and apply the same strategy for each of them
- */
- @Override
- public Container add(Object... objects) {
- for (Object o : objects) {
- if (o instanceof Class) {
- Class<?> clazz = (Class<?>) o;
- context.registerBean(componentKeys.ofClass(clazz), clazz);
- } else if (o instanceof Iterable) {
- add(Iterables.toArray((Iterable<?>) o, Object.class));
- } else {
- registerInstance(o);
- }
- }
- return this;
- }
-
- private <T> void registerInstance(T instance) {
- Supplier<T> supplier = () -> instance;
- Class<T> clazz = (Class<T>) instance.getClass();
- context.registerBean(componentKeys.ofInstance(instance), clazz, supplier);
- declareExtension("", instance);
- }
-
- /**
- * Extensions are usually added by plugins and we assume they don't support any injection-related annotations.
- * Spring contexts supporting annotations will fail if multiple constructors are present without any annotations indicating which one to use for injection.
- * For that reason, we need to create the beans ourselves, using ClassDerivedBeanDefinition, which will declare that all constructors can be used for injection.
- */
- private Container addExtension(Object o) {
- if (o instanceof Class) {
- Class<?> clazz = (Class<?>) o;
- ClassDerivedBeanDefinition bd = new ClassDerivedBeanDefinition(clazz);
- context.registerBeanDefinition(componentKeys.ofClass(clazz), bd);
- } else if (o instanceof Iterable) {
- ((Iterable<?>) o).forEach(this::addExtension);
- } else {
- ClassDerivedBeanDefinition bd = new ClassDerivedBeanDefinition(o.getClass());
- bd.setInstanceSupplier(() -> o);
- context.registerBeanDefinition(componentKeys.ofInstance(o), bd);
- }
- return this;
- }
-
- @Override
- public Container addSingletons(Iterable<?> components) {
- return add(components);
- }
-
- @Override
- public <T> T getComponentByType(Class<T> type) {
- try {
- return context.getBean(type);
- } catch (Exception t) {
- throw new IllegalStateException("Unable to load component " + type, t);
- }
- }
-
- @Override
- public <T> List<T> getComponentsByType(Class<T> type) {
- try {
- return new ArrayList<>(context.getBeansOfType(type).values());
- } catch (Exception t) {
- throw new IllegalStateException("Unable to load components " + type, t);
- }
- }
-
- public void execute() {
- RuntimeException r = null;
- try {
- startComponents();
- } catch (RuntimeException e) {
- r = e;
- } finally {
- try {
- stopComponents();
- } catch (RuntimeException e) {
- if (r == null) {
- r = e;
- }
- }
- }
- if (r != null) {
- throw r;
- }
- }
-
- public SpringComponentContainer startComponents() {
- doBeforeStart();
- context.refresh();
- doAfterStart();
- return this;
- }
-
- public SpringComponentContainer stopComponents() {
- if (context.isActive()) {
- context.close();
- }
- return this;
- }
-
- public SpringComponentContainer createChild() {
- return new SpringComponentContainer(this);
- }
-
- @Override
- @CheckForNull
- public SpringComponentContainer getParent() {
- return parent;
- }
-
- @Override
- public SpringComponentContainer addExtension(@Nullable PluginInfo pluginInfo, Object extension) {
- addExtension(extension);
- declareExtension(pluginInfo, extension);
- return this;
- }
-
- @Override
- public SpringComponentContainer addExtension(@Nullable String defaultCategory, Object extension) {
- addExtension(extension);
- declareExtension(defaultCategory, extension);
- return this;
- }
-
- @Override
- public SpringComponentContainer declareExtension(@Nullable PluginInfo pluginInfo, Object extension) {
- declareExtension(pluginInfo != null ? pluginInfo.getName() : "", extension);
- return this;
- }
-
- @Override
- public SpringComponentContainer declareExtension(@Nullable String defaultCategory, Object extension) {
- this.propertyDefinitions.addComponent(extension, ofNullable(defaultCategory).orElse(""));
- return this;
- }
-
- /**
- * This method aims to be overridden
- */
- protected void doBeforeStart() {
- // nothing
- }
-
- /**
- * This method aims to be overridden
- */
- protected void doAfterStart() {
- // nothing
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
index fb0f25eaf76..4e85fc6c1cc 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
@@ -43,6 +43,7 @@ import org.sonar.core.platform.PluginClassLoader;
import org.sonar.core.platform.PluginClassloaderFactory;
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginRepository;
+import org.sonar.core.platform.SpringComponentContainer;
import org.sonar.core.util.DefaultHttpDownloader;
import org.sonar.core.util.UuidFactoryImpl;
import org.sonar.scanner.extension.ScannerCoreExtensionsInstaller;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java
deleted file mode 100644
index 3bb4cb5570a..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import org.sonar.api.Startable;
-import org.sonar.api.utils.log.Loggers;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
-import org.springframework.lang.Nullable;
-
-public class StartableBeanPostProcessor implements DestructionAwareBeanPostProcessor {
- @Override
- @Nullable
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof Startable) {
- ((Startable) bean).start();
- } else if (bean instanceof org.picocontainer.Startable) {
- ((org.picocontainer.Startable) bean).start();
- }
- return bean;
- }
-
- @Override
- public boolean requiresDestruction(Object bean) {
- return (bean instanceof Startable) || (bean instanceof org.picocontainer.Startable) || (bean instanceof AutoCloseable);
- }
-
- @Override
- public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
- try {
- if (bean instanceof Startable) {
- ((Startable) bean).stop();
- } else if (bean instanceof org.picocontainer.Startable) {
- ((org.picocontainer.Startable) bean).stop();
- } else if (bean instanceof AutoCloseable) {
- ((AutoCloseable) bean).close();
- }
- } catch (Exception e) {
- Loggers.get(StartableBeanPostProcessor.class)
- .warn("Dispose of component {} failed", bean.getClass().getCanonicalName(), e);
- }
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java
index b5629ce69ef..ac65a92484e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java
@@ -32,7 +32,7 @@ public class InputProjectProvider {
@Bean("DefaultInputProject")
public DefaultInputProject provide(ProjectBuildersExecutor projectBuildersExecutor, ProjectReactorValidator validator,
- ProjectReactor projectReactor, ScannerComponentIdGenerator scannerComponentIdGenerator) {
+ ProjectReactor projectReactor, ScannerComponentIdGenerator scannerComponentIdGenerator, WorkDirectoriesInitializer workDirectoriesInit) {
// 1 Apply project builders
projectBuildersExecutor.execute(projectReactor);
@@ -41,6 +41,7 @@ public class InputProjectProvider {
// 3 Create project
DefaultInputProject project = new DefaultInputProject(projectReactor.getRoot(), scannerComponentIdGenerator.getAsInt());
+ workDirectoriesInit.execute(project);
LOG.info("Project key: {}", project.key());
LOG.info("Base dir: {}", project.getBaseDir().toAbsolutePath().toString());
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java
deleted file mode 100644
index d1c3d972350..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/LanguagesProvider.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.scan;
-
-import java.util.List;
-import java.util.Optional;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Languages;
-import org.springframework.context.annotation.Bean;
-
-public class LanguagesProvider {
- @Bean("Languages")
- public Languages provide(Optional<List<Language>> languages) {
- if (languages.isEmpty()) {
- return new Languages();
- }
- return new Languages(languages.get().toArray(new Language[0]));
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java
index 79a09172a31..4707354a706 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringModuleScanContainer.java
@@ -23,7 +23,7 @@ import javax.annotation.Priority;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.scan.filesystem.FileExclusions;
import org.sonar.scanner.bootstrap.ExtensionInstaller;
-import org.sonar.scanner.bootstrap.SpringComponentContainer;
+import org.sonar.core.platform.SpringComponentContainer;
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.scanner.scan.filesystem.ModuleInputComponentStore;
import org.sonar.scanner.sensor.ModuleSensorContext;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java
index 8320fa8a3fc..888f5661e8c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java
@@ -33,6 +33,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.config.ScannerProperties;
import org.sonar.core.extension.CoreExtensionsInstaller;
+import org.sonar.core.language.LanguagesProvider;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.scanner.DefaultFileLinesContextFactory;
import org.sonar.scanner.ProjectInfo;
@@ -41,7 +42,7 @@ import org.sonar.scanner.bootstrap.ExtensionInstaller;
import org.sonar.scanner.bootstrap.ExtensionMatcher;
import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.PostJobExtensionDictionary;
-import org.sonar.scanner.bootstrap.SpringComponentContainer;
+import org.sonar.core.platform.SpringComponentContainer;
import org.sonar.scanner.ci.CiConfigurationProvider;
import org.sonar.scanner.ci.vendors.AppVeyor;
import org.sonar.scanner.ci.vendors.AwsCodeBuild;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java
index b118a870ff7..11552502e00 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java
@@ -24,26 +24,42 @@ import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
-import org.sonar.core.util.FileUtils;
+import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
+import org.sonar.core.util.FileUtils;
import org.sonar.scanner.fs.InputModuleHierarchy;
/**
- * Clean and create working directories of each module.
+ * Clean and create working directories of each module, except the root.
* Be careful that sub module work dir might be nested in parent working directory.
*/
public class WorkDirectoriesInitializer {
public void execute(InputModuleHierarchy moduleHierarchy) {
- cleanAllWorkingDirs(moduleHierarchy, moduleHierarchy.root());
- mkdirsAllWorkingDirs(moduleHierarchy, moduleHierarchy.root());
+ // dont apply to root. Root is done by InputProjectProvider
+ for (DefaultInputModule sub : moduleHierarchy.children(moduleHierarchy.root())) {
+ cleanAllWorkingDirs(moduleHierarchy, sub);
+ }
+ for (DefaultInputModule sub : moduleHierarchy.children(moduleHierarchy.root())) {
+ mkdirsAllWorkingDirs(moduleHierarchy, sub);
+ }
+ }
+
+ public void execute(DefaultInputProject project) {
+ cleanWorkingDir(project);
+ mkdirWorkingDir(project);
}
private static void cleanAllWorkingDirs(InputModuleHierarchy moduleHierarchy, DefaultInputModule module) {
for (DefaultInputModule sub : moduleHierarchy.children(module)) {
cleanAllWorkingDirs(moduleHierarchy, sub);
}
- if (Files.exists(module.getWorkDir())) {
- deleteAllRecursivelyExceptLockFile(module.getWorkDir());
+ cleanWorkingDir(module);
+ }
+
+ private static void cleanWorkingDir(AbstractProjectOrModule projectOrModule) {
+ if (Files.exists(projectOrModule.getWorkDir())) {
+ deleteAllRecursivelyExceptLockFile(projectOrModule.getWorkDir());
}
}
@@ -51,10 +67,14 @@ public class WorkDirectoriesInitializer {
for (DefaultInputModule sub : moduleHierarchy.children(module)) {
mkdirsAllWorkingDirs(moduleHierarchy, sub);
}
+ mkdirWorkingDir(module);
+ }
+
+ private static void mkdirWorkingDir(AbstractProjectOrModule projectOrModule) {
try {
- Files.createDirectories(module.getWorkDir());
+ Files.createDirectories(projectOrModule.getWorkDir());
} catch (Exception e) {
- throw new IllegalStateException("Fail to create working dir: " + module.getWorkDir(), e);
+ throw new IllegalStateException("Fail to create working dir: " + projectOrModule.getWorkDir(), e);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java
index d723bb2ebf3..5764ba0c854 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorExtensionDictionary.java
@@ -22,9 +22,8 @@ package org.sonar.scanner.sensor;
import java.util.Collection;
import java.util.stream.Collectors;
import org.sonar.api.batch.sensor.Sensor;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ExtensionContainer;
import org.sonar.scanner.bootstrap.AbstractExtensionDictionary;
-import org.sonar.scanner.bootstrap.SpringComponentContainer;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scan.filesystem.MutableFileSystem;
@@ -35,7 +34,7 @@ public class ModuleSensorExtensionDictionary extends AbstractExtensionDictionary
private final MutableFileSystem fileSystem;
private final BranchConfiguration branchConfiguration;
- public ModuleSensorExtensionDictionary(SpringComponentContainer componentContainer, ModuleSensorContext sensorContext, ModuleSensorOptimizer sensorOptimizer,
+ public ModuleSensorExtensionDictionary(ExtensionContainer componentContainer, ModuleSensorContext sensorContext, ModuleSensorOptimizer sensorOptimizer,
MutableFileSystem fileSystem, BranchConfiguration branchConfiguration) {
super(componentContainer);
this.sensorContext = sensorContext;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java
index 60b31745d19..b33c96fa848 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorExtensionDictionary.java
@@ -24,7 +24,7 @@ import java.util.List;
import java.util.stream.Collectors;
import org.sonar.api.scanner.sensor.ProjectSensor;
import org.sonar.scanner.bootstrap.AbstractExtensionDictionary;
-import org.sonar.scanner.bootstrap.SpringComponentContainer;
+import org.sonar.core.platform.SpringComponentContainer;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scan.filesystem.MutableFileSystem;
diff --git a/sonar-scanner-engine/src/main/resources/org/sonar/batch/bootstrapper/logback.xml b/sonar-scanner-engine/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
index b61685130a1..41ec1d712e5 100644
--- a/sonar-scanner-engine/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
+++ b/sonar-scanner-engine/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
@@ -33,7 +33,7 @@
<level value="INFO"/>
</logger>
- <logger name="org.sonar.scanner.bootstrap.PriorityBeanFactory">
+ <logger name="org.sonar.core.platform.PriorityBeanFactory">
<level value="INFO"/>
</logger>
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java
index d4c61ca7d9d..9fcebc1958c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ExtensionInstallerTest.java
@@ -20,13 +20,14 @@
package org.sonar.scanner.bootstrap;
import java.util.Arrays;
+
import org.apache.commons.lang.ClassUtils;
import org.junit.Test;
import org.sonar.api.Plugin;
import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.config.internal.MapSettings;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ListContainer;
import org.sonar.core.platform.PluginInfo;
import static org.assertj.core.api.Assertions.assertThat;
@@ -35,8 +36,8 @@ import static org.mockito.Mockito.when;
public class ExtensionInstallerTest {
- private MapSettings settings = new MapSettings();
- private ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class);
+ private final MapSettings settings = new MapSettings();
+ private final ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class);
private static Plugin newPluginInstance(final Object... extensions) {
return desc -> desc.addExtensions(Arrays.asList(extensions));
@@ -47,12 +48,13 @@ public class ExtensionInstallerTest {
when(pluginRepository.getPluginInfos()).thenReturn(Arrays.asList(new PluginInfo("foo")));
when(pluginRepository.getPluginInstance("foo")).thenReturn(newPluginInstance(Foo.class, Bar.class));
- ComponentContainer container = new ComponentContainer();
+ ListContainer container = new ListContainer();
ExtensionInstaller installer = new ExtensionInstaller(mock(SonarRuntime.class), pluginRepository, settings.asConfig());
installer.install(container, new FooMatcher());
- assertThat(container.getComponentByType(Foo.class)).isNotNull();
- assertThat(container.getComponentByType(Bar.class)).isNull();
+ assertThat(container.getAddedObjects())
+ .contains(Foo.class)
+ .doesNotContain(Bar.class);
}
private static class FooMatcher implements ExtensionMatcher {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessorTest.java
deleted file mode 100644
index 04327d52720..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/LazyBeanFactoryPostProcessorTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import org.junit.Test;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class LazyBeanFactoryPostProcessorTest {
- private final LazyBeanFactoryPostProcessor postProcessor = new LazyBeanFactoryPostProcessor();
-
- @Test
- public void sets_all_beans_lazy() {
- DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
- beanFactory.registerBeanDefinition("bean1", new RootBeanDefinition());
- assertThat(beanFactory.getBeanDefinition("bean1").isLazyInit()).isFalse();
-
- postProcessor.postProcessBeanFactory(beanFactory);
- assertThat(beanFactory.getBeanDefinition("bean1").isLazyInit()).isTrue();
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java
index b2625033efc..2246bd1914d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionaryTest.java
@@ -19,21 +19,21 @@
*/
package org.sonar.scanner.bootstrap;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
-import org.picocontainer.behaviors.FieldDecorated;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
-import org.sonar.scanner.scan.SpringModuleScanContainer;
+import org.sonar.core.platform.ExtensionContainer;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scan.filesystem.MutableFileSystem;
import org.sonar.scanner.sensor.ModuleSensorContext;
@@ -41,10 +41,6 @@ import org.sonar.scanner.sensor.ModuleSensorExtensionDictionary;
import org.sonar.scanner.sensor.ModuleSensorOptimizer;
import org.sonar.scanner.sensor.ModuleSensorWrapper;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -61,17 +57,9 @@ public class ModuleSensorExtensionDictionaryTest {
when(sensorOptimizer.shouldExecute(any(DefaultSensorDescriptor.class))).thenReturn(true);
}
- private ModuleSensorExtensionDictionary newSelector(Object... extensions) {
- DefaultInputModule inputModule = mock(DefaultInputModule.class);
- when(inputModule.definition()).thenReturn(mock(ProjectDefinition.class));
-
- SpringComponentContainer parent = new SpringComponentContainer();
- parent.context.refresh();
-
- SpringComponentContainer iocContainer = new SpringModuleScanContainer(parent, inputModule);
- iocContainer.add(Arrays.asList(extensions));
- iocContainer.context.refresh();
-
+ private ModuleSensorExtensionDictionary newSelector(Class type, Object... instances) {
+ ExtensionContainer iocContainer = mock(ExtensionContainer.class);
+ when(iocContainer.getComponentsByType(type)).thenReturn(Arrays.asList(instances));
return new ModuleSensorExtensionDictionary(iocContainer, mock(ModuleSensorContext.class), sensorOptimizer, fileSystem, branchConfiguration);
}
@@ -80,7 +68,7 @@ public class ModuleSensorExtensionDictionaryTest {
final Sensor sensor1 = new FakeSensor();
final Sensor sensor2 = new FakeSensor();
- ModuleSensorExtensionDictionary selector = newSelector(sensor1, sensor2);
+ ModuleSensorExtensionDictionary selector = newSelector(Sensor.class, sensor1, sensor2);
Collection<Sensor> sensors = selector.select(Sensor.class, true, extension -> extension.equals(sensor1));
assertThat(sensors).contains(sensor1);
assertEquals(1, sensors.size());
@@ -90,9 +78,8 @@ public class ModuleSensorExtensionDictionaryTest {
public void testGetFilteredExtensions() {
Sensor sensor1 = new FakeSensor();
Sensor sensor2 = new FakeSensor();
- FieldDecorated.Decorator decorator = mock(FieldDecorated.Decorator.class);
- ModuleSensorExtensionDictionary selector = newSelector(sensor1, sensor2, decorator);
+ ModuleSensorExtensionDictionary selector = newSelector(Sensor.class, sensor1, sensor2);
Collection<Sensor> sensors = selector.select(Sensor.class, false, null);
assertThat(sensors).containsOnly(sensor1, sensor2);
@@ -104,17 +91,16 @@ public class ModuleSensorExtensionDictionaryTest {
Sensor b = new FakeSensor();
Sensor c = new FakeSensor();
- SpringComponentContainer grandParent = new SpringComponentContainer();
- grandParent.add(a);
- grandParent.context.refresh();
+ ExtensionContainer grandParent = mock(ExtensionContainer.class);
+ when(grandParent.getComponentsByType(Sensor.class)).thenReturn(List.of(a));
- SpringComponentContainer parent = grandParent.createChild();
- parent.add(b);
- parent.context.refresh();
+ ExtensionContainer parent = mock(ExtensionContainer.class);
+ when(parent.getComponentsByType(Sensor.class)).thenReturn(List.of(b));
+ when(parent.getParent()).thenReturn(grandParent);
- SpringComponentContainer child = parent.createChild();
- child.add(c);
- child.context.refresh();
+ ExtensionContainer child = mock(ExtensionContainer.class);
+ when(child.getComponentsByType(Sensor.class)).thenReturn(List.of(c));
+ when(child.getParent()).thenReturn(parent);
ModuleSensorExtensionDictionary dictionnary = new ModuleSensorExtensionDictionary(child, mock(ModuleSensorContext.class), mock(ModuleSensorOptimizer.class),
fileSystem, branchConfiguration);
@@ -127,8 +113,8 @@ public class ModuleSensorExtensionDictionaryTest {
Object b = new MethodDependentOf(a);
Object c = new MethodDependentOf(b);
- ModuleSensorExtensionDictionary selector = newSelector(b, c, a);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, b, c, a);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(3);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -141,16 +127,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object a = new GeneratesSomething("foo");
Object b = new MethodDependentOf("foo");
- ModuleSensorExtensionDictionary selector = newSelector(a, b);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, a, b);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions.size()).isEqualTo(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, b, a);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -162,16 +148,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object a = new GeneratesSomething("foo");
Object b = new MethodDependentOf(Arrays.asList("foo"));
- ModuleSensorExtensionDictionary selector = newSelector(a, b);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, a, b);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, b, a);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -183,16 +169,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object a = new GeneratesSomething("foo");
Object b = new MethodDependentOf(new String[] {"foo"});
- ModuleSensorExtensionDictionary selector = newSelector(a, b);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, a, b);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, b, a);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -204,16 +190,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object a = new ClassDependedUpon();
Object b = new ClassDependsUpon();
- ModuleSensorExtensionDictionary selector = newSelector(a, b);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, a, b);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, b, a);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -227,16 +213,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object b = new InterfaceDependsUpon() {
};
- ModuleSensorExtensionDictionary selector = newSelector(a, b);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, a, b);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, b, a);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -248,16 +234,16 @@ public class ModuleSensorExtensionDictionaryTest {
Object a = new SubClass("foo");
Object b = new MethodDependentOf("foo");
- ModuleSensorExtensionDictionary selector = newSelector(b, a);
- List<Object> extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Marker.class, b, a);
+ List<Object> extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
assertThat(extensions.get(1)).isEqualTo(b);
// change initial order
- selector = newSelector(a, b);
- extensions = Lists.newArrayList(selector.select(Marker.class, true, null));
+ selector = newSelector(Marker.class, a, b);
+ extensions = new ArrayList<>(selector.select(Marker.class, true, null));
assertThat(extensions).hasSize(2);
assertThat(extensions.get(0)).isEqualTo(a);
@@ -266,7 +252,8 @@ public class ModuleSensorExtensionDictionaryTest {
@Test(expected = IllegalStateException.class)
public void annotatedMethodsCanNotBePrivate() {
- ModuleSensorExtensionDictionary selector = newSelector();
+ ModuleSensorExtensionDictionary selector = new ModuleSensorExtensionDictionary(mock(ExtensionContainer.class), mock(ModuleSensorContext.class),
+ sensorOptimizer, fileSystem, branchConfiguration);
Object wrong = new Object() {
@DependsUpon
private Object foo() {
@@ -282,7 +269,7 @@ public class ModuleSensorExtensionDictionaryTest {
NormalSensor normal = new NormalSensor();
PostSensor post = new PostSensor();
- ModuleSensorExtensionDictionary selector = newSelector(normal, post, pre);
+ ModuleSensorExtensionDictionary selector = newSelector(Sensor.class, normal, post, pre);
assertThat(selector.selectSensors(false)).extracting("wrappedSensor").containsExactly(pre, normal, post);
}
@@ -292,8 +279,8 @@ public class ModuleSensorExtensionDictionaryTest {
NormalSensor normal = new NormalSensor();
PostSensorSubclass post = new PostSensorSubclass();
- ModuleSensorExtensionDictionary selector = newSelector(normal, post, pre);
- List extensions = Lists.newArrayList(selector.select(Sensor.class, true, null));
+ ModuleSensorExtensionDictionary selector = newSelector(Sensor.class, normal, post, pre);
+ List extensions = new ArrayList<>(selector.select(Sensor.class, true, null));
assertThat(extensions).containsExactly(pre, normal, post);
}
@@ -302,7 +289,7 @@ public class ModuleSensorExtensionDictionaryTest {
public void selectSensors() {
FakeSensor nonGlobalSensor = new FakeSensor();
FakeGlobalSensor globalSensor = new FakeGlobalSensor();
- ModuleSensorExtensionDictionary selector = newSelector(nonGlobalSensor, globalSensor);
+ ModuleSensorExtensionDictionary selector = newSelector(Sensor.class, nonGlobalSensor, globalSensor);
// verify non-global sensor
Collection<ModuleSensorWrapper> extensions = selector.selectSensors(false);
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java
index e359a0f1be6..dbfd4bd9f5c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionaryTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.scanner.bootstrap;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.Phase;
@@ -26,10 +27,7 @@ import org.sonar.api.batch.postjob.PostJob;
import org.sonar.api.batch.postjob.PostJobContext;
import org.sonar.api.batch.postjob.PostJobDescriptor;
import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor;
-import org.sonar.api.batch.sensor.Sensor;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ExtensionContainer;
import org.sonar.scanner.postjob.PostJobOptimizer;
import static org.assertj.core.api.Assertions.assertThat;
@@ -38,49 +36,23 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PostJobExtensionDictionaryTest {
- private PostJobOptimizer postJobOptimizer = mock(PostJobOptimizer.class);
+ private final PostJobOptimizer postJobOptimizer = mock(PostJobOptimizer.class);
@Before
public void setUp() {
when(postJobOptimizer.shouldExecute(any(DefaultPostJobDescriptor.class))).thenReturn(true);
}
- private PostJobExtensionDictionary newSelector(Object... extensions) {
- ComponentContainer iocContainer = new ComponentContainer();
- for (Object extension : extensions) {
- iocContainer.addSingleton(extension);
- }
- return new PostJobExtensionDictionary(iocContainer, postJobOptimizer, mock(PostJobContext.class));
- }
-
@Test
public void dependsUponPhaseForPostJob() {
PrePostJob pre = new PrePostJob();
NormalPostJob normal = new NormalPostJob();
- PostJobExtensionDictionary selector = newSelector(normal, pre);
- assertThat(selector.selectPostJobs()).extracting("wrappedPostJob").containsExactly(pre, normal);
- }
-
- interface Marker {
-
- }
-
- @Phase(name = Phase.Name.POST) static
- class PostSensor implements Sensor {
-
- @Override
- public void describe(SensorDescriptor descriptor) {
- }
-
- @Override
- public void execute(SensorContext context) {
- }
-
- }
-
- class PostSensorSubclass extends PostSensor {
+ ExtensionContainer iocContainer = mock(ExtensionContainer.class);
+ when(iocContainer.getComponentsByType(PostJob.class)).thenReturn(List.of(pre, normal));
+ PostJobExtensionDictionary selector = new PostJobExtensionDictionary(iocContainer, postJobOptimizer, mock(PostJobContext.class));
+ assertThat(selector.selectPostJobs()).extracting("wrappedPostJob").containsExactly(pre, normal);
}
static class NormalPostJob implements PostJob {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PriorityBeanFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PriorityBeanFactoryTest.java
deleted file mode 100644
index b20e87e9a26..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PriorityBeanFactoryTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import javax.annotation.Priority;
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
-import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.core.annotation.AnnotationAwareOrderComparator;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-public class PriorityBeanFactoryTest {
- private final DefaultListableBeanFactory parentBeanFactory = new PriorityBeanFactory();
- private final DefaultListableBeanFactory beanFactory = new PriorityBeanFactory();
-
- @Before
- public void setUp() {
- // needed to support autowiring with @Inject
- beanFactory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
- //needed to read @Priority
- beanFactory.setDependencyComparator(new AnnotationAwareOrderComparator());
- beanFactory.setParentBeanFactory(parentBeanFactory);
- }
-
- @Test
- public void give_priority_to_child_container() {
- parentBeanFactory.registerBeanDefinition("A1", new RootBeanDefinition(A1.class));
-
- beanFactory.registerBeanDefinition("A2", new RootBeanDefinition(A2.class));
- beanFactory.registerBeanDefinition("B", new RootBeanDefinition(B.class));
-
- assertThat(beanFactory.getBean(B.class).dep.getClass()).isEqualTo(A2.class);
- }
-
- @Test
- public void follow_priority_annotations() {
- parentBeanFactory.registerBeanDefinition("A3", new RootBeanDefinition(A3.class));
-
- beanFactory.registerBeanDefinition("A1", new RootBeanDefinition(A1.class));
- beanFactory.registerBeanDefinition("A2", new RootBeanDefinition(A2.class));
- beanFactory.registerBeanDefinition("B", new RootBeanDefinition(B.class));
-
- assertThat(beanFactory.getBean(B.class).dep.getClass()).isEqualTo(A3.class);
- }
-
- @Test
- public void throw_NoUniqueBeanDefinitionException_if_cant_find_single_bean_with_higher_priority() {
- beanFactory.registerBeanDefinition("A1", new RootBeanDefinition(A1.class));
- beanFactory.registerBeanDefinition("A2", new RootBeanDefinition(A2.class));
- beanFactory.registerBeanDefinition("B", new RootBeanDefinition(B.class));
-
- assertThatThrownBy(() -> beanFactory.getBean(B.class))
- .hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class);
- }
-
- private static class B {
- private final A dep;
-
- public B(A dep) {
- this.dep = dep;
- }
- }
-
- private interface A {
-
- }
-
- private static class A1 implements A {
-
- }
-
- private static class A2 implements A {
-
- }
-
- @Priority(1)
- private static class A3 implements A {
-
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java
deleted file mode 100644
index 7c1008b4938..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import org.junit.Test;
-import org.sonar.api.Startable;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertThrows;
-
-public class SpringComponentContainerTest {
-
- @Test
- public void should_stop_after_failing() {
- ApiStartable startStop = new ApiStartable();
- SpringComponentContainer container = new SpringComponentContainer() {
- @Override
- public void doBeforeStart() {
- add(startStop);
- }
-
- @Override
- public void doAfterStart() {
- getComponentByType(ApiStartable.class);
- throw new IllegalStateException("doBeforeStart");
- }
- };
-
- assertThrows("doBeforeStart", IllegalStateException.class, container::execute);
- assertThat(startStop.start).isTrue();
- assertThat(startStop.stop).isTrue();
- }
-
- @Test
- public void register_instance_with_toString() {
- SpringComponentContainer container = new SimpleContainer(new ToString("a"), new ToString("b"));
- container.startComponents();
- assertThat(container.context.getBeanDefinitionNames())
- .contains(
- this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-a",
- this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-b");
- assertThat(container.getComponentsByType(ToString.class)).hasSize(2);
- }
-
- @Test
- public void register_class_with_classloader_and_fqcn() {
- SpringComponentContainer container = new SimpleContainer(A.class, B.class);
- container.startComponents();
- assertThat(container.context.getBeanDefinitionNames())
- .contains(
- this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.A",
- this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.B");
- assertThat(container.getComponentByType(A.class)).isNotNull();
- assertThat(container.getComponentByType(B.class)).isNotNull();
- }
-
- @Test
- public void should_throw_start_exception_if_stop_also_throws_exception() {
- ErrorStopClass errorStopClass = new ErrorStopClass();
- SpringComponentContainer container = new SpringComponentContainer() {
- @Override
- public void doBeforeStart() {
- add(errorStopClass);
- }
-
- @Override
- public void doAfterStart() {
- getComponentByType(ErrorStopClass.class);
- throw new IllegalStateException("doBeforeStart");
- }
- };
- assertThrows("doBeforeStart", IllegalStateException.class, container::execute);
- assertThat(errorStopClass.stopped).isTrue();
- }
-
- @Test
- public void should_support_extensions_without_annotations() {
- SpringComponentContainer container = new SimpleContainer(A.class, B.class);
- container.addExtension("", ExtensionWithMultipleConstructorsAndNoAnnotations.class);
- container.startComponents();
- assertThat(container.getComponentByType(ExtensionWithMultipleConstructorsAndNoAnnotations.class).gotBothArgs).isTrue();
- }
-
- @Test
- public void support_start_stop_callbacks() {
- JsrLifecycleCallbacks jsr = new JsrLifecycleCallbacks();
- ApiStartable api = new ApiStartable();
- PicoStartable pico = new PicoStartable();
-
- SpringComponentContainer container = new SimpleContainer(jsr, api, pico) {
- @Override
- public void doAfterStart() {
- // force lazy instantiation
- getComponentByType(JsrLifecycleCallbacks.class);
- getComponentByType(ApiStartable.class);
- getComponentByType(PicoStartable.class);
- }
- };
- container.execute();
-
- assertThat(jsr.postConstruct).isTrue();
- assertThat(jsr.preDestroy).isTrue();
- assertThat(api.start).isTrue();
- assertThat(api.stop).isTrue();
- assertThat(pico.start).isTrue();
- assertThat(pico.stop).isTrue();
- }
-
- private static class JsrLifecycleCallbacks {
- private boolean postConstruct = false;
- private boolean preDestroy = false;
-
- @PostConstruct
- public void postConstruct() {
- postConstruct = true;
- }
-
- @PreDestroy
- public void preDestroy() {
- preDestroy = true;
- }
- }
-
- private static class ApiStartable implements Startable {
- private boolean start = false;
- private boolean stop = false;
-
- public void start() {
- start = true;
- }
-
- public void stop() {
- stop = true;
- }
- }
-
- private static class PicoStartable implements org.picocontainer.Startable {
- private boolean start = false;
- private boolean stop = false;
-
- public void start() {
- start = true;
- }
-
- public void stop() {
- stop = true;
- }
- }
-
- private static class ToString {
- private final String toString;
-
- public ToString(String toString) {
- this.toString = toString;
- }
-
- @Override
- public String toString() {
- return toString;
- }
- }
-
- private static class A {
- }
-
- private static class B {
- }
-
- private static class ExtensionWithMultipleConstructorsAndNoAnnotations {
- private boolean gotBothArgs = false;
- public ExtensionWithMultipleConstructorsAndNoAnnotations(A a) {
- }
-
- public ExtensionWithMultipleConstructorsAndNoAnnotations(A a, B b) {
- gotBothArgs = true;
- }
- }
-
- private static class ErrorStopClass implements Startable {
- private boolean stopped = false;
-
- @Override
- public void start() {
- }
-
- @Override
- public void stop() {
- stopped = true;
- throw new IllegalStateException("stop");
- }
- }
-
- private static class SimpleContainer extends SpringComponentContainer {
- public SimpleContainer(Object... objects) {
- add(objects);
- }
- }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessorTest.java
deleted file mode 100644
index ecdb6164cac..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/StartableBeanPostProcessorTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.bootstrap;
-
-import org.junit.Test;
-import org.picocontainer.Startable;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class StartableBeanPostProcessorTest {
- private final StartableBeanPostProcessor underTest = new StartableBeanPostProcessor();
-
- @Test
- public void starts_pico_startable() {
- Startable startable = mock(Startable.class);
- underTest.postProcessBeforeInitialization(startable, "startable");
- verify(startable).start();
- verifyNoMoreInteractions(startable);
- }
-
- @Test
- public void starts_api_startable() {
- org.sonar.api.Startable startable = mock(org.sonar.api.Startable.class);
- underTest.postProcessBeforeInitialization(startable, "startable");
- verify(startable).start();
- verifyNoMoreInteractions(startable);
- }
-
- @Test
- public void stops_pico_startable() {
- Startable startable = mock(Startable.class);
- underTest.postProcessBeforeDestruction(startable, "startable");
- verify(startable).stop();
- verifyNoMoreInteractions(startable);
- }
-
- @Test
- public void stops_api_startable() {
- org.sonar.api.Startable startable = mock(org.sonar.api.Startable.class);
- underTest.postProcessBeforeDestruction(startable, "startable");
- verify(startable).stop();
- verifyNoMoreInteractions(startable);
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java
index febb3323f5d..458d42dd691 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/extension/ScannerCoreExtensionsInstallerTest.java
@@ -25,6 +25,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.stream.Stream;
+
import org.junit.Test;
import org.sonar.api.SonarRuntime;
import org.sonar.api.scanner.ScannerSide;
@@ -32,7 +33,7 @@ import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.core.extension.CoreExtension;
import org.sonar.core.extension.CoreExtensionRepository;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ListContainer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -41,10 +42,9 @@ import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideF
import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
public class ScannerCoreExtensionsInstallerTest {
- private SonarRuntime sonarRuntime = mock(SonarRuntime.class);
- private CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class);
-
- private ScannerCoreExtensionsInstaller underTest = new ScannerCoreExtensionsInstaller(sonarRuntime, coreExtensionRepository);
+ private final SonarRuntime sonarRuntime = mock(SonarRuntime.class);
+ private final CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class);
+ private final ScannerCoreExtensionsInstaller underTest = new ScannerCoreExtensionsInstaller(sonarRuntime, coreExtensionRepository);
@Test
public void install_only_adds_ScannerSide_annotated_extension_to_container() {
@@ -61,14 +61,13 @@ public class ScannerCoreExtensionsInstallerTest {
NoAnnotationClass.class, OtherAnnotationClass.class, MultipleAnnotationClass.class);
}
}));
- ComponentContainer container = new ComponentContainer();
+ ListContainer container = new ListContainer();
underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
- assertThat(container.getPicoContainer().getComponentAdapters())
- .hasSize(ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 2);
- assertThat(container.getComponentByType(ScannerClass.class)).isNotNull();
- assertThat(container.getComponentByType(MultipleAnnotationClass.class)).isNotNull();
+ assertThat(container.getAddedObjects())
+ .hasSize(2)
+ .contains(ScannerClass.class, MultipleAnnotationClass.class);
}
@ComputeEngineSide
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumTest.java
index 3f969ca4963..e0c3137f270 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/NoLanguagesPluginsMediumTest.java
@@ -26,7 +26,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
-import org.springframework.beans.factory.UnsatisfiedDependencyException;
+import org.springframework.beans.factory.BeanCreationException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -44,7 +44,7 @@ public class NoLanguagesPluginsMediumTest {
assertThatThrownBy(() -> tester
.newAnalysis(new File(projectDir, "sonar-project.properties"))
.execute())
- .isInstanceOf(UnsatisfiedDependencyException.class)
+ .isInstanceOf(BeanCreationException.class)
.hasRootCauseMessage("No language plugins are installed.");
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java
index ec873cf72ae..180466e355c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java
@@ -27,6 +27,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
import org.sonar.scanner.fs.InputModuleHierarchy;
import static org.assertj.core.api.Assertions.assertThat;
@@ -34,46 +35,47 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class WorkDirectoriesInitializerTest {
- private WorkDirectoriesInitializer initializer;
+ private final WorkDirectoriesInitializer initializer = new WorkDirectoriesInitializer();
+ private final InputModuleHierarchy hierarchy = mock(InputModuleHierarchy.class);
+ private final DefaultInputProject project = mock(DefaultInputProject.class);
+ private final DefaultInputModule root = mock(DefaultInputModule.class);
+
@Rule
public TemporaryFolder temp = new TemporaryFolder();
private File rootWorkDir;
private File lock;
- private InputModuleHierarchy hierarchy;
- private DefaultInputModule root;
@Before
public void setUp() throws IOException {
rootWorkDir = temp.newFolder();
- // create files to clean
- new File(rootWorkDir, "foo.txt").createNewFile();
- File newFolder = new File(rootWorkDir, "foo");
+ when(hierarchy.root()).thenReturn(root);
+ createFilesToClean(rootWorkDir);
+ when(root.getWorkDir()).thenReturn(rootWorkDir.toPath());
+ when(project.getWorkDir()).thenReturn(rootWorkDir.toPath());
+ }
+
+ private void createFilesToClean(File dir) throws IOException {
+ new File(dir, "foo.txt").createNewFile();
+ File newFolder = new File(dir, "foo");
newFolder.mkdir();
File fileInFolder = new File(newFolder, "test");
fileInFolder.createNewFile();
- lock = new File(rootWorkDir, DirectoryLock.LOCK_FILE_NAME);
+ lock = new File(dir, DirectoryLock.LOCK_FILE_NAME);
lock.createNewFile();
-
- hierarchy = mock(InputModuleHierarchy.class);
- root = mock(DefaultInputModule.class);
- when(hierarchy.root()).thenReturn(root);
- when(root.getWorkDir()).thenReturn(rootWorkDir.toPath());
-
- assertThat(rootWorkDir.list().length).isGreaterThan(1);
- initializer = new WorkDirectoriesInitializer();
+ assertThat(dir.list()).hasSizeGreaterThan(1);
}
@Test
- public void testNonExisting() {
+ public void execute_doesnt_fail_if_nothing_to_clean() {
temp.delete();
initializer.execute(hierarchy);
}
@Test
- public void testClean() {
- initializer.execute(hierarchy);
+ public void execute_should_clean_root() {
+ initializer.execute(project);
assertThat(rootWorkDir).exists();
assertThat(lock).exists();
@@ -81,20 +83,35 @@ public class WorkDirectoriesInitializerTest {
}
@Test
- public void cleaningRootModuleShouldNotDeleteChildrenWorkDir() throws IOException {
+ public void execute_on_hierarchy_should_clean_submodules() throws IOException {
DefaultInputModule moduleA = mock(DefaultInputModule.class);
+ DefaultInputModule moduleB = mock(DefaultInputModule.class);
+
when(hierarchy.children(root)).thenReturn(Arrays.asList(moduleA));
+ when(hierarchy.children(moduleA)).thenReturn(Arrays.asList(moduleB));
+
File moduleAWorkdir = new File(rootWorkDir, "moduleA");
+ File moduleBWorkdir = new File(moduleAWorkdir, "moduleB");
+
when(moduleA.getWorkDir()).thenReturn(moduleAWorkdir.toPath());
+ when(moduleB.getWorkDir()).thenReturn(moduleBWorkdir.toPath());
+
moduleAWorkdir.mkdir();
+ moduleBWorkdir.mkdir();
+
new File(moduleAWorkdir, "fooA.txt").createNewFile();
+ new File(moduleBWorkdir, "fooB.txt").createNewFile();
+ initializer.execute(project);
initializer.execute(hierarchy);
assertThat(rootWorkDir).exists();
assertThat(lock).exists();
assertThat(rootWorkDir.list()).containsOnly(DirectoryLock.LOCK_FILE_NAME, "moduleA");
assertThat(moduleAWorkdir).exists();
+ assertThat(moduleBWorkdir).exists();
+ assertThat(moduleAWorkdir.list()).containsOnly("moduleB");
+ assertThat(moduleBWorkdir).isEmptyDirectory();
}
}