/* * Copyright (C) 2011 Google Inc. * * Licensed 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 com.google.caliper.runner; import static com.google.common.collect.ObjectArrays.concat; import com.google.caliper.config.InvalidConfigurationException; import com.google.caliper.options.CaliperOptions; import com.google.caliper.options.OptionsModule; import com.google.caliper.util.InvalidCommandException; import com.google.caliper.util.OutputModule; import com.google.common.base.Strings; import com.google.common.collect.ImmutableSortedMap; import com.google.common.util.concurrent.ServiceManager; import java.io.PrintWriter; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.annotation.Nullable; /** * Primary entry point for the caliper benchmark runner application; run with {@code --help} for * details. This class's only purpose is to take care of anything that's specific to command-line * invocation and then hand off to {@code CaliperRun}. That is, a hypothetical GUI benchmark runner * might still use {@code CaliperRun} but would skip using this class. */ public final class CaliperMain { /** * Your benchmark classes can implement main() like this:
   {@code
   *
   *   public static void main(String[] args) {
   *     CaliperMain.main(MyBenchmark.class, args);
   *   }}
* * Note that this method does invoke {@link System#exit} when it finishes. Consider {@link * #exitlessMain} if you don't want that. * *

Measurement is handled in a subprocess, so it will not use {@code benchmarkClass} itself; * the class is provided here only as a shortcut for specifying the full class name. The * class that gets loaded later could be completely different. */ public static void main(Class benchmarkClass, String[] args) { main(concat(args, benchmarkClass.getName())); } /** * Entry point for the caliper benchmark runner application; run with {@code --help} for details. */ public static void main(String[] args) { PrintWriter stdout = new PrintWriter(System.out, true); PrintWriter stderr = new PrintWriter(System.err, true); int code = 1; // pessimism! try { exitlessMain(args, stdout, stderr); code = 0; } catch (InvalidCommandException e) { e.display(stderr); code = e.exitCode(); } catch (InvalidBenchmarkException e) { e.display(stderr); } catch (InvalidConfigurationException e) { e.display(stderr); } catch (Throwable t) { t.printStackTrace(stderr); stdout.println(); stdout.println("An unexpected exception has been thrown by the caliper runner."); stdout.println("Please see https://sites.google.com/site/caliperusers/issues"); } stdout.flush(); stderr.flush(); System.exit(code); } private static final String LEGACY_ENV = "USE_LEGACY_CALIPER"; public static void exitlessMain(String[] args, PrintWriter stdout, PrintWriter stderr) throws InvalidCommandException, InvalidBenchmarkException, InvalidConfigurationException { @Nullable String legacyCaliperEnv = System.getenv(LEGACY_ENV); if (!Strings.isNullOrEmpty(legacyCaliperEnv)) { System.err.println("Legacy Caliper is no more. " + LEGACY_ENV + " has no effect."); } try { MainComponent mainComponent = DaggerMainComponent.builder() .optionsModule(OptionsModule.withBenchmarkClass(args)) .outputModule(new OutputModule(stdout, stderr)) .build(); CaliperOptions options = mainComponent.getCaliperOptions(); if (options.printConfiguration()) { stdout.println("Configuration:"); ImmutableSortedMap sortedProperties = ImmutableSortedMap.copyOf(mainComponent.getCaliperConfig().properties()); for (Entry entry : sortedProperties.entrySet()) { stdout.printf(" %s = %s%n", entry.getKey(), entry.getValue()); } } // check that the parameters are valid mainComponent.getBenchmarkClass().validateParameters(options.userParameters()); ServiceManager serviceManager = mainComponent.getServiceManager(); serviceManager.startAsync().awaitHealthy(); try { CaliperRun run = mainComponent.getCaliperRun(); run.run(); // throws IBE } finally { try { // We have some shutdown logic to ensure that files are cleaned up so give it a chance to // run serviceManager.stopAsync().awaitStopped(10, TimeUnit.SECONDS); } catch (TimeoutException e) { // That's fine } } } finally { // courtesy flush stderr.flush(); stdout.flush(); } } }