*/
package org.sonar.ce.log;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.FileAppender;
-import java.util.function.Supplier;
import org.apache.log4j.MDC;
-import org.sonar.api.utils.log.Logger;
import org.sonar.ce.queue.CeTask;
-import org.sonar.process.LogbackHelper;
-import org.sonar.process.Props;
-/**
- * Manages the logs written by Compute Engine:
- * <ul>
- * <li>access to existing logs</li>
- * <li>configure logback when CE worker starts and stops processing a task</li>
- * </ul>
- */
public class CeLogging {
- private static final String CE_ACTIVITY_APPENDER_NAME = "ce_activity";
- private static final String CE_ACTIVITY_FILE_NAME_PREFIX = "ce_activity";
- private static final String CE_ACTIVITY_ENCODER_PATTERN = "%d{yyyy.MM.dd HH:mm:ss} %-5level [%X{ceTaskUuid}][%logger{20}] %msg%n";
-
static final String MDC_CE_ACTIVITY_FLAG = "ceActivityFlag";
static final String MDC_CE_TASK_UUID = "ceTaskUuid";
MDC.remove(MDC_CE_TASK_UUID);
}
- public void logCeActivity(Logger logger, Runnable logProducer) {
- MDC.put(MDC_CE_ACTIVITY_FLAG, computeCeActivityFlag(logger));
- try {
- logProducer.run();
- } finally {
- MDC.remove(MDC_CE_ACTIVITY_FLAG);
- }
- }
-
- public <T> T logCeActivity(Logger logger, Supplier<T> logProducer) {
- MDC.put(MDC_CE_ACTIVITY_FLAG, computeCeActivityFlag(logger));
- try {
- return logProducer.get();
- } finally {
- MDC.remove(MDC_CE_ACTIVITY_FLAG);
- }
- }
-
- private static String computeCeActivityFlag(Logger logger) {
- return logger.isDebugEnabled() || logger.isTraceEnabled() ? "all" : "ce_only";
- }
-
- public static Appender<ILoggingEvent> createCeActivityAppenderConfiguration(LogbackHelper helper, LoggerContext ctx, Props processProps) {
- LogbackHelper.RollingPolicy rollingPolicy = helper.createRollingPolicy(ctx, processProps, CE_ACTIVITY_FILE_NAME_PREFIX);
- FileAppender<ILoggingEvent> fileAppender = rollingPolicy.createAppender(CE_ACTIVITY_APPENDER_NAME);
- fileAppender.setContext(ctx);
-
- PatternLayoutEncoder consoleEncoder = new PatternLayoutEncoder();
- consoleEncoder.setContext(ctx);
- consoleEncoder.setPattern(CE_ACTIVITY_ENCODER_PATTERN);
- consoleEncoder.start();
- fileAppender.setEncoder(consoleEncoder);
- fileAppender.addFilter(new CeActivityLogAcceptFilter<>());
- fileAppender.start();
-
- return fileAppender;
- }
}
protected void configureAppenders(String logFormat, LoggerContext ctx, LogbackHelper helper, Props props) {
ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", logFormat, new CeActivityLogConsoleFilter());
ctx.getLogger(ROOT_LOGGER_NAME).addAppender(consoleAppender);
- ctx.getLogger(ROOT_LOGGER_NAME).addAppender(CeLogging.createCeActivityAppenderConfiguration(helper, ctx, props));
}
}
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
*/
public class VisitorsCrawler implements ComponentCrawler {
+ private final boolean computeDuration;
private final Map<ComponentVisitor, VisitorDuration> visitorCumulativeDurations;
private final List<VisitorWrapper> preOrderVisitorWrappers;
private final List<VisitorWrapper> postOrderVisitorWrappers;
public VisitorsCrawler(Iterable<ComponentVisitor> visitors) {
+ this(visitors, false);
+ }
+
+ public VisitorsCrawler(Iterable<ComponentVisitor> visitors, boolean computeDuration) {
List<VisitorWrapper> visitorWrappers = from(visitors).transform(ToVisitorWrapper.INSTANCE).toList();
this.preOrderVisitorWrappers = from(visitorWrappers).filter(MathPreOrderVisitor.INSTANCE).toList();
this.postOrderVisitorWrappers = from(visitorWrappers).filter(MatchPostOrderVisitor.INSTANCE).toList();
- this.visitorCumulativeDurations = from(visitors).toMap(VisitorWrapperToInitialDuration.INSTANCE);
+ this.computeDuration = computeDuration;
+ this.visitorCumulativeDurations = computeDuration ? from(visitors).toMap(VisitorWrapperToInitialDuration.INSTANCE) : Collections.emptyMap();
}
public Map<ComponentVisitor, Long> getCumulativeDurations() {
- return ImmutableMap.copyOf(
- Maps.transformValues(this.visitorCumulativeDurations, VisitorDurationToDuration.INSTANCE)
+ if (computeDuration) {
+ return ImmutableMap.copyOf(
+ Maps.transformValues(this.visitorCumulativeDurations, VisitorDurationToDuration.INSTANCE)
);
+ }
+ return Collections.emptyMap();
}
@Override
}
private void incrementDuration(VisitorWrapper visitorWrapper, long duration) {
- visitorCumulativeDurations.get(visitorWrapper.getWrappedVisitor()).increment(duration);
+ if (computeDuration) {
+ visitorCumulativeDurations.get(visitorWrapper.getWrappedVisitor()).increment(duration);
+ }
}
private enum ToVisitorWrapper implements Function<ComponentVisitor, VisitorWrapper> {
import java.util.Map;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.log.CeLogging;
import org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
import org.sonar.server.computation.task.projectanalysis.component.VisitorsCrawler;
private final TreeRootHolder treeRootHolder;
private final List<ComponentVisitor> visitors;
- private final CeLogging ceLogging;
- public ExecuteVisitorsStep(TreeRootHolder treeRootHolder, List<ComponentVisitor> visitors, CeLogging ceLogging) {
+ public ExecuteVisitorsStep(TreeRootHolder treeRootHolder, List<ComponentVisitor> visitors) {
this.treeRootHolder = treeRootHolder;
this.visitors = visitors;
- this.ceLogging = ceLogging;
}
@Override
@Override
public void execute() {
- VisitorsCrawler visitorsCrawler = new VisitorsCrawler(visitors);
+ VisitorsCrawler visitorsCrawler = new VisitorsCrawler(visitors, LOGGER.isDebugEnabled());
visitorsCrawler.visit(treeRootHolder.getRoot());
- ceLogging.logCeActivity(LOGGER, () -> logVisitorExecutionDurations(visitors, visitorsCrawler));
+ logVisitorExecutionDurations(visitors, visitorsCrawler);
}
private static void logVisitorExecutionDurations(List<ComponentVisitor> visitors, VisitorsCrawler visitorsCrawler) {
- LOGGER.info(" Execution time for each component visitor:");
- Map<ComponentVisitor, Long> cumulativeDurations = visitorsCrawler.getCumulativeDurations();
- for (ComponentVisitor visitor : visitors) {
- LOGGER.info(" - {} | time={}ms", visitor.getClass().getSimpleName(), cumulativeDurations.get(visitor));
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(" Execution time for each component visitor:");
+ Map<ComponentVisitor, Long> cumulativeDurations = visitorsCrawler.getCumulativeDurations();
+ for (ComponentVisitor visitor : visitors) {
+ LOGGER.debug(" - {} | time={}ms", visitor.getClass().getSimpleName(), cumulativeDurations.get(visitor));
+ }
}
}
}
import javax.annotation.Nullable;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.log.CeLogging;
import org.sonar.core.util.logs.Profiler;
public final class ComputationStepExecutor {
private static final Logger LOGGER = Loggers.get(ComputationStepExecutor.class);
private final ComputationSteps steps;
- private final CeLogging ceLogging;
@CheckForNull
private final Listener listener;
* Used when no {@link ComputationStepExecutor.Listener} is available in pico
* container.
*/
- public ComputationStepExecutor(ComputationSteps steps, CeLogging ceLogging) {
- this(steps, ceLogging, null);
+ public ComputationStepExecutor(ComputationSteps steps) {
+ this(steps, null);
}
- public ComputationStepExecutor(ComputationSteps steps, CeLogging ceLogging, @Nullable Listener listener) {
+ public ComputationStepExecutor(ComputationSteps steps, @Nullable Listener listener) {
this.steps = steps;
- this.ceLogging = ceLogging;
this.listener = listener;
}
for (ComputationStep step : steps.instances()) {
stepProfiler.start();
step.execute();
- ceLogging.logCeActivity(LOGGER, () -> stepProfiler.stopInfo(step.getDescription()));
+ stepProfiler.stopDebug(step.getDescription());
}
}
}
}
- private Profiler startActivityProfiler(CeTask task) {
+ private static Profiler startActivityProfiler(CeTask task) {
Profiler profiler = Profiler.create(LOG);
addContext(profiler, task);
- return ceLogging.logCeActivity(LOG, () -> profiler.startInfo("Execute task"));
+ return profiler.startInfo("Execute task");
}
- private void stopActivityProfiler(Profiler profiler, CeTask task, CeActivityDto.Status status) {
+ private static void stopActivityProfiler(Profiler profiler, CeTask task, CeActivityDto.Status status) {
addContext(profiler, task);
if (status == CeActivityDto.Status.FAILED) {
- ceLogging.logCeActivity(LOG, () -> profiler.stopError("Executed task"));
+ profiler.stopError("Executed task");
} else {
- ceLogging.logCeActivity(LOG, () -> profiler.stopInfo("Executed task"));
+ profiler.stopInfo("Executed task");
}
}
*/
package org.sonar.ce.log;
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.joran.spi.JoranException;
-import java.io.File;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.After;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.slf4j.MDC;
-import org.sonar.api.utils.log.Logger;
import org.sonar.ce.queue.CeTask;
import org.sonar.process.LogbackHelper;
-import org.sonar.process.ProcessProperties;
-import org.sonar.process.Props;
-import static ch.qos.logback.classic.Level.DEBUG;
-import static ch.qos.logback.classic.Level.ERROR;
-import static ch.qos.logback.classic.Level.INFO;
-import static ch.qos.logback.classic.Level.TRACE;
-import static ch.qos.logback.classic.Level.WARN;
-import static junit.framework.TestCase.fail;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.ce.log.CeLogging.MDC_CE_ACTIVITY_FLAG;
import static org.sonar.ce.log.CeLogging.MDC_CE_TASK_UUID;
public class CeLoggingTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
private LogbackHelper helper = new LogbackHelper();
- private File logDir;
-
private CeLogging underTest = new CeLogging();
- @Before
- public void setUp() throws Exception {
- this.logDir = temp.newFolder();
- }
-
@After
public void resetLogback() throws JoranException {
helper.resetFromXml("/logback-test.xml");
assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
}
- @Test
- public void createCeConfigurationConfiguration_fails_if_log_directory_is_not_set_in_Props() {
- LogbackHelper helper = new LogbackHelper();
- LoggerContext ctx = new LoggerContext();
- Props processProps = new Props(new Properties());
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Property sonar.path.logs is not set");
-
- CeLogging.createCeActivityAppenderConfiguration(helper, ctx, processProps);
- }
-
- @Test
- public void createCeConfigurationConfiguration() {
- Properties props = new Properties();
- props.setProperty(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
- Appender<ILoggingEvent> appender = CeLogging.createCeActivityAppenderConfiguration(new LogbackHelper(), new LoggerContext(), new Props(props));
-
- // filter on CE logs
- List<Filter<ILoggingEvent>> filters = appender.getCopyOfAttachedFiltersList();
- assertThat(filters).hasSize(1);
- assertThat(filters.get(0)).isInstanceOf(CeActivityLogAcceptFilter.class);
-
- assertThat(appender).isInstanceOf(FileAppender.class);
- assertThat(appender.getName()).isEqualTo("ce_activity");
- FileAppender fileAppender = (FileAppender) appender;
- assertThat(fileAppender.getEncoder())
- .isInstanceOf(PatternLayoutEncoder.class);
- assertThat(fileAppender.getFile()).isEqualTo(new File(logDir, "ce_activity.log").getAbsolutePath());
- }
-
- @Test
- public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_ERROR_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
- callLogCeActivityOfRunnableAndVerify("ce_only", ERROR);
- callLogCeActivityOfFailingRunnableAndVerify("ce_only", ERROR);
- }
-
- @Test
- public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_WARN_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
- callLogCeActivityOfRunnableAndVerify("ce_only", WARN);
- callLogCeActivityOfFailingRunnableAndVerify("ce_only", WARN);
- }
-
- @Test
- public void logCeActivity_of_Runnable_set_flag_in_MDC_to_ce_only_when_log_level_is_INFO_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
- callLogCeActivityOfRunnableAndVerify("ce_only", INFO);
- }
-
- @Test
- public void logCeActivity_of_Runnable_set_flag_in_MDC_to_all_when_log_level_is_DEBUG_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
- callLogCeActivityOfRunnableAndVerify("all", DEBUG);
- callLogCeActivityOfFailingRunnableAndVerify("all", DEBUG);
- }
-
- @Test
- public void logCeActivity_of_Runnable_set_flag_in_MDC_to_all_when_log_level_is_TRACE_and_calls_Runnable_and_remove_flag_even_if_Runnable_throws_exception() {
- callLogCeActivityOfRunnableAndVerify("all", TRACE);
- callLogCeActivityOfFailingRunnableAndVerify("all", TRACE);
- }
-
- private void callLogCeActivityOfRunnableAndVerify(String expectedMdcValue, Level logLevel) {
- AtomicBoolean called = new AtomicBoolean(false);
- underTest.logCeActivity(
- createLogger(logLevel),
- () -> {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedMdcValue);
- called.compareAndSet(false, true);
- });
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
- assertThat(called.get()).isTrue();
- }
-
- private void callLogCeActivityOfFailingRunnableAndVerify(String expectedMdcValue, Level logLevel) {
- RuntimeException exception = new RuntimeException("Simulates a failing Runnable");
-
- AtomicBoolean called = new AtomicBoolean(false);
- try {
- underTest.logCeActivity(
- createLogger(logLevel),
- () -> {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedMdcValue);
- called.compareAndSet(false, true);
- throw exception;
- });
- fail("exception should have been raised");
- } catch (Exception e) {
- assertThat(e).isSameAs(exception);
- } finally {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
- assertThat(called.get()).isTrue();
- }
- }
-
- private static Logger createLogger(Level info) {
- Logger logger = mock(Logger.class);
- when(logger.isDebugEnabled()).thenReturn(DEBUG.isGreaterOrEqual(info));
- when(logger.isTraceEnabled()).thenReturn(TRACE.isGreaterOrEqual(info));
- return logger;
- }
-
- @Test
- public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_ERROR_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
- callLogCeActivityOfSupplierAndVerify(ERROR, "ce_only");
- callLogCeActivityOfFailingSupplierAndVerify(ERROR, "ce_only");
- }
-
- @Test
- public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_WARN_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
- callLogCeActivityOfSupplierAndVerify(WARN, "ce_only");
- callLogCeActivityOfFailingSupplierAndVerify(WARN, "ce_only");
- }
-
- @Test
- public void logCeActivity_of_Supplier_set_flag_in_MDC_to_ce_only_when_log_level_is_INFO_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
- callLogCeActivityOfSupplierAndVerify(INFO, "ce_only");
- callLogCeActivityOfFailingSupplierAndVerify(INFO, "ce_only");
- }
-
- @Test
- public void logCeActivity_of_Supplier_set_flag_in_MDC_to_all_when_log_level_is_DEBUG_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
- callLogCeActivityOfSupplierAndVerify(DEBUG, "all");
- callLogCeActivityOfFailingSupplierAndVerify(DEBUG, "all");
- }
-
- @Test
- public void logCeActivity_of_Supplier_set_flag_in_MDC_to_all_when_log_level_is_TRACE_and_calls_Supplier_and_remove_flag_even_if_Supplier_throws_exception() {
- callLogCeActivityOfSupplierAndVerify(TRACE, "all");
- callLogCeActivityOfFailingSupplierAndVerify(TRACE, "all");
- }
-
- private void callLogCeActivityOfSupplierAndVerify(Level logLevel, String expectedFlag) {
- AtomicBoolean called = new AtomicBoolean(false);
- underTest.logCeActivity(
- createLogger(logLevel),
- () -> {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedFlag);
- called.compareAndSet(false, true);
- return 1;
- });
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
- assertThat(called.get()).isTrue();
- }
-
- private void callLogCeActivityOfFailingSupplierAndVerify(Level logLevel, String expectedFlag) {
- RuntimeException exception = new RuntimeException("Simulates a failing Supplier");
-
- AtomicBoolean called = new AtomicBoolean(false);
- try {
- underTest.logCeActivity(
- createLogger(logLevel),
- () -> {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isEqualTo(expectedFlag);
- called.compareAndSet(false, true);
- throw exception;
- });
- fail("exception should have been raised");
- } catch (Exception e) {
- assertThat(e).isSameAs(exception);
- } finally {
- assertThat(MDC.get(MDC_CE_ACTIVITY_FLAG)).isNull();
- assertThat(called.get()).isTrue();
- }
- }
-
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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);
+ }
+}
import org.junit.rules.ExpectedException;
import org.mockito.InOrder;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
@Test
public void execute_pre_visitor_before_post_visitor() throws Exception {
InOrder inOrder = inOrder(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor);
- VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
underTest.visit(COMPONENT_TREE);
inOrder.verify(spyPreOrderTypeAwareVisitor).visitProject(COMPONENT_TREE);
inOrder.verify(spyPostOrderTypeAwareVisitor).visitProject(COMPONENT_TREE);
}
+ @Test
+ public void getCumulativeDurations_returns_an_empty_map_when_computation_is_disabled_in_constructor() {
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
+ underTest.visit(COMPONENT_TREE);
+
+ assertThat(underTest.getCumulativeDurations()).isEmpty();
+ }
+
+ @Test
+ public void getCumulativeDurations_returns_an_non_empty_map_when_computation_is_enabled_in_constructor() {
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), true);
+ underTest.visit(COMPONENT_TREE);
+
+ assertThat(underTest.getCumulativeDurations()).hasSize(2);
+ }
+
@Test
public void fail_with_IAE_when_visitor_is_not_path_aware_or_type_aware() throws Exception {
thrown.expect(IllegalArgumentException.class);
import org.junit.rules.ExpectedException;
import org.mockito.InOrder;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
@Test
public void execute_each_visitor_on_each_level() throws Exception {
InOrder inOrder = inOrder(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor);
- VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor));
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPostOrderTypeAwareVisitor, spyPathAwareVisitor), false);
underTest.visit(COMPONENT_TREE);
inOrder.verify(spyPostOrderTypeAwareVisitor).visitAny(PROJECT_VIEW_5);
@Test
public void execute_pre_visitor_before_post_visitor() throws Exception {
InOrder inOrder = inOrder(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor);
- VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor));
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
underTest.visit(COMPONENT_TREE);
inOrder.verify(spyPreOrderTypeAwareVisitor).visitView(COMPONENT_TREE);
new VisitorsCrawler(Arrays.asList(componentVisitor));
}
+ @Test
+ public void getCumulativeDurations_returns_an_empty_map_when_computation_is_disabled_in_constructor() {
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), false);
+ underTest.visit(COMPONENT_TREE);
+
+ assertThat(underTest.getCumulativeDurations()).isEmpty();
+ }
+
+ @Test
+ public void getCumulativeDurations_returns_an_non_empty_map_when_computation_is_enabled_in_constructor() {
+ VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(spyPreOrderTypeAwareVisitor, spyPostOrderTypeAwareVisitor), true);
+ underTest.visit(COMPONENT_TREE);
+
+ assertThat(underTest.getCumulativeDurations()).hasSize(2);
+ }
+
private static Component component(final Component.Type type, final int ref, final Component... children) {
return ViewsComponent.builder(type, ref).addChildren(children).build();
}
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.task.ChangeLogLevel;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor;
import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import static org.sonar.api.measures.CoreMetrics.NCLOC;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
@Rule
public LogTester logTester = new LogTester();
- private CeLogging ceLogging = spy(new CeLogging());
-
@Before
public void setUp() throws Exception {
treeRootHolder.setRoot(
@Test
public void execute_with_type_aware_visitor() throws Exception {
- ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestTypeAwareVisitor()), ceLogging);
+ ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestTypeAwareVisitor()));
measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(2));
@Test
public void execute_with_path_aware_visitor() throws Exception {
- ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestPathAwareVisitor()), ceLogging);
+ ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestPathAwareVisitor()));
measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(1));
@Test
public void execute_logs_at_info_level_all_execution_duration_of_all_visitors() {
- ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(
- treeRootHolder,
- asList(new VisitorA(), new VisitorB(), new VisitorC()),
- ceLogging);
-
- underStep.execute();
+ try (ChangeLogLevel executor = new ChangeLogLevel(ExecuteVisitorsStep.class, LoggerLevel.DEBUG);
+ ChangeLogLevel step1 = new ChangeLogLevel(VisitorA.class, LoggerLevel.DEBUG);
+ ChangeLogLevel step2 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG);
+ ChangeLogLevel step3 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG)) {
+ ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(
+ treeRootHolder,
+ asList(new VisitorA(), new VisitorB(), new VisitorC()));
+
+ underStep.execute();
+
+ List<String> logs = logTester.logs(LoggerLevel.DEBUG);
+ assertThat(logs).hasSize(4);
+ assertThat(logs.get(0)).isEqualTo(" Execution time for each component visitor:");
+ assertThat(logs.get(1)).startsWith(" - VisitorA | time=");
+ assertThat(logs.get(2)).startsWith(" - VisitorB | time=");
+ assertThat(logs.get(3)).startsWith(" - VisitorC | time=");
- verify(ceLogging).logCeActivity(any(Logger.class), any(Runnable.class));
- List<String> logs = logTester.logs(LoggerLevel.INFO);
- assertThat(logs).hasSize(4);
- assertThat(logs.get(0)).isEqualTo(" Execution time for each component visitor:");
- assertThat(logs.get(1)).startsWith(" - VisitorA | time=");
- assertThat(logs.get(2)).startsWith(" - VisitorB | time=");
- assertThat(logs.get(3)).startsWith(" - VisitorC | time=");
+ }
}
private static class VisitorA extends TypeAwareVisitorAdapter {
import org.mockito.InOrder;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.task.ChangeLogLevel;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
private final ComputationStep computationStep2 = mockComputationStep("step2");
private final ComputationStep computationStep3 = mockComputationStep("step3");
- private CeLogging ceLogging = new CeLogging();
-
@Test
public void execute_call_execute_on_each_ComputationStep_in_order_returned_by_instances_method() {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3), ceLogging)
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2, computationStep3))
.execute();
InOrder inOrder = inOrder(computationStep1, computationStep2, computationStep3);
.when(computationStep)
.execute();
- ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep), ceLogging);
+ ComputationStepExecutor computationStepExecutor = new ComputationStepExecutor(mockComputationSteps(computationStep));
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(message);
}
@Test
- public void execute_logs_end_timing_for_each_ComputationStep_called() {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), ceLogging)
- .execute();
+ 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();
+ }
- List<String> infoLogs = logTester.logs(LoggerLevel.INFO);
+ @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), ceLogging, listener)
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
.execute();
verify(listener).finished(true);
.execute();
try {
- new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), ceLogging, listener)
+ new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), listener)
.execute();
fail("exception toBeThrown should have been raised");
} catch (RuntimeException e) {