org.apache.drill.test.DrillTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.drill.test.DrillTest.java

Source

/*
 * 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.io.PrintStream;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.List;

import org.apache.commons.io.output.NullOutputStream;
import org.apache.drill.common.util.DrillStringUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.DisableOnDebug;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.slf4j.Logger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DrillTest {

    protected static final ObjectMapper objectMapper;
    static {
        System.setProperty("line.separator", "\n");
        objectMapper = new ObjectMapper();
    }

    static final SystemManager manager = new SystemManager();

    static final Logger testReporter = org.slf4j.LoggerFactory.getLogger("org.apache.drill.TestReporter");
    static final TestLogReporter LOG_OUTCOME = new TestLogReporter();

    static MemWatcher memWatcher;
    static String className;

    @Rule
    public final TestRule TIMEOUT = new DisableOnDebug(TestTools.getTimeoutRule(100_000));
    @Rule
    public final TestLogReporter logOutcome = LOG_OUTCOME;

    @Rule
    public final TestRule REPEAT_RULE = TestTools.getRepeatRule(false);

    /**
     * Rule for tests that verify {@link org.apache.drill.common.exceptions.UserException} type and message. See
     * {@link UserExceptionMatcher} and e.g. apache.drill.exec.server.TestOptions#checkValidationException.
     * Tests that do not use this rule are not affected.
     */
    @Rule
    public final ExpectedException thrownException = ExpectedException.none();

    @Rule
    public TestName TEST_NAME = new TestName();

    /**
     * Option to cause tests to produce verbose output. Many tests provide
     * detailed information to stdout when enabled. To enable:
     * <p>
     * <tt>java ... -Dtest.verbose=true ...</tt>
     */
    public static final String VERBOSE_OUTPUT = "test.verbose";

    protected static final boolean verbose = Boolean.parseBoolean(System.getProperty(VERBOSE_OUTPUT));

    /**
     * Output destination for verbose test output. Rather than using
     * <tt>System.out</tt>, use <tt>DrillTest.out</tt>. Output will
     * automagically be routed to the bit bucket unless the
     * {@link #VERBOSE_OUTPUT} flag is set.
     */

    public static final PrintStream out = verbose ? System.out : new PrintStream(new NullOutputStream());

    @Before
    public void printID() throws Exception {
        System.out.printf("Running %s#%s\n", getClass().getName(), TEST_NAME.getMethodName());
    }

    @BeforeClass
    public static void initDrillTest() throws Exception {
        memWatcher = new MemWatcher();
    }

    @AfterClass
    public static void finiDrillTest() throws InterruptedException {
        testReporter.info(String.format("Test Class done (%s): %s.", memWatcher.getMemString(true), className));
        // Clear interrupts for next test
        Thread.interrupted();
    }

    protected static class MemWatcher {
        private long startDirect;
        private long startHeap;
        private long startNonHeap;

        public MemWatcher() {
            startDirect = manager.getMemDirect();
            startHeap = manager.getMemHeap();
            startNonHeap = manager.getMemNonHeap();
        }

        public Object getMemString() {
            return getMemString(false);
        }

        public String getMemString(boolean runGC) {
            if (runGC) {
                Runtime.getRuntime().gc();
            }
            long endDirect = manager.getMemDirect();
            long endHeap = manager.getMemHeap();
            long endNonHeap = manager.getMemNonHeap();
            return String.format("d: %s(%s), h: %s(%s), nh: %s(%s)", //
                    DrillStringUtils.readable(endDirect - startDirect), DrillStringUtils.readable(endDirect), //
                    DrillStringUtils.readable(endHeap - startHeap), DrillStringUtils.readable(endHeap), //
                    DrillStringUtils.readable(endNonHeap - startNonHeap), DrillStringUtils.readable(endNonHeap) //
            );
        }
    }

    private static class TestLogReporter extends TestWatcher {
        private MemWatcher memWatcher;

        @Override
        protected void starting(Description description) {
            super.starting(description);
            className = description.getClassName();
            memWatcher = new MemWatcher();
        }

        @Override
        protected void failed(Throwable e, Description description) {
            testReporter.error(
                    String.format("Test Failed (%s): %s", memWatcher.getMemString(), description.getDisplayName()),
                    e);
        }

        @Override
        public void succeeded(Description description) {
            testReporter.info(String.format("Test Succeeded (%s): %s", memWatcher.getMemString(),
                    description.getDisplayName()));
        }
    }

    public static String escapeJsonString(String original) {
        try {
            return objectMapper.writeValueAsString(original);
        } catch (JsonProcessingException e) {
            return original;
        }
    }

    private static class SystemManager {

        final BufferPoolMXBean directBean;
        final MemoryMXBean memoryBean;

        public SystemManager() {
            memoryBean = ManagementFactory.getMemoryMXBean();
            BufferPoolMXBean localBean = null;
            List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
            for (BufferPoolMXBean b : pools) {
                if (b.getName().equals("direct")) {
                    localBean = b;

                }
            }
            directBean = localBean;
        }

        public long getMemDirect() {
            return directBean.getMemoryUsed();
        }

        public long getMemHeap() {
            return memoryBean.getHeapMemoryUsage().getUsed();
        }

        public long getMemNonHeap() {
            return memoryBean.getNonHeapMemoryUsage().getUsed();
        }
    }

    /**
     * Reports whether verbose output has been selected for this test run.
     *
     * @return <tt>true</tt> if verbose output is wanted (test is likely running
     * in a debugger), <tt>false</tt> if verbose output is to be suppressed
     * (test is likely running in a batch Maven build).
     */

    public static boolean verbose() {
        return verbose;
    }
}