org.hibernate.search.test.performance.scenario.TestReporter.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.search.test.performance.scenario.TestReporter.java

Source

/*
 * Hibernate Search, full-text search for your domain model
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.search.test.performance.scenario;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DurationFormatUtils;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.search.engine.Version;
import org.hibernate.search.test.performance.task.AbstractTask;
import org.hibernate.search.test.performance.util.CheckerLuceneIndex;
import org.hibernate.search.test.performance.util.CheckerUncaughtExceptions;
import org.hibernate.search.test.performance.util.TargetDirHelper;
import org.hibernate.search.testsupport.TestConstants;

import static org.apache.commons.lang.StringUtils.leftPad;
import static org.apache.commons.lang.StringUtils.rightPad;
import static org.hibernate.search.test.performance.TestRunnerArquillian.RUNNER_PROPERTIES;
import static org.hibernate.search.test.performance.TestRunnerArquillian.TARGET_DIR_KEY;
import static org.hibernate.search.test.performance.scenario.TestContext.ASSERT_QUERY_RESULTS;
import static org.hibernate.search.test.performance.scenario.TestContext.CHECK_INDEX_STATE;
import static org.hibernate.search.test.performance.scenario.TestContext.MEASURE_MEMORY;
import static org.hibernate.search.test.performance.scenario.TestContext.MEASURE_TASK_TIME;
import static org.hibernate.search.test.performance.scenario.TestContext.THREADS_COUNT;
import static org.hibernate.search.test.performance.scenario.TestContext.VERBOSE;
import static org.hibernate.search.test.performance.util.Util.runGarbageCollectorAndWait;

/**
 * @author Tomas Hradec
 */
public class TestReporter {

    private TestReporter() {
    }

