Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2015 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.caliper.runner;
     18 
     19 import com.google.caliper.config.ConfigModule;
     20 import com.google.caliper.options.OptionsModule;
     21 import com.google.caliper.util.OutputModule;
     22 import com.google.common.collect.ImmutableSet;
     23 
     24 import dagger.Component;
     25 
     26 import java.io.PrintWriter;
     27 import java.lang.reflect.Method;
     28 import java.util.List;
     29 
     30 import javax.inject.Singleton;
     31 
     32 /**
     33  * Determines whether a class contains one or more benchmarks or not.
     34  *
     35  * <p>Useful for tools that need to check whether a class contains benchmarks before running them
     36  * by calling an appropriate method on {@link CaliperMain}.
     37  */
     38 // This should be considered part of the public API alongside {@link CaliperMain}.
     39 public final class BenchmarkClassChecker {
     40 
     41   /**
     42    * Create a new instance of {@link BenchmarkClassChecker}.
     43    *
     44    * @param arguments a list of command line arguments for Caliper, can include any of the
     45    *     options supported by Caliper.
     46    * @return a new instance of {@link BenchmarkClassChecker}.
     47    */
     48   public static BenchmarkClassChecker create(List<String> arguments) {
     49     return new BenchmarkClassChecker(arguments);
     50   }
     51 
     52   /**
     53    * The set of {@link Instrument instruments} that are used to determine whether a class has any
     54    * methods suitable for benchmarking.
     55    */
     56   private final ImmutableSet<Instrument> instruments;
     57 
     58   private BenchmarkClassChecker(List<String> arguments) {
     59     String[] args = arguments.toArray(new String[arguments.size()]);
     60     InstrumentProvider instrumentProvider = DaggerBenchmarkClassChecker_InstrumentProvider.builder()
     61         .optionsModule(OptionsModule.withoutBenchmarkClass(args))
     62         .outputModule(new OutputModule(new PrintWriter(System.out), new PrintWriter(System.err)))
     63         .build();
     64 
     65     instruments = instrumentProvider.instruments();
     66   }
     67 
     68   /**
     69    * Check to see whether the supplied class contains at least one benchmark method that can be run
     70    * by caliper.
     71    *
     72    * @param theClass the class that may contain one or more benchmark methods.
     73    * @return true if the class does contain a benchmark method, false otherwise.
     74    */
     75   public boolean isBenchmark(Class<?> theClass) {
     76     for (Method method : theClass.getDeclaredMethods()) {
     77       for (Instrument instrument : instruments) {
     78         if (instrument.isBenchmarkMethod(method)) {
     79           return true;
     80         }
     81       }
     82     }
     83 
     84     return false;
     85   }
     86 
     87   @Singleton
     88   @Component(modules = {
     89       ConfigModule.class,
     90       ExperimentingRunnerModule.class,
     91       OptionsModule.class,
     92       OutputModule.class,
     93       PlatformModule.class,
     94       RunnerModule.class,
     95   })
     96   /**
     97    * Provides the set of supported {@link Instrument instruments}.
     98    */
     99   interface InstrumentProvider {
    100     ImmutableSet<Instrument> instruments();
    101   }
    102 }
    103