Java tutorial
/* * 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(); } } }