001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.utils.log;
021
022import org.junit.rules.ExternalResource;
023
024import java.util.List;
025
026/**
027 * <b>For tests only</b>
028 * <p/>
029 * This JUnit rule allows to configure and access logs in tests. By default
030 * trace level is enabled.
031 * <p/>
032 * Warning - not compatible with parallel execution of tests in the same JVM fork.
033 * <p/>
034 * Example:
035 * <pre>
036 * public class MyClass {
037 *   private final Logger logger = Loggers.get("logger_name");
038 *
039 *   public void doSomething() {
040 *     logger.info("foo");
041 *   }
042 * }
043 *
044 * public class MyTest {
045 *   &#064;org.junit.Rule
046 *   public LogTester logTester = new LogTester();
047 *
048 *   &#064;org.junit.Test
049 *   public void test_log() {
050 *     new MyClass().doSomething();
051 *
052 *     assertThat(logTester.logs()).containsOnly("foo");
053 *   }
054 * }
055 * </pre>
056 *
057 * @since 5.1
058 */
059public class LogTester extends ExternalResource {
060
061  private LoggerLevel initialLevel;
062
063  @Override
064  protected void before() throws Throwable {
065    initialLevel = Loggers.getFactory().getLevel();
066
067    // this shared instance breaks compatibility with parallel execution of tests
068    LogInterceptors.set(new ListInterceptor());
069    setLevel(LoggerLevel.TRACE);
070  }
071
072  @Override
073  protected void after() {
074    LogInterceptors.set(NullInterceptor.NULL_INSTANCE);
075    setLevel(initialLevel);
076  }
077
078  LoggerLevel getLevel() {
079    return Loggers.getFactory().getLevel();
080  }
081
082  /**
083   * Enable/disable debug logs. Info, warn and error logs are always enabled.
084   * By default debug logs are enabled when LogTester is started.
085   */
086  public LogTester setLevel(LoggerLevel level) {
087    Loggers.getFactory().setLevel(level);
088    return this;
089  }
090
091  /**
092   * Logs in chronological order (item at index 0 is the oldest one)
093   */
094  public List<String> logs() {
095    return ((ListInterceptor) LogInterceptors.get()).logs();
096  }
097
098  /**
099   * Logs in chronological order (item at index 0 is the oldest one) for
100   * a given level
101   */
102  public List<String> logs(LoggerLevel level) {
103    return ((ListInterceptor) LogInterceptors.get()).logs(level);
104  }
105
106  public LogTester clear() {
107    ((ListInterceptor) LogInterceptors.get()).clear();
108    return this;
109  }
110}