compileOnly 'com.google.code.findbugs:jsr305'
compileOnly project(':sonar-core')
+ compileOnly project(':server:sonar-ce-task')
compileOnly project(':server:sonar-db-dao')
compileOnly project(':server:sonar-process')
compileOnly project(':server:sonar-server-common')
testCompile 'org.mockito:mockito-core'
testCompile 'org.reflections:reflections'
testCompile project(':server:sonar-db-testing')
+ testCompile project(path: ":server:sonar-ce-task", configuration: "tests")
testCompile project(path: ":server:sonar-server", configuration: "tests")
}
--- /dev/null
+description = 'Definition of a Compute Engine task and utility "framework" and classes to code one'
+
+sonarqube {
+ properties {
+ property 'sonar.projectName', "${projectTitle} :: Compute Engine :: Task"
+ }
+}
+
+sourceSets {
+ test {
+ resources {
+ srcDirs += ['src/test/projects']
+ }
+ }
+}
+
+
+import org.apache.tools.ant.filters.ReplaceTokens
+processResources {
+ filesMatching('build.properties') {
+ filter ReplaceTokens, tokens: [
+ 'buildNumber': release ? 'git rev-parse HEAD'.execute().text.trim() : 'N/A'
+ ]
+ }
+}
+
+dependencies {
+ // please keep the list grouped by configuration and ordered by name
+
+ compile 'org.picocontainer:picocontainer'
+ compile 'org.slf4j:jul-to-slf4j'
+ compile 'org.slf4j:slf4j-api'
+
+ compile project(':server:sonar-process')
+ compile project(':sonar-core')
+ compileOnly project(path: ':sonar-plugin-api')
+
+ compileOnly 'com.google.code.findbugs:jsr305'
+
+ testCompile 'ch.qos.logback:logback-access'
+ testCompile 'ch.qos.logback:logback-classic'
+ testCompile 'ch.qos.logback:logback-core'
+ testCompile 'com.google.code.findbugs:jsr305'
+ testCompile 'com.h2database:h2'
+ testCompile 'com.tngtech.java:junit-dataprovider'
+ testCompile 'junit:junit'
+ testCompile 'org.apache.logging.log4j:log4j-api'
+ testCompile 'org.apache.logging.log4j:log4j-core'
+ testCompile 'org.assertj:assertj-core'
+ testCompile 'org.assertj:assertj-guava'
+ testCompile 'org.mockito:mockito-core'
+ testCompile 'org.reflections:reflections'
+}
+
+task testJar(type: Jar) {
+ classifier = 'tests'
+ from sourceSets.test.output
+}
+
+configurations {
+ tests
+}
+
+artifacts {
+ tests testJar
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation;
+
+import com.google.common.base.MoreObjects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Strings.emptyToNull;
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class CeTask {
+
+ private final String organizationUuid;
+ private final String type;
+ private final String uuid;
+ private final String componentUuid;
+ private final String componentKey;
+ private final String componentName;
+ private final String submitterUuid;
+
+ private CeTask(Builder builder) {
+ this.organizationUuid = requireNonNull(emptyToNull(builder.organizationUuid), "organizationUuid can't be null nor empty");
+ this.uuid = requireNonNull(emptyToNull(builder.uuid), "uuid can't be null nor empty");
+ this.type = requireNonNull(emptyToNull(builder.type), "type can't be null nor empty");
+ this.componentUuid = emptyToNull(builder.componentUuid);
+ this.componentKey = emptyToNull(builder.componentKey);
+ this.componentName = emptyToNull(builder.componentName);
+ this.submitterUuid = emptyToNull(builder.submitterUuid);
+ }
+
+ public String getOrganizationUuid() {
+ return organizationUuid;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ @CheckForNull
+ public String getComponentUuid() {
+ return componentUuid;
+ }
+
+ @CheckForNull
+ public String getComponentKey() {
+ return componentKey;
+ }
+
+ @CheckForNull
+ public String getComponentName() {
+ return componentName;
+ }
+
+ @CheckForNull
+ public String getSubmitterUuid() {
+ return submitterUuid;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("organizationUuid", organizationUuid)
+ .add("type", type)
+ .add("uuid", uuid)
+ .add("componentUuid", componentUuid)
+ .add("componentKey", componentKey)
+ .add("componentName", componentName)
+ .add("submitterUuid", submitterUuid)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CeTask ceTask = (CeTask) o;
+ return uuid.equals(ceTask.uuid);
+ }
+
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ public static final class Builder {
+ private String organizationUuid;
+ private String uuid;
+ private String type;
+ private String componentUuid;
+ private String componentKey;
+ private String componentName;
+ private String submitterUuid;
+
+ public Builder setOrganizationUuid(String organizationUuid) {
+ this.organizationUuid = organizationUuid;
+ return this;
+ }
+
+ // FIXME remove this method when organization support is added to the Compute Engine queue
+ public boolean hasOrganizationUuid() {
+ return organizationUuid != null;
+ }
+
+ public Builder setUuid(String uuid) {
+ this.uuid = uuid;
+ return this;
+ }
+
+ public Builder setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder setComponentUuid(String componentUuid) {
+ this.componentUuid = componentUuid;
+ return this;
+ }
+
+ public Builder setComponentKey(@Nullable String s) {
+ this.componentKey = s;
+ return this;
+ }
+
+ public Builder setComponentName(@Nullable String s) {
+ this.componentName = s;
+ return this;
+ }
+
+ public Builder setSubmitterUuid(@Nullable String s) {
+ this.submitterUuid = s;
+ return this;
+ }
+
+ public CeTask build() {
+ return new CeTask(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation;
+
+import java.util.Optional;
+
+/**
+ * Represents the result of the processing of a {@link CeTask}.
+ */
+@FunctionalInterface
+public interface CeTaskResult {
+ /**
+ * The UUID of the analysis created, if any, for the Component in {@link CeTask}
+ */
+ Optional<String> getAnalysisUuid();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.log;
+
+import org.slf4j.MDC;
+import org.sonar.server.computation.CeTask;
+
+public class CeTaskLogging {
+
+ public static final String MDC_CE_TASK_UUID = "ceTaskUuid";
+
+ public void initForTask(CeTask task) {
+ MDC.put(MDC_CE_TASK_UUID, task.getUuid());
+ }
+
+ public void clearForTask() {
+ MDC.remove(MDC_CE_TASK_UUID);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.log;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.container;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Components with this annotation will be eagerly started when loaded into the {@link TaskContainerImpl}.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EagerStart {
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.container;
+
+import org.picocontainer.PicoContainer;
+import org.sonar.server.computation.CeTask;
+import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ContainerPopulator;
+
+/**
+ * The Compute Engine task container. Created for a specific parent {@link ComponentContainer} and a specific {@link CeTask}.
+ */
+public interface TaskContainer extends ContainerPopulator.Container, AutoCloseable {
+
+ ComponentContainer getParent();
+
+ /**
+ * Starts task container, starting any startable component in it.
+ */
+ void bootup();
+
+ /**
+ * Cleans up resources after process has been called and has returned.
+ */
+ @Override
+ void close();
+
+ /**
+ * Access to the underlying pico container.
+ */
+ PicoContainer getPicoContainer();
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.container;
+
+import java.util.List;
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.DefaultPicoContainer;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.behaviors.OptInCaching;
+import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
+import org.picocontainer.monitors.NullComponentMonitor;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ContainerPopulator;
+import org.sonar.core.platform.Module;
+import org.sonar.core.platform.StopSafeReflectionLifecycleStrategy;
+
+import static java.util.Objects.requireNonNull;
+
+public class TaskContainerImpl extends ComponentContainer implements TaskContainer {
+
+ public TaskContainerImpl(ComponentContainer parent, ContainerPopulator<TaskContainer> populator) {
+ super(createContainer(requireNonNull(parent)), parent.getComponentByType(PropertyDefinitions.class));
+
+ populateContainer(requireNonNull(populator));
+ }
+
+ private void populateContainer(ContainerPopulator<TaskContainer> populator) {
+ populator.populateContainer(this);
+ populateFromModules();
+ }
+
+ private void populateFromModules() {
+ List<Module> modules = getComponentsByType(Module.class);
+ for (Module module : modules) {
+ module.configure(this);
+ }
+ }
+
+ /**
+ * Creates a PicContainer which extends the specified ComponentContainer <strong>but is not referenced in return</strong>
+ * and lazily starts its components.
+ */
+ private static MutablePicoContainer createContainer(ComponentContainer parent) {
+ ComponentMonitor componentMonitor = new NullComponentMonitor();
+ ReflectionLifecycleStrategy lifecycleStrategy = new StopSafeReflectionLifecycleStrategy(componentMonitor) {
+ @Override
+ public boolean isLazy(ComponentAdapter<?> adapter) {
+ return adapter.getComponentImplementation().getAnnotation(EagerStart.class) == null;
+ }
+ };
+
+ return new DefaultPicoContainer(new OptInCaching(), lifecycleStrategy, parent.getPicoContainer(), componentMonitor);
+ }
+
+ @Override
+ public void bootup() {
+ startComponents();
+ }
+
+ @Override
+ public String toString() {
+ return "TaskContainerImpl";
+ }
+
+ @Override
+ public void close() {
+ try {
+ stopComponents();
+ } catch (Throwable t) {
+ Loggers.get(TaskContainerImpl.class).error("Cleanup of container failed", t);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.task.container;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+/**
+ * A way of splitting the processing of a task into smaller items which can be executed sequencially
+ * by {@link ComputationStepExecutor}.
+ */
+public interface ComputationStep {
+
+ void execute();
+
+ String getDescription();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.util.logs.Profiler;
+
+public final class ComputationStepExecutor {
+ private static final Logger LOGGER = Loggers.get(ComputationStepExecutor.class);
+
+ private final ComputationSteps steps;
+ @CheckForNull
+ private final Listener listener;
+
+ /**
+ * Used when no {@link ComputationStepExecutor.Listener} is available in pico
+ * container.
+ */
+ public ComputationStepExecutor(ComputationSteps steps) {
+ this(steps, null);
+ }
+
+ public ComputationStepExecutor(ComputationSteps steps, @Nullable Listener listener) {
+ this.steps = steps;
+ this.listener = listener;
+ }
+
+ public void execute() {
+ Profiler stepProfiler = Profiler.create(LOGGER);
+ boolean allStepsExecuted = false;
+ try {
+ executeSteps(stepProfiler);
+ allStepsExecuted = true;
+ } finally {
+ if (listener != null) {
+ executeListener(allStepsExecuted);
+ }
+ }
+ }
+
+ private void executeSteps(Profiler stepProfiler) {
+ for (ComputationStep step : steps.instances()) {
+ stepProfiler.start();
+ step.execute();
+ stepProfiler.stopDebug(step.getDescription());
+ }
+ }
+
+ private void executeListener(boolean allStepsExecuted) {
+ try {
+ listener.finished(allStepsExecuted);
+ } catch (Throwable e) {
+ // any Throwable throws by the listener going up the stack might hide an Exception/Error thrown by the step and
+ // cause it be swallowed. We don't wan't that => we catch Throwable
+ LOGGER.error("Execution of listener failed", e);
+ }
+ }
+
+ @FunctionalInterface
+ public interface Listener {
+ void finished(boolean allStepsExecuted);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import java.util.List;
+
+/**
+ * Ordered list of steps classes and instances to be executed in a Compute Engine process.
+ */
+public interface ComputationSteps {
+ /**
+ * List of all {@link ComputationStep},
+ * ordered by execution sequence.
+ */
+ List<Class<? extends ComputationStep>> orderedStepClasses();
+
+ /**
+ * List of all {@link ComputationStep},
+ * ordered by execution sequence.
+ */
+ Iterable<ComputationStep> instances();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import org.sonar.api.ce.ComputeEngineSide;
+
+/**
+ * Execute {@link StatelessInitExtension} instances in no specific order.
+ * If an extension fails (throws an exception), consecutive extensions
+ * won't be called.
+ */
+@ComputeEngineSide
+public class ExecuteStatelessInitExtensionsStep implements ComputationStep {
+
+ private final StatelessInitExtension[] extensions;
+
+ public ExecuteStatelessInitExtensionsStep(StatelessInitExtension[] extensions) {
+ this.extensions = extensions;
+ }
+
+ /**
+ * Used when zero {@link StatelessInitExtension} are registered into container.
+ */
+ public ExecuteStatelessInitExtensionsStep() {
+ this(new StatelessInitExtension[0]);
+ }
+
+ @Override
+ public void execute() {
+ for (StatelessInitExtension extension : extensions) {
+ extension.onInit();
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Initialize";
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import org.sonar.api.ExtensionPoint;
+import org.sonar.api.ce.ComputeEngineSide;
+
+/**
+ * Extension point that is called during processing of a task
+ * by {@link ExecuteStatelessInitExtensionsStep}.
+ * It is stateless, the same instance is reused for all tasks.
+ * As a consequence Compute Engine task components can't be injected
+ * as dependencies.
+ */
+@ComputeEngineSide
+@ExtensionPoint
+public interface StatelessInitExtension {
+
+ /**
+ * This method can make the task fail by throwing a {@link RuntimeException}
+ */
+ void onInit();
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+/**
+ * This interface is implemented by the exceptions
+ * that provide a type of error when failing
+ * a Compute Engine task.
+ * The error type is persisted and available in
+ * the tasks returned by the web services api/ce.
+ */
+public interface TypedException {
+
+ String getType();
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.task.step;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
+
+import org.sonar.server.computation.CeTaskResult;
+
+public interface MutableTaskResultHolder extends TaskResultHolder {
+ /**
+ * @throws NullPointerException if {@code taskResult} is {@code null}
+ * @throws IllegalStateException if a {@link CeTaskResult} has already been set in the holder
+ */
+ void setResult(CeTaskResult taskResult);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
+
+import javax.annotation.CheckForNull;
+import org.sonar.server.computation.CeTaskResult;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+public class MutableTaskResultHolderImpl implements MutableTaskResultHolder {
+ @CheckForNull
+ private CeTaskResult result;
+
+ @Override
+ public CeTaskResult getResult() {
+ checkState(this.result != null, "No CeTaskResult has been set in the holder");
+ return this.result;
+ }
+
+ @Override
+ public void setResult(CeTaskResult taskResult) {
+ requireNonNull(taskResult, "taskResult can not be null");
+ checkState(this.result == null, "CeTaskResult has already been set in the holder");
+ this.result = taskResult;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
+
+import org.sonar.server.computation.CeTaskResult;
+
+public interface TaskResultHolder {
+ /**
+ * @throws IllegalStateException if holder holds no CeTaskResult
+ */
+ CeTaskResult getResult();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.util;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class InitializedProperty<E> {
+ private E property;
+ private boolean initialized = false;
+
+ public InitializedProperty<E> setProperty(@Nullable E property) {
+ this.property = property;
+ this.initialized = true;
+ return this;
+ }
+
+ @CheckForNull
+ public E getProperty() {
+ return property;
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.util;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CeTaskTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private CeTask.Builder underTest = new CeTask.Builder();
+
+ @Test
+ public void build_fails_with_NPE_if_organizationUuid_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_organizationUuid_is_empty() {
+ underTest.setOrganizationUuid("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_uid_is_null() {
+ underTest.setOrganizationUuid("org1");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_uuid_is_empty() {
+ underTest.setOrganizationUuid("org1").setUuid("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_type_is_null() {
+ underTest.setOrganizationUuid("org1").setUuid("uuid");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("type can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_type_is_empty() {
+ underTest.setOrganizationUuid("org1").setUuid("uuid").setType("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("type can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void verify_getters() {
+ underTest.setOrganizationUuid("org1");
+ underTest.setType("TYPE_1");
+ underTest.setUuid("UUID_1");
+ underTest.setSubmitterUuid("LOGIN_1");
+ underTest.setComponentKey("COMPONENT_KEY_1");
+ underTest.setComponentUuid("COMPONENT_UUID_1");
+ underTest.setComponentName("The component");
+
+ CeTask task = underTest.build();
+
+ assertThat(task.getOrganizationUuid()).isEqualTo("org1");
+ assertThat(task.getUuid()).isEqualTo("UUID_1");
+ assertThat(task.getType()).isEqualTo("TYPE_1");
+ assertThat(task.getSubmitterUuid()).isEqualTo("LOGIN_1");
+ assertThat(task.getComponentKey()).isEqualTo("COMPONENT_KEY_1");
+ assertThat(task.getComponentUuid()).isEqualTo("COMPONENT_UUID_1");
+ assertThat(task.getComponentName()).isEqualTo("The component");
+ }
+
+ @Test
+ public void empty_in_component_properties_is_considered_as_null() {
+ CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
+ .setComponentKey("")
+ .setComponentName("")
+ .setComponentUuid("")
+ .build();
+
+ assertThat(ceTask.getComponentKey()).isNull();
+ assertThat(ceTask.getComponentName()).isNull();
+ assertThat(ceTask.getComponentUuid()).isNull();
+ }
+
+ @Test
+ public void empty_in_submitterLogin_is_considered_as_null() {
+ CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
+ .setSubmitterUuid("")
+ .build();
+
+ assertThat(ceTask.getSubmitterUuid()).isNull();
+ }
+
+ @Test
+ public void equals_and_hashCode_on_uuid() {
+ underTest.setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_1");
+ CeTask task1 = underTest.build();
+ CeTask task1bis = underTest.build();
+ CeTask task2 = new CeTask.Builder().setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_2").build();
+
+ assertThat(task1.equals(task1)).isTrue();
+ assertThat(task1.equals(task1bis)).isTrue();
+ assertThat(task1.equals(task2)).isFalse();
+ assertThat(task1.hashCode()).isEqualTo(task1.hashCode());
+ assertThat(task1.hashCode()).isEqualTo(task1bis.hashCode());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.log;
+
+import ch.qos.logback.core.joran.spi.JoranException;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.slf4j.MDC;
+import org.sonar.process.logging.LogbackHelper;
+import org.sonar.server.computation.CeTask;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.computation.log.CeTaskLogging.MDC_CE_TASK_UUID;
+
+public class CeTaskLoggingTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private LogbackHelper helper = new LogbackHelper();
+ private CeTaskLogging underTest = new CeTaskLogging();
+
+ @After
+ public void resetLogback() throws JoranException {
+ helper.resetFromXml("/logback-test.xml");
+ }
+
+ @After
+ public void cleanMDC() {
+ MDC.clear();
+ }
+
+ @Test
+ public void initForTask_stores_task_uuid_in_MDC() {
+ String uuid = "ce_task_uuid";
+
+ underTest.initForTask(createCeTask(uuid));
+
+ assertThat(MDC.get(MDC_CE_TASK_UUID)).isEqualTo(uuid);
+ }
+
+ private CeTask createCeTask(String uuid) {
+ CeTask ceTask = Mockito.mock(CeTask.class);
+ when(ceTask.getUuid()).thenReturn(uuid);
+ return ceTask;
+ }
+
+ @Test
+ public void clearForTask_removes_task_uuid_from_MDC() {
+ MDC.put(MDC_CE_TASK_UUID, "some_value");
+
+ underTest.clearForTask();
+
+ assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task;
+
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.api.utils.log.Loggers;
+
+public final class ChangeLogLevel implements AutoCloseable {
+ private final Logger logger;
+ private final LoggerLevel previous;
+
+ public ChangeLogLevel(Class<?> clazz, LoggerLevel newLevel) {
+ this.logger = Loggers.get(clazz);
+ this.previous = logger.getLevel();
+ logger.setLevel(newLevel);
+ }
+
+ @Override
+ public void close() {
+ logger.setLevel(previous);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.container;
+
+import org.junit.Test;
+import org.picocontainer.Startable;
+import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ContainerPopulator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class TaskContainerImplTest {
+ private ComponentContainer parent = new ComponentContainer();
+ private ContainerPopulator populator = mock(ContainerPopulator.class);
+
+ @Test(expected = NullPointerException.class)
+ public void constructor_fails_fast_on_null_container() {
+ new TaskContainerImpl(null, mock(ContainerPopulator.class));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void constructor_fails_fast_on_null_item() {
+ new TaskContainerImpl(new ComponentContainer(), null);
+ }
+
+ @Test
+ public void calls_method_populateContainer_of_passed_in_populator() {
+ TaskContainerImpl ceContainer = new TaskContainerImpl(parent, populator);
+
+ verify(populator).populateContainer(ceContainer);
+ }
+
+ @Test
+ public void ce_container_is_not_child_of_specified_container() {
+ TaskContainerImpl ceContainer = new TaskContainerImpl(parent, populator);
+
+ assertThat(parent.getChildren()).isEmpty();
+ verify(populator).populateContainer(ceContainer);
+ }
+
+ @Test
+ public void bootup_starts_components_lazily_unless_they_are_annotated_with_EagerStart() {
+ final DefaultStartable defaultStartable = new DefaultStartable();
+ final EagerStartable eagerStartable = new EagerStartable();
+ TaskContainerImpl ceContainer = new TaskContainerImpl(parent, container -> {
+ container.add(defaultStartable);
+ container.add(eagerStartable);
+ });
+ ceContainer.bootup();
+
+ assertThat(defaultStartable.startCalls).isEqualTo(0);
+ assertThat(defaultStartable.stopCalls).isEqualTo(0);
+ assertThat(eagerStartable.startCalls).isEqualTo(1);
+ assertThat(eagerStartable.stopCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void close_stops_started_components() {
+ final DefaultStartable defaultStartable = new DefaultStartable();
+ final EagerStartable eagerStartable = new EagerStartable();
+ TaskContainerImpl ceContainer = new TaskContainerImpl(parent, container -> {
+ container.add(defaultStartable);
+ container.add(eagerStartable);
+ });
+ ceContainer.bootup();
+
+ ceContainer.close();
+
+ assertThat(defaultStartable.startCalls).isEqualTo(0);
+ assertThat(defaultStartable.stopCalls).isEqualTo(0);
+ assertThat(eagerStartable.startCalls).isEqualTo(1);
+ assertThat(eagerStartable.stopCalls).isEqualTo(1);
+ }
+
+ public static class DefaultStartable implements Startable {
+ protected int startCalls = 0;
+ protected int stopCalls = 0;
+
+ @Override
+ public void start() {
+ startCalls++;
+ }
+
+ @Override
+ public void stop() {
+ stopCalls++;
+ }
+ }
+
+ @EagerStart
+ public static class EagerStartable extends DefaultStartable {
+ }
+
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.InOrder;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.server.computation.task.ChangeLogLevel;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class ComputationStepExecutorTest {
+ @Rule
+ public LogTester logTester = new LogTester();
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private final ComputationStepExecutor.Listener listener = mock(ComputationStepExecutor.Listener.class);
+ private final ComputationStep computationStep1 = mockComputationStep("step1");
+ private final ComputationStep computationStep2 = mockComputationStep("step2");
+ private final ComputationStep computationStep3 = mockComputationStep("step3");
+
+ @Test
+ public void execute_call_execute_on_each_ComputationStep_in_order_returned_by_instances_method() {
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3))
+ .execute();
+
+ InOrder inOrder = inOrder(computationStep1, computationStep2, computationStep3);
+ inOrder.verify(computationStep1).execute();
+ inOrder.verify(computationStep1).getDescription();
+ inOrder.verify(computationStep2).execute();
+ inOrder.verify(computationStep2).getDescription();
+ inOrder.verify(computationStep3).execute();
+ inOrder.verify(computationStep3).getDescription();
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void execute_let_exception_thrown_by_ComputationStep_go_up_as_is() {
+ String message = "Exception should go up";
+
+ ComputationStep computationStep = mockComputationStep("step1");
+ doThrow(new RuntimeException(message))
+ .when(computationStep)
+ .execute();
+
+ ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep));
+
+ expectedException.expect(RuntimeException.class);
+ expectedException.expectMessage(message);
+
+ computationStepExecutor.execute();
+ }
+
+ @Test
+ public void execute_does_not_log_end_timing_for_each_ComputationStep_called_when_level_is_INFO() {
+ List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.INFO);
+ assertThat(infoLogs).isEmpty();
+ }
+
+ @Test
+ public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_DEBUG() {
+ List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.DEBUG);
+ assertThat(infoLogs).hasSize(2);
+ assertThat(infoLogs.get(0)).contains("step1 | time=");
+ assertThat(infoLogs.get(1)).contains("step2 | time=");
+ }
+
+ @Test
+ public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_TRACE() {
+ List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.TRACE);
+ assertThat(infoLogs).hasSize(2);
+ assertThat(infoLogs.get(0)).contains("step1 | time=");
+ assertThat(infoLogs.get(1)).contains("step2 | time=");
+ }
+
+ private List<String> execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel level) {
+ try (ChangeLogLevel executor = new ChangeLogLevel(ComputationStepExecutor.class, level);
+ ChangeLogLevel step1 = new ChangeLogLevel(computationStep1.getClass(), level);
+ ChangeLogLevel step2 = new ChangeLogLevel(computationStep2.getClass(), level)) {
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2))
+ .execute();
+
+ return logTester.logs(LoggerLevel.DEBUG);
+ }
+ }
+
+ @Test
+ public void execute_calls_listener_finished_method_with_all_step_runs() {
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
+ .execute();
+
+ verify(listener).finished(true);
+ verifyNoMoreInteractions(listener);
+ }
+
+ @Test
+ public void execute_calls_listener_finished_method_even_if_a_step_throws_an_exception() {
+ RuntimeException toBeThrown = new RuntimeException("simulating failing execute Step method");
+ doThrow(toBeThrown)
+ .when(computationStep1)
+ .execute();
+
+ try {
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
+ .execute();
+ fail("exception toBeThrown should have been raised");
+ } catch (RuntimeException e) {
+ assertThat(e).isSameAs(toBeThrown);
+ verify(listener).finished(false);
+ verifyNoMoreInteractions(listener);
+ }
+ }
+
+ @Test
+ public void execute_does_not_fail_if_listener_throws_Throwable() {
+ ComputationStepExecutor.Listener listener = mock(ComputationStepExecutor.Listener.class);
+ doThrow(new Error("Facking error thrown by Listener"))
+ .when(listener)
+ .finished(anyBoolean());
+
+ new ComputationStepExecutor(mockComputationSteps(computationStep1), listener).execute();
+ }
+
+ private static ComputationSteps mockComputationSteps(ComputationStep... computationSteps) {
+ ComputationSteps steps = mock(ComputationSteps.class);
+ when(steps.instances()).thenReturn(Arrays.asList(computationSteps));
+ return steps;
+ }
+
+ private static ComputationStep mockComputationStep(String desc) {
+ ComputationStep mock = mock(ComputationStep.class);
+ when(mock.getDescription()).thenReturn(desc);
+ return mock;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.InOrder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class ExecuteStatelessInitExtensionsStepTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void test_getDescription() {
+ ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep();
+
+ assertThat(underTest.getDescription()).isEqualTo("Initialize");
+ }
+
+ @Test
+ public void do_nothing_if_no_extensions() {
+ ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep();
+
+ // no failure
+ underTest.execute();
+ }
+
+ @Test
+ public void execute_extensions() {
+ StatelessInitExtension ext1 = mock(StatelessInitExtension.class);
+ StatelessInitExtension ext2 = mock(StatelessInitExtension.class);
+
+ ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep(
+ new StatelessInitExtension[] {ext1, ext2});
+ underTest.execute();
+
+ InOrder inOrder = inOrder(ext1, ext2);
+ inOrder.verify(ext1).onInit();
+ inOrder.verify(ext2).onInit();
+ }
+
+ @Test
+ public void fail_if_an_extension_throws_an_exception() {
+ StatelessInitExtension ext1 = mock(StatelessInitExtension.class);
+ StatelessInitExtension ext2 = mock(StatelessInitExtension.class);
+ doThrow(new IllegalStateException("BOOM")).when(ext2).onInit();
+ StatelessInitExtension ext3 = mock(StatelessInitExtension.class);
+
+ ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep(
+ new StatelessInitExtension[] {ext1, ext2, ext3});
+
+ try {
+ underTest.execute();
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("BOOM");
+ verify(ext1).onInit();
+ verify(ext3, never()).onInit();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.task.step;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import java.lang.reflect.Modifier;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.reflections.Reflections;
+
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.FluentIterable.from;
+
+public class StepsExplorer {
+ /**
+ * Compute set of canonical names of classes implementing ComputationStep in the specified package using reflection.
+ */
+ public static Set<String> retrieveStepPackageStepsCanonicalNames(String packageName) {
+ Reflections reflections = new Reflections(packageName);
+
+ return from(reflections.getSubTypesOf(ComputationStep.class))
+ .filter(NotAbstractClass.INSTANCE)
+ .transform(ClassToCanonicalName.INSTANCE)
+ // anonymous classes do not have canonical names
+ .filter(notNull())
+ .toSet();
+ }
+
+ private enum NotAbstractClass implements Predicate<Class<? extends ComputationStep>> {
+ INSTANCE;
+
+ @Override
+ public boolean apply(Class<? extends ComputationStep> input) {
+ return !Modifier.isAbstract(input.getModifiers());
+ }
+ }
+
+ public static Function<Class<?>, String> toCanonicalName() {
+ return ClassToCanonicalName.INSTANCE;
+ }
+
+ private enum ClassToCanonicalName implements Function<Class<?>, String> {
+ INSTANCE;
+
+ @Override
+ public String apply(@Nonnull Class<?> input) {
+ return input.getCanonicalName();
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.server.computation.CeTaskResult;
+
+import static org.mockito.Mockito.mock;
+
+public class MutableTaskResultHolderImplTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private MutableTaskResultHolder underTest = new MutableTaskResultHolderImpl();
+
+ @Test
+ public void getResult_throws_ISE_if_no_CeTaskResult_is_set() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("No CeTaskResult has been set in the holder");
+
+ underTest.getResult();
+ }
+
+ @Test
+ public void getResult_returns_object_set_with_setResult() {
+ CeTaskResult taskResult = mock(CeTaskResult.class);
+
+ underTest.setResult(taskResult);
+
+ Assertions.assertThat(underTest.getResult()).isSameAs(taskResult);
+ }
+
+ @Test
+ public void setResult_throws_NPE_if_CeTaskResult_argument_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("taskResult can not be null");
+
+ underTest.setResult(null);
+ }
+
+ @Test
+ public void setResult_throws_ISE_if_called_twice() {
+ underTest.setResult(mock(CeTaskResult.class));
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("CeTaskResult has already been set in the holder");
+
+ underTest.setResult(mock(CeTaskResult.class));
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration debug="false">
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>
+ %d{yyyy.MM.dd HH:mm:ss} %-5level %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <root>
+ <level value="INFO"/>
+ <appender-ref ref="CONSOLE"/>
+ </root>
+
+ <logger name="ch.qos.logback">
+ <level value="WARN"/>
+ </logger>
+
+ <logger name="okhttp3.mockwebserver">
+ <level value="WARN"/>
+ </logger>
+
+</configuration>
compile 'com.google.protobuf:protobuf-java'
compile 'org.nanohttpd:nanohttpd'
+ compile project(':server:sonar-ce-task')
compile project(':server:sonar-ce-task-projectanalysis')
compile project(':server:sonar-server')
compile 'org.sonarsource.update-center:sonar-update-center-common'
compile 'org.mindrot:jbcrypt'
+ compile project(':server:sonar-ce-task')
compile project(':server:sonar-db-dao')
compile project(':server:sonar-db-migration')
compile project(':server:sonar-plugin-bridge')
testCompile 'org.eclipse.jetty:jetty-servlet'
testCompile 'org.hamcrest:hamcrest-all'
testCompile 'org.mockito:mockito-core'
- testCompile 'org.reflections:reflections'
testCompile 'org.subethamail:subethasmtp'
testCompile project(':server:sonar-db-testing')
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation;
-
-import com.google.common.base.MoreObjects;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import static com.google.common.base.Strings.emptyToNull;
-import static java.util.Objects.requireNonNull;
-
-@Immutable
-public class CeTask {
-
- private final String organizationUuid;
- private final String type;
- private final String uuid;
- private final String componentUuid;
- private final String componentKey;
- private final String componentName;
- private final String submitterUuid;
-
- private CeTask(Builder builder) {
- this.organizationUuid = requireNonNull(emptyToNull(builder.organizationUuid), "organizationUuid can't be null nor empty");
- this.uuid = requireNonNull(emptyToNull(builder.uuid), "uuid can't be null nor empty");
- this.type = requireNonNull(emptyToNull(builder.type), "type can't be null nor empty");
- this.componentUuid = emptyToNull(builder.componentUuid);
- this.componentKey = emptyToNull(builder.componentKey);
- this.componentName = emptyToNull(builder.componentName);
- this.submitterUuid = emptyToNull(builder.submitterUuid);
- }
-
- public String getOrganizationUuid() {
- return organizationUuid;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public String getType() {
- return type;
- }
-
- @CheckForNull
- public String getComponentUuid() {
- return componentUuid;
- }
-
- @CheckForNull
- public String getComponentKey() {
- return componentKey;
- }
-
- @CheckForNull
- public String getComponentName() {
- return componentName;
- }
-
- @CheckForNull
- public String getSubmitterUuid() {
- return submitterUuid;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("organizationUuid", organizationUuid)
- .add("type", type)
- .add("uuid", uuid)
- .add("componentUuid", componentUuid)
- .add("componentKey", componentKey)
- .add("componentName", componentName)
- .add("submitterUuid", submitterUuid)
- .toString();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- CeTask ceTask = (CeTask) o;
- return uuid.equals(ceTask.uuid);
- }
-
- @Override
- public int hashCode() {
- return uuid.hashCode();
- }
-
- public static final class Builder {
- private String organizationUuid;
- private String uuid;
- private String type;
- private String componentUuid;
- private String componentKey;
- private String componentName;
- private String submitterUuid;
-
- public Builder setOrganizationUuid(String organizationUuid) {
- this.organizationUuid = organizationUuid;
- return this;
- }
-
- // FIXME remove this method when organization support is added to the Compute Engine queue
- public boolean hasOrganizationUuid() {
- return organizationUuid != null;
- }
-
- public Builder setUuid(String uuid) {
- this.uuid = uuid;
- return this;
- }
-
- public Builder setType(String type) {
- this.type = type;
- return this;
- }
-
- public Builder setComponentUuid(String componentUuid) {
- this.componentUuid = componentUuid;
- return this;
- }
-
- public Builder setComponentKey(@Nullable String s) {
- this.componentKey = s;
- return this;
- }
-
- public Builder setComponentName(@Nullable String s) {
- this.componentName = s;
- return this;
- }
-
- public Builder setSubmitterUuid(@Nullable String s) {
- this.submitterUuid = s;
- return this;
- }
-
- public CeTask build() {
- return new CeTask(this);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation;
-
-import java.util.Optional;
-
-/**
- * Represents the result of the processing of a {@link CeTask}.
- */
-@FunctionalInterface
-public interface CeTaskResult {
- /**
- * The UUID of the analysis created, if any, for the Component in {@link CeTask}
- */
- Optional<String> getAnalysisUuid();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.log;
-
-import org.slf4j.MDC;
-import org.sonar.server.computation.CeTask;
-
-public class CeTaskLogging {
-
- public static final String MDC_CE_TASK_UUID = "ceTaskUuid";
-
- public void initForTask(CeTask task) {
- MDC.put(MDC_CE_TASK_UUID, task.getUuid());
- }
-
- public void clearForTask() {
- MDC.remove(MDC_CE_TASK_UUID);
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation.log;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.container;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Components with this annotation will be eagerly started when loaded into the {@link TaskContainerImpl}.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface EagerStart {
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.container;
-
-import org.picocontainer.PicoContainer;
-import org.sonar.server.computation.CeTask;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.ContainerPopulator;
-
-/**
- * The Compute Engine task container. Created for a specific parent {@link ComponentContainer} and a specific {@link CeTask}.
- */
-public interface TaskContainer extends ContainerPopulator.Container, AutoCloseable {
-
- ComponentContainer getParent();
-
- /**
- * Starts task container, starting any startable component in it.
- */
- void bootup();
-
- /**
- * Cleans up resources after process has been called and has returned.
- */
- @Override
- void close();
-
- /**
- * Access to the underlying pico container.
- */
- PicoContainer getPicoContainer();
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.container;
-
-import java.util.List;
-import org.picocontainer.ComponentAdapter;
-import org.picocontainer.ComponentMonitor;
-import org.picocontainer.DefaultPicoContainer;
-import org.picocontainer.MutablePicoContainer;
-import org.picocontainer.behaviors.OptInCaching;
-import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
-import org.picocontainer.monitors.NullComponentMonitor;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.ContainerPopulator;
-import org.sonar.core.platform.Module;
-import org.sonar.core.platform.StopSafeReflectionLifecycleStrategy;
-
-import static java.util.Objects.requireNonNull;
-
-public class TaskContainerImpl extends ComponentContainer implements TaskContainer {
-
- public TaskContainerImpl(ComponentContainer parent, ContainerPopulator<TaskContainer> populator) {
- super(createContainer(requireNonNull(parent)), parent.getComponentByType(PropertyDefinitions.class));
-
- populateContainer(requireNonNull(populator));
- }
-
- private void populateContainer(ContainerPopulator<TaskContainer> populator) {
- populator.populateContainer(this);
- populateFromModules();
- }
-
- private void populateFromModules() {
- List<Module> modules = getComponentsByType(Module.class);
- for (Module module : modules) {
- module.configure(this);
- }
- }
-
- /**
- * Creates a PicContainer which extends the specified ComponentContainer <strong>but is not referenced in return</strong>
- * and lazily starts its components.
- */
- private static MutablePicoContainer createContainer(ComponentContainer parent) {
- ComponentMonitor componentMonitor = new NullComponentMonitor();
- ReflectionLifecycleStrategy lifecycleStrategy = new StopSafeReflectionLifecycleStrategy(componentMonitor) {
- @Override
- public boolean isLazy(ComponentAdapter<?> adapter) {
- return adapter.getComponentImplementation().getAnnotation(EagerStart.class) == null;
- }
- };
-
- return new DefaultPicoContainer(new OptInCaching(), lifecycleStrategy, parent.getPicoContainer(), componentMonitor);
- }
-
- @Override
- public void bootup() {
- startComponents();
- }
-
- @Override
- public String toString() {
- return "TaskContainerImpl";
- }
-
- @Override
- public void close() {
- try {
- stopComponents();
- } catch (Throwable t) {
- Loggers.get(TaskContainerImpl.class).error("Cleanup of container failed", t);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation.task.container;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-/**
- * A way of splitting the processing of a task into smaller items which can be executed sequencially
- * by {@link ComputationStepExecutor}.
- */
-public interface ComputationStep {
-
- void execute();
-
- String getDescription();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.util.logs.Profiler;
-
-public final class ComputationStepExecutor {
- private static final Logger LOGGER = Loggers.get(ComputationStepExecutor.class);
-
- private final ComputationSteps steps;
- @CheckForNull
- private final Listener listener;
-
- /**
- * Used when no {@link ComputationStepExecutor.Listener} is available in pico
- * container.
- */
- public ComputationStepExecutor(ComputationSteps steps) {
- this(steps, null);
- }
-
- public ComputationStepExecutor(ComputationSteps steps, @Nullable Listener listener) {
- this.steps = steps;
- this.listener = listener;
- }
-
- public void execute() {
- Profiler stepProfiler = Profiler.create(LOGGER);
- boolean allStepsExecuted = false;
- try {
- executeSteps(stepProfiler);
- allStepsExecuted = true;
- } finally {
- if (listener != null) {
- executeListener(allStepsExecuted);
- }
- }
- }
-
- private void executeSteps(Profiler stepProfiler) {
- for (ComputationStep step : steps.instances()) {
- stepProfiler.start();
- step.execute();
- stepProfiler.stopDebug(step.getDescription());
- }
- }
-
- private void executeListener(boolean allStepsExecuted) {
- try {
- listener.finished(allStepsExecuted);
- } catch (Throwable e) {
- // any Throwable throws by the listener going up the stack might hide an Exception/Error thrown by the step and
- // cause it be swallowed. We don't wan't that => we catch Throwable
- LOGGER.error("Execution of listener failed", e);
- }
- }
-
- @FunctionalInterface
- public interface Listener {
- void finished(boolean allStepsExecuted);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import java.util.List;
-
-/**
- * Ordered list of steps classes and instances to be executed in a Compute Engine process.
- */
-public interface ComputationSteps {
- /**
- * List of all {@link ComputationStep},
- * ordered by execution sequence.
- */
- List<Class<? extends ComputationStep>> orderedStepClasses();
-
- /**
- * List of all {@link ComputationStep},
- * ordered by execution sequence.
- */
- Iterable<ComputationStep> instances();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import org.sonar.api.ce.ComputeEngineSide;
-
-/**
- * Execute {@link StatelessInitExtension} instances in no specific order.
- * If an extension fails (throws an exception), consecutive extensions
- * won't be called.
- */
-@ComputeEngineSide
-public class ExecuteStatelessInitExtensionsStep implements ComputationStep {
-
- private final StatelessInitExtension[] extensions;
-
- public ExecuteStatelessInitExtensionsStep(StatelessInitExtension[] extensions) {
- this.extensions = extensions;
- }
-
- /**
- * Used when zero {@link StatelessInitExtension} are registered into container.
- */
- public ExecuteStatelessInitExtensionsStep() {
- this(new StatelessInitExtension[0]);
- }
-
- @Override
- public void execute() {
- for (StatelessInitExtension extension : extensions) {
- extension.onInit();
- }
- }
-
- @Override
- public String getDescription() {
- return "Initialize";
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import org.sonar.api.ExtensionPoint;
-import org.sonar.api.ce.ComputeEngineSide;
-
-/**
- * Extension point that is called during processing of a task
- * by {@link ExecuteStatelessInitExtensionsStep}.
- * It is stateless, the same instance is reused for all tasks.
- * As a consequence Compute Engine task components can't be injected
- * as dependencies.
- */
-@ComputeEngineSide
-@ExtensionPoint
-public interface StatelessInitExtension {
-
- /**
- * This method can make the task fail by throwing a {@link RuntimeException}
- */
- void onInit();
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-/**
- * This interface is implemented by the exceptions
- * that provide a type of error when failing
- * a Compute Engine task.
- * The error type is persisted and available in
- * the tasks returned by the web services api/ce.
- */
-public interface TypedException {
-
- String getType();
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation.task.step;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
-
-import org.sonar.server.computation.CeTaskResult;
-
-public interface MutableTaskResultHolder extends TaskResultHolder {
- /**
- * @throws NullPointerException if {@code taskResult} is {@code null}
- * @throws IllegalStateException if a {@link CeTaskResult} has already been set in the holder
- */
- void setResult(CeTaskResult taskResult);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
-
-import javax.annotation.CheckForNull;
-import org.sonar.server.computation.CeTaskResult;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-public class MutableTaskResultHolderImpl implements MutableTaskResultHolder {
- @CheckForNull
- private CeTaskResult result;
-
- @Override
- public CeTaskResult getResult() {
- checkState(this.result != null, "No CeTaskResult has been set in the holder");
- return this.result;
- }
-
- @Override
- public void setResult(CeTaskResult taskResult) {
- requireNonNull(taskResult, "taskResult can not be null");
- checkState(this.result == null, "CeTaskResult has already been set in the holder");
- this.result = taskResult;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
-
-import org.sonar.server.computation.CeTaskResult;
-
-public interface TaskResultHolder {
- /**
- * @throws IllegalStateException if holder holds no CeTaskResult
- */
- CeTaskResult getResult();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.util;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-public class InitializedProperty<E> {
- private E property;
- private boolean initialized = false;
-
- public InitializedProperty<E> setProperty(@Nullable E property) {
- this.property = property;
- this.initialized = true;
- return this;
- }
-
- @CheckForNull
- public E getProperty() {
- return property;
- }
-
- public boolean isInitialized() {
- return initialized;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.computation.util;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CeTaskTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private CeTask.Builder underTest = new CeTask.Builder();
-
- @Test
- public void build_fails_with_NPE_if_organizationUuid_is_null() {
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("organizationUuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_organizationUuid_is_empty() {
- underTest.setOrganizationUuid("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("organizationUuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_uid_is_null() {
- underTest.setOrganizationUuid("org1");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("uuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_uuid_is_empty() {
- underTest.setOrganizationUuid("org1").setUuid("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("uuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_type_is_null() {
- underTest.setOrganizationUuid("org1").setUuid("uuid");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("type can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_type_is_empty() {
- underTest.setOrganizationUuid("org1").setUuid("uuid").setType("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("type can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void verify_getters() {
- underTest.setOrganizationUuid("org1");
- underTest.setType("TYPE_1");
- underTest.setUuid("UUID_1");
- underTest.setSubmitterUuid("LOGIN_1");
- underTest.setComponentKey("COMPONENT_KEY_1");
- underTest.setComponentUuid("COMPONENT_UUID_1");
- underTest.setComponentName("The component");
-
- CeTask task = underTest.build();
-
- assertThat(task.getOrganizationUuid()).isEqualTo("org1");
- assertThat(task.getUuid()).isEqualTo("UUID_1");
- assertThat(task.getType()).isEqualTo("TYPE_1");
- assertThat(task.getSubmitterUuid()).isEqualTo("LOGIN_1");
- assertThat(task.getComponentKey()).isEqualTo("COMPONENT_KEY_1");
- assertThat(task.getComponentUuid()).isEqualTo("COMPONENT_UUID_1");
- assertThat(task.getComponentName()).isEqualTo("The component");
- }
-
- @Test
- public void empty_in_component_properties_is_considered_as_null() {
- CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
- .setComponentKey("")
- .setComponentName("")
- .setComponentUuid("")
- .build();
-
- assertThat(ceTask.getComponentKey()).isNull();
- assertThat(ceTask.getComponentName()).isNull();
- assertThat(ceTask.getComponentUuid()).isNull();
- }
-
- @Test
- public void empty_in_submitterLogin_is_considered_as_null() {
- CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
- .setSubmitterUuid("")
- .build();
-
- assertThat(ceTask.getSubmitterUuid()).isNull();
- }
-
- @Test
- public void equals_and_hashCode_on_uuid() {
- underTest.setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_1");
- CeTask task1 = underTest.build();
- CeTask task1bis = underTest.build();
- CeTask task2 = new CeTask.Builder().setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_2").build();
-
- assertThat(task1.equals(task1)).isTrue();
- assertThat(task1.equals(task1bis)).isTrue();
- assertThat(task1.equals(task2)).isFalse();
- assertThat(task1.hashCode()).isEqualTo(task1.hashCode());
- assertThat(task1.hashCode()).isEqualTo(task1bis.hashCode());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.log;
-
-import ch.qos.logback.core.joran.spi.JoranException;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mockito;
-import org.slf4j.MDC;
-import org.sonar.process.logging.LogbackHelper;
-import org.sonar.server.computation.CeTask;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-import static org.sonar.server.computation.log.CeTaskLogging.MDC_CE_TASK_UUID;
-
-public class CeTaskLoggingTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private LogbackHelper helper = new LogbackHelper();
- private CeTaskLogging underTest = new CeTaskLogging();
-
- @After
- public void resetLogback() throws JoranException {
- helper.resetFromXml("/logback-test.xml");
- }
-
- @After
- public void cleanMDC() {
- MDC.clear();
- }
-
- @Test
- public void initForTask_stores_task_uuid_in_MDC() {
- String uuid = "ce_task_uuid";
-
- underTest.initForTask(createCeTask(uuid));
-
- assertThat(MDC.get(MDC_CE_TASK_UUID)).isEqualTo(uuid);
- }
-
- private CeTask createCeTask(String uuid) {
- CeTask ceTask = Mockito.mock(CeTask.class);
- when(ceTask.getUuid()).thenReturn(uuid);
- return ceTask;
- }
-
- @Test
- public void clearForTask_removes_task_uuid_from_MDC() {
- MDC.put(MDC_CE_TASK_UUID, "some_value");
-
- underTest.clearForTask();
-
- assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task;
-
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.api.utils.log.Loggers;
-
-public final class ChangeLogLevel implements AutoCloseable {
- private final Logger logger;
- private final LoggerLevel previous;
-
- public ChangeLogLevel(Class<?> clazz, LoggerLevel newLevel) {
- this.logger = Loggers.get(clazz);
- this.previous = logger.getLevel();
- logger.setLevel(newLevel);
- }
-
- @Override
- public void close() {
- logger.setLevel(previous);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.container;
-
-import org.junit.Test;
-import org.picocontainer.Startable;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.ContainerPopulator;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class TaskContainerImplTest {
- private ComponentContainer parent = new ComponentContainer();
- private ContainerPopulator populator = mock(ContainerPopulator.class);
-
- @Test(expected = NullPointerException.class)
- public void constructor_fails_fast_on_null_container() {
- new TaskContainerImpl(null, mock(ContainerPopulator.class));
- }
-
- @Test(expected = NullPointerException.class)
- public void constructor_fails_fast_on_null_item() {
- new TaskContainerImpl(new ComponentContainer(), null);
- }
-
- @Test
- public void calls_method_populateContainer_of_passed_in_populator() {
- TaskContainerImpl ceContainer = new TaskContainerImpl(parent, populator);
-
- verify(populator).populateContainer(ceContainer);
- }
-
- @Test
- public void ce_container_is_not_child_of_specified_container() {
- TaskContainerImpl ceContainer = new TaskContainerImpl(parent, populator);
-
- assertThat(parent.getChildren()).isEmpty();
- verify(populator).populateContainer(ceContainer);
- }
-
- @Test
- public void bootup_starts_components_lazily_unless_they_are_annotated_with_EagerStart() {
- final DefaultStartable defaultStartable = new DefaultStartable();
- final EagerStartable eagerStartable = new EagerStartable();
- TaskContainerImpl ceContainer = new TaskContainerImpl(parent, container -> {
- container.add(defaultStartable);
- container.add(eagerStartable);
- });
- ceContainer.bootup();
-
- assertThat(defaultStartable.startCalls).isEqualTo(0);
- assertThat(defaultStartable.stopCalls).isEqualTo(0);
- assertThat(eagerStartable.startCalls).isEqualTo(1);
- assertThat(eagerStartable.stopCalls).isEqualTo(0);
- }
-
- @Test
- public void close_stops_started_components() {
- final DefaultStartable defaultStartable = new DefaultStartable();
- final EagerStartable eagerStartable = new EagerStartable();
- TaskContainerImpl ceContainer = new TaskContainerImpl(parent, container -> {
- container.add(defaultStartable);
- container.add(eagerStartable);
- });
- ceContainer.bootup();
-
- ceContainer.close();
-
- assertThat(defaultStartable.startCalls).isEqualTo(0);
- assertThat(defaultStartable.stopCalls).isEqualTo(0);
- assertThat(eagerStartable.startCalls).isEqualTo(1);
- assertThat(eagerStartable.stopCalls).isEqualTo(1);
- }
-
- public static class DefaultStartable implements Startable {
- protected int startCalls = 0;
- protected int stopCalls = 0;
-
- @Override
- public void start() {
- startCalls++;
- }
-
- @Override
- public void stop() {
- stopCalls++;
- }
- }
-
- @EagerStart
- public static class EagerStartable extends DefaultStartable {
- }
-
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.InOrder;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.server.computation.task.ChangeLogLevel;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-public class ComputationStepExecutorTest {
- @Rule
- public LogTester logTester = new LogTester();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private final ComputationStepExecutor.Listener listener = mock(ComputationStepExecutor.Listener.class);
- private final ComputationStep computationStep1 = mockComputationStep("step1");
- private final ComputationStep computationStep2 = mockComputationStep("step2");
- private final ComputationStep computationStep3 = mockComputationStep("step3");
-
- @Test
- public void execute_call_execute_on_each_ComputationStep_in_order_returned_by_instances_method() {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3))
- .execute();
-
- InOrder inOrder = inOrder(computationStep1, computationStep2, computationStep3);
- inOrder.verify(computationStep1).execute();
- inOrder.verify(computationStep1).getDescription();
- inOrder.verify(computationStep2).execute();
- inOrder.verify(computationStep2).getDescription();
- inOrder.verify(computationStep3).execute();
- inOrder.verify(computationStep3).getDescription();
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void execute_let_exception_thrown_by_ComputationStep_go_up_as_is() {
- String message = "Exception should go up";
-
- ComputationStep computationStep = mockComputationStep("step1");
- doThrow(new RuntimeException(message))
- .when(computationStep)
- .execute();
-
- ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep));
-
- expectedException.expect(RuntimeException.class);
- expectedException.expectMessage(message);
-
- computationStepExecutor.execute();
- }
-
- @Test
- public void execute_does_not_log_end_timing_for_each_ComputationStep_called_when_level_is_INFO() {
- List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.INFO);
- assertThat(infoLogs).isEmpty();
- }
-
- @Test
- public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_DEBUG() {
- List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.DEBUG);
- assertThat(infoLogs).hasSize(2);
- assertThat(infoLogs.get(0)).contains("step1 | time=");
- assertThat(infoLogs.get(1)).contains("step2 | time=");
- }
-
- @Test
- public void execute_logs_end_timing_for_each_ComputationStep_called_when_level_is_TRACE() {
- List<String> infoLogs = execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel.TRACE);
- assertThat(infoLogs).hasSize(2);
- assertThat(infoLogs.get(0)).contains("step1 | time=");
- assertThat(infoLogs.get(1)).contains("step2 | time=");
- }
-
- private List<String> execute_logs_end_timing_for_each_ComputationStep_called_when_(LoggerLevel level) {
- try (ChangeLogLevel executor = new ChangeLogLevel(ComputationStepExecutor.class, level);
- ChangeLogLevel step1 = new ChangeLogLevel(computationStep1.getClass(), level);
- ChangeLogLevel step2 = new ChangeLogLevel(computationStep2.getClass(), level)) {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2))
- .execute();
-
- return logTester.logs(LoggerLevel.DEBUG);
- }
- }
-
- @Test
- public void execute_calls_listener_finished_method_with_all_step_runs() {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
- .execute();
-
- verify(listener).finished(true);
- verifyNoMoreInteractions(listener);
- }
-
- @Test
- public void execute_calls_listener_finished_method_even_if_a_step_throws_an_exception() {
- RuntimeException toBeThrown = new RuntimeException("simulating failing execute Step method");
- doThrow(toBeThrown)
- .when(computationStep1)
- .execute();
-
- try {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
- .execute();
- fail("exception toBeThrown should have been raised");
- } catch (RuntimeException e) {
- assertThat(e).isSameAs(toBeThrown);
- verify(listener).finished(false);
- verifyNoMoreInteractions(listener);
- }
- }
-
- @Test
- public void execute_does_not_fail_if_listener_throws_Throwable() {
- ComputationStepExecutor.Listener listener = mock(ComputationStepExecutor.Listener.class);
- doThrow(new Error("Facking error thrown by Listener"))
- .when(listener)
- .finished(anyBoolean());
-
- new ComputationStepExecutor(mockComputationSteps(computationStep1), listener).execute();
- }
-
- private static ComputationSteps mockComputationSteps(ComputationStep... computationSteps) {
- ComputationSteps steps = mock(ComputationSteps.class);
- when(steps.instances()).thenReturn(Arrays.asList(computationSteps));
- return steps;
- }
-
- private static ComputationStep mockComputationStep(String desc) {
- ComputationStep mock = mock(ComputationStep.class);
- when(mock.getDescription()).thenReturn(desc);
- return mock;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.InOrder;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-public class ExecuteStatelessInitExtensionsStepTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Test
- public void test_getDescription() {
- ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep();
-
- assertThat(underTest.getDescription()).isEqualTo("Initialize");
- }
-
- @Test
- public void do_nothing_if_no_extensions() {
- ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep();
-
- // no failure
- underTest.execute();
- }
-
- @Test
- public void execute_extensions() {
- StatelessInitExtension ext1 = mock(StatelessInitExtension.class);
- StatelessInitExtension ext2 = mock(StatelessInitExtension.class);
-
- ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep(
- new StatelessInitExtension[] {ext1, ext2});
- underTest.execute();
-
- InOrder inOrder = inOrder(ext1, ext2);
- inOrder.verify(ext1).onInit();
- inOrder.verify(ext2).onInit();
- }
-
- @Test
- public void fail_if_an_extension_throws_an_exception() {
- StatelessInitExtension ext1 = mock(StatelessInitExtension.class);
- StatelessInitExtension ext2 = mock(StatelessInitExtension.class);
- doThrow(new IllegalStateException("BOOM")).when(ext2).onInit();
- StatelessInitExtension ext3 = mock(StatelessInitExtension.class);
-
- ExecuteStatelessInitExtensionsStep underTest = new ExecuteStatelessInitExtensionsStep(
- new StatelessInitExtension[] {ext1, ext2, ext3});
-
- try {
- underTest.execute();
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("BOOM");
- verify(ext1).onInit();
- verify(ext3, never()).onInit();
- }
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.task.step;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import java.lang.reflect.Modifier;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import org.reflections.Reflections;
-
-import static com.google.common.base.Predicates.notNull;
-import static com.google.common.collect.FluentIterable.from;
-
-public class StepsExplorer {
- /**
- * Compute set of canonical names of classes implementing ComputationStep in the specified package using reflection.
- */
- public static Set<String> retrieveStepPackageStepsCanonicalNames(String packageName) {
- Reflections reflections = new Reflections(packageName);
-
- return from(reflections.getSubTypesOf(ComputationStep.class))
- .filter(NotAbstractClass.INSTANCE)
- .transform(ClassToCanonicalName.INSTANCE)
- // anonymous classes do not have canonical names
- .filter(notNull())
- .toSet();
- }
-
- private enum NotAbstractClass implements Predicate<Class<? extends ComputationStep>> {
- INSTANCE;
-
- @Override
- public boolean apply(Class<? extends ComputationStep> input) {
- return !Modifier.isAbstract(input.getModifiers());
- }
- }
-
- public static Function<Class<?>, String> toCanonicalName() {
- return ClassToCanonicalName.INSTANCE;
- }
-
- private enum ClassToCanonicalName implements Function<Class<?>, String> {
- INSTANCE;
-
- @Override
- public String apply(@Nonnull Class<?> input) {
- return input.getCanonicalName();
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.server.computation.taskprocessor;
-
-import org.assertj.core.api.Assertions;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.server.computation.CeTaskResult;
-
-import static org.mockito.Mockito.mock;
-
-public class MutableTaskResultHolderImplTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private MutableTaskResultHolder underTest = new MutableTaskResultHolderImpl();
-
- @Test
- public void getResult_throws_ISE_if_no_CeTaskResult_is_set() {
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("No CeTaskResult has been set in the holder");
-
- underTest.getResult();
- }
-
- @Test
- public void getResult_returns_object_set_with_setResult() {
- CeTaskResult taskResult = mock(CeTaskResult.class);
-
- underTest.setResult(taskResult);
-
- Assertions.assertThat(underTest.getResult()).isSameAs(taskResult);
- }
-
- @Test
- public void setResult_throws_NPE_if_CeTaskResult_argument_is_null() {
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("taskResult can not be null");
-
- underTest.setResult(null);
- }
-
- @Test
- public void setResult_throws_ISE_if_called_twice() {
- underTest.setResult(mock(CeTaskResult.class));
-
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("CeTaskResult has already been set in the holder");
-
- underTest.setResult(mock(CeTaskResult.class));
- }
-}
include 'server:sonar-bitbucketcloud'
include 'server:sonar-ce'
+include 'server:sonar-ce-task'
include 'server:sonar-ce-task-projectanalysis'
include 'server:sonar-db-testing'
include 'server:sonar-db-core'