[ 
https://issues.apache.org/jira/browse/DRILL-5126?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15830399#comment-15830399
 ] 

ASF GitHub Bot commented on DRILL-5126:
---------------------------------------

Github user paul-rogers commented on a diff in the pull request:

    https://github.com/apache/drill/pull/710#discussion_r96924435
  
    --- Diff: 
exec/java-exec/src/test/java/org/apache/drill/test/LogFixture.java ---
    @@ -0,0 +1,255 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + * http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.drill.test;
    +
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import org.slf4j.LoggerFactory;
    +
    +import ch.qos.logback.classic.Level;
    +import ch.qos.logback.classic.Logger;
    +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.ConsoleAppender;
    +
    +/**
    + * Establishes test-specific logging without having to alter the global
    + * <tt>logback-test.xml</tt> file. Allows directing output to the console
    + * (if not already configured) and setting the log level on specific 
loggers
    + * of interest in the test. The fixture automatically restores the original
    + * log configuration on exit.
    + * <p>
    + * Typical usage: <pre><code>
    + * {@literal @}Test
    + * public void myTest() {
    + *   LogFixtureBuilder logBuilder = LogFixture.builder()
    + *          .toConsole()
    + *          .disable() // Silence all other loggers
    + *          .logger(ExternalSortBatch.class, Level.DEBUG);
    + *   try (LogFixture logs = logBuilder.build()) {
    + *     // Test code here
    + *   }
    + * }</code></pre>
    + *  <p>
    + * You can &ndash; and should &ndash; combine the log fixtue with the
    + * cluster and client fixtures to have complete control over your test-time
    + * Drill environment.
    + */
    +
    +public class LogFixture implements AutoCloseable {
    +
    +  // Elapsed time in ms, log level, thread, logger, message.
    +
    +  public static final String DEFAULT_CONSOLE_FORMAT = "%r %level [%thread] 
[%logger] - %msg%n";
    +  private static final String DRILL_PACKAGE_NAME = "org.apache.drill";
    +
    +  /**
    +   * Memento for a logger name and level.
    +   */
    +  public static class LogSpec {
    +    String loggerName;
    +    Level logLevel;
    +
    +    public LogSpec(String loggerName, Level level) {
    +      this.loggerName = loggerName;
    +      this.logLevel = level;
    +    }
    +  }
    +
    +  /**
    +   * Builds the log settings to be used for a test. The log settings here
    +   * add to those specified in a <tt>logback.xml</tt> or
    +   * <tt>logback-test.xml</tt> file on your class path. In particular, if
    +   * the logging configuration already redirects the Drill logger to the
    +   * console, setting console logging here does nothing.
    +   */
    +
    +  public static class LogFixtureBuilder {
    +
    +    private String consoleFormat = DEFAULT_CONSOLE_FORMAT;
    +    private boolean logToConsole;
    +    private List<LogSpec> loggers = new ArrayList<>();
    +
    +    /**
    +     * Send all enabled logging to the console (if not already 
configured.) Some
    +     * Drill log configuration files send the root to the console (or 
file), but
    +     * the Drill loggers to Lilith. In that case, Lilith "hides" the 
console
    +     * logger. Using this call adds a console logger to the Drill logger 
so that
    +     * output does, in fact, go to the console regardless of the 
configuration
    +     * in the Logback configuration file.
    +     *
    +     * @return this builder
    +     */
    +    public LogFixtureBuilder toConsole() {
    +      logToConsole = true;
    +      return this;
    +    }
    +
    +    /**
    +     * Send logging to the console using the defined format.
    +     *
    +     * @param format valid Logback log format
    +     * @return this builder
    +     */
    +
    +    public LogFixtureBuilder toConsole(String format) {
    +      consoleFormat = format;
    +      return toConsole();
    +    }
    +
    +    /**
    +     * Set a specific logger to the given level.
    +     *
    +     * @param loggerName name of the logger (typically used for 
package-level
    +     * loggers)
    +     * @param level the desired Logback-defined level
    +     * @return this builder
    +     */
    +    public LogFixtureBuilder logger(String loggerName, Level level) {
    +      loggers.add(new LogSpec(loggerName, level));
    +      return this;
    +    }
    +
    +    /**
    +     * Set a specific logger to the given level.
    +     *
    +     * @param loggerClass class that defines the logger (typically used for
    +     * class-specific loggers)
    +     * @param level the desired Logback-defined level
    +     * @return this builder
    +     */
    +    public LogFixtureBuilder logger(Class<?> loggerClass, Level level) {
    +      loggers.add(new LogSpec(loggerClass.getName(), level));
    +      return this;
    +    }
    +
    +    /**
    +     * Turns off all logging. If called first, you can set disable as your
    +     * general policy, then turn back on loggers selectively for those
    +     * of interest.
    +     * @return this builder
    +     */
    +    public LogFixtureBuilder disable() {
    +      return rootLogger(Level.OFF);
    +    }
    +
    +    /**
    +     * Set the desired log level on the root logger.
    +     * @param level the desired Logback log level
    +     * @return this builder
    +     */
    +
    +    public LogFixtureBuilder rootLogger(Level level) {
    +      loggers.add(new LogSpec(Logger.ROOT_LOGGER_NAME, level));
    +      return this;
    +    }
    +
    +    /**
    +     * Apply the log levels and output, then return a fixture to be used
    +     * in a try-with-resources block. The fixture automatically restores
    +     * the original configuration on completion of the try block.
    +     * @return the log fixture
    +     */
    +    public LogFixture build() {
    +      return new LogFixture(this);
    +    }
    +  }
    +
    +  private PatternLayoutEncoder ple;
    +  private ConsoleAppender<ILoggingEvent> appender;
    +  private List<LogSpec> loggers = new ArrayList<>();
    +  private Logger drillLogger;
    +
    +  public LogFixture(LogFixtureBuilder builder) {
    +    if (builder.logToConsole) {
    +      setupConsole(builder);
    +    }
    +    setupLoggers(builder);
    +  }
    +
    +  /**
    +   * Creates a new log fixture builder.
    +   * @return the log fixture builder
    +   */
    +
    +  public static LogFixtureBuilder builder() {
    +    return new LogFixtureBuilder();
    +  }
    +
    +  private void setupConsole(LogFixtureBuilder builder) {
    +    Logger drillLogger = 
(Logger)LoggerFactory.getLogger(DRILL_PACKAGE_NAME);
    +    if (drillLogger.getAppender("STDOUT") != null) {
    +      return;
    +    }
    +    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    +    ple = new PatternLayoutEncoder();
    +    ple.setPattern(builder.consoleFormat);
    +    ple.setContext(lc);
    +    ple.start();
    +
    +    appender = new ConsoleAppender<>( );
    +    appender.setContext(lc);
    +    appender.setName("Console");
    +    appender.setEncoder( ple );
    +    appender.start();
    +
    +    Logger root = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    --- End diff --
    
    As I understand the semantics, each logger can have multiple appenders. We 
add ours to any that exist. When we remove ours, we only remove that one, not 
any others that might be registered. Of course, I still might be missing 
something...


> Provide simplified, unified "cluster fixture" for tests
> -------------------------------------------------------
>
>                 Key: DRILL-5126
>                 URL: https://issues.apache.org/jira/browse/DRILL-5126
>             Project: Apache Drill
>          Issue Type: Improvement
>          Components: Tools, Build & Test
>    Affects Versions: 1.9.0
>            Reporter: Paul Rogers
>            Assignee: Paul Rogers
>            Priority: Minor
>
> Drill provides a robust selection of test frameworks that have evolved to 
> satisfy the needs of a variety of test cases. For newbies, however, the 
> result is a bewildering array of ways to do basically the same thing: set up 
> an embedded Drill cluster, run queries and check results.
> Further, some key test settings are distributed: some are in the pom.xml 
> file, some in config files stored as resources, some in hard-coded settings 
> in base test classes.
> Also, some test base classes helpfully set up a test cluster, but then 
> individual tests need a different config, so they immediately tear down the 
> default cluster and create a new one.
> This ticket proposes a new test framework, available for new tests, that 
> combines the best of the existing test frameworks into a single, easy-to-use 
> package.
> * Builder for the cluster
> * Accept config-time options
> * Accept run-time session and system options
> * Specify number of Drillbits
> * Simplified API for the most common options
> * AutoCloseable for use in try-with-resources statements
> * Integration with existing test builder classes
> And so on.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to