    public static void printReport(TestContext ctx) throws UnsupportedEncodingException, IOException {
        PrintStream outStream = createOutputStream(ctx.scenario.getClass().getSimpleName());
        PrintWriter outWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outStream, "UTF-8")),
                false);

        outWriter.println("==================================================================");
        outWriter.println("HIBERNATE SEARCH PERFORMANCE TEST REPORT");
        printSummary(ctx, outWriter);
        printTaskInfo(ctx, outWriter);
        printEnvInfo(ctx, outWriter);
        outWriter.println("==================================================================");
        outWriter.flush();

        CheckerLuceneIndex.printIndexReport(ctx, outStream);
        CheckerUncaughtExceptions.printUncaughtExceptions(ctx, outWriter);

        outWriter.close();
        outStream.close();
    }

    private static void printSummary(TestContext ctx, PrintWriter out) {
        long freeMemory2 = -1;
        long totalMemory2 = -1;
        if (MEASURE_MEMORY) {
            runGarbageCollectorAndWait();
            freeMemory2 = Runtime.getRuntime().freeMemory();
            totalMemory2 = Runtime.getRuntime().totalMemory();
        }

        long totalNanos = ctx.stopTime - ctx.startTime;
        long totalMilis = TimeUnit.MILLISECONDS.convert(totalNanos, TimeUnit.NANOSECONDS);

        out.println("");
        out.println("SUMMARY");
        out.println("    Name   : " + ctx.scenario.getClass().getSimpleName());
        out.println("    Date   : " + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm"));
        out.println("");
        out.println("    Measured time (HH:mm:ss.SSS)");
        out.println("        MEASURED TASKS : " + DurationFormatUtils.formatDuration(totalMilis, "HH:mm:ss.SSS"));
        out.println("        init database  : "
                + DurationFormatUtils.formatDuration(ctx.scenario.initDatabaseStopWatch.getTime(), "HH:mm:ss.SSS"));
        out.println("        init index     : "
                + DurationFormatUtils.formatDuration(ctx.scenario.initIndexStopWatch.getTime(), "HH:mm:ss.SSS"));
        out.println("        warmup phase   : "
                + DurationFormatUtils.formatDuration(ctx.scenario.warmupStopWatch.getTime(), "HH:mm:ss.SSS"));

        if (MEASURE_MEMORY) {
            out.println("");
            out.println("    Memory usage (total-free):");
            out.println("        before : " + toMB(ctx.totalMemory - ctx.freeMemory));
            out.println("        after  : " + toMB(totalMemory2 - freeMemory2));
        }
    }

    private static void printTaskInfo(TestContext ctx, PrintWriter out) {
        out.println("");
        out.println("TASKS");
        for (AbstractTask task : ctx.tasks) {
            String taskTotalTime = "n/a";
            String taskAverageTime = "n/a";
            if (MEASURE_TASK_TIME) {
                long taskTotalMilis = TimeUnit.MILLISECONDS.convert(task.getTimerValue(), TimeUnit.NANOSECONDS);
                long taskAverageMilis = taskTotalMilis / task.getCounterValue();
                taskTotalTime = DurationFormatUtils.formatDuration(taskTotalMilis, "mm:ss.SSS");
                taskAverageTime = DurationFormatUtils.formatDuration(taskAverageMilis, "mm:ss.SSS");
            }
            out.println("    " + leftPad(task.getCounterValue() + "x ", 5)
                    + rightPad(task.getClass().getSimpleName(), 35) + " | sum " + taskTotalTime + " | avg "
                    + taskAverageTime);
        }
    }

    private static void printEnvInfo(TestContext ctx, PrintWriter out) {
        out.println("");
        out.println("TEST CONFIGURATION");
        out.println("    measure performance : " + TestConstants.arePerformanceTestsEnabled());
        out.println("    threads             : " + THREADS_COUNT);
        out.println("    measured cycles     : " + ctx.scenario.measuredCyclesCount);
        out.println("    warmup cycles       : " + ctx.scenario.warmupCyclesCount);
        out.println("    initial book count  : " + ctx.scenario.initialBookCount);
        out.println("    initial autor count : " + ctx.scenario.initialAutorCount);
        out.println("    verbose             : " + VERBOSE);
        out.println("    measure memory      : " + MEASURE_MEMORY);
        out.println("    measure task time   : " + MEASURE_TASK_TIME);
        out.println("    check query results : " + ASSERT_QUERY_RESULTS);
        out.println("    check index state   : " + CHECK_INDEX_STATE);

        out.println("");
        out.println("HIBERNATE SEARCH PROPERTIES");
        Properties properties = ((SessionFactoryImplementor) ctx.sf).getProperties();
        for (Entry<Object, Object> e : properties.entrySet()) {
            if (e.getKey().toString().startsWith("hibernate.search")) {
                out.println("    " + e.getKey() + " = " + e.getValue());
            }
        }

        out.println("");
        out.println("VERSIONS");
        out.println("    org.hibernate.search : " + Version.getVersionString());
        out.println("    org.hibernate        : " + org.hibernate.Version.getVersionString());
        out.println("");
    }

    private static String toMB(long bytes) {
        long megabytes = bytes / 1000 / 1000;
        return megabytes + "MB";
    }

    private static PrintStream createOutputStream(String testScenarioName) {
        try {
            Path targetDir = getTargetDir();
            String reportFileName = "report-" + testScenarioName + "-"
                    + DateFormatUtils.format(new Date(), "yyyy-MM-dd-HH'h'mm'm'") + ".txt";
            Path reportFile = targetDir.resolve(reportFileName);

            final OutputStream std = System.out;
            final OutputStream file = new PrintStream(new FileOutputStream(reportFile.toFile()), true, "UTF-8");
            final OutputStream stream = new OutputStream() {

                @Override
                public void write(int b) throws IOException {
                    std.write(b);
                    file.write(b);
                }

                @Override
                public void flush() throws IOException {
                    std.flush();
                    file.flush();
                }

                @Override
                public void close() throws IOException {
                    file.close();
                }
            };
            return new PrintStream(stream, false, "UTF-8");
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    private static Path getTargetDir() {
        InputStream runnerPropertiesStream = TestReporter.class.getResourceAsStream("/" + RUNNER_PROPERTIES);
        if (runnerPropertiesStream != null) {
            Properties runnerProperties = new Properties();
            try {
                runnerProperties.load(runnerPropertiesStream);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return Paths.get(runnerProperties.getProperty(TARGET_DIR_KEY));
        } else {
            return TargetDirHelper.getTargetDir();
        }
    }

}