Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2013 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 static com.google.common.base.Preconditions.checkArgument;
     20 
     21 import com.google.caliper.Benchmark;
     22 import com.google.caliper.util.Util;
     23 
     24 import java.lang.reflect.Method;
     25 import java.util.Arrays;
     26 
     27 /**
     28  * Utilities for working with methods annotated by {@link Benchmark}.
     29  */
     30 final class BenchmarkMethods {
     31   private static final Class<?>[] MACROBENCHMARK_PARAMS = new Class<?>[] {};
     32   private static final Class<?>[] MICROBENCHMARK_PARAMS = new Class<?>[] {int.class};
     33   private static final Class<?>[] PICOBENCHMARK_PARAMS = new Class<?>[] {long.class};
     34 
     35   private BenchmarkMethods() {}
     36 
     37   enum Type {
     38     MACRO,
     39     MICRO,
     40     PICO;
     41 
     42     static Type of(Method benchmarkMethod) {
     43       Class<?>[] parameterTypes = benchmarkMethod.getParameterTypes();
     44       if (Arrays.equals(parameterTypes, MACROBENCHMARK_PARAMS)) {
     45         return MACRO;
     46       } else if (Arrays.equals(parameterTypes, MICROBENCHMARK_PARAMS)) {
     47         return MICRO;
     48       } else if (Arrays.equals(parameterTypes, PICOBENCHMARK_PARAMS)) {
     49         return PICO;
     50       } else {
     51         throw new IllegalArgumentException("invalid method parameters: " + benchmarkMethod);
     52       }
     53     }
     54   }
     55 
     56   /**
     57    * Several instruments look for benchmark methods like {@code timeBlah(int reps)}; this is the
     58    * centralized code that identifies such methods.
     59    *
     60    * <p>This method does not check the correctness of the argument types.
     61    */
     62   static boolean isTimeMethod(Method method) {
     63     return method.getName().startsWith("time") && Util.isPublic(method);
     64   }
     65 
     66   /**
     67    * For instruments that use {@link #isTimeMethod} to identify their methods, this method checks
     68    * the {@link Method} appropriately.
     69    */
     70   static Method checkTimeMethod(Method timeMethod) throws InvalidBenchmarkException {
     71     checkArgument(isTimeMethod(timeMethod));
     72     Class<?>[] parameterTypes = timeMethod.getParameterTypes();
     73     if (!Arrays.equals(parameterTypes, new Class<?>[] {int.class})
     74         && !Arrays.equals(parameterTypes, new Class<?>[] {long.class})) {
     75       throw new InvalidBenchmarkException(
     76           "Microbenchmark methods must accept a single int parameter: " + timeMethod.getName());
     77     }
     78 
     79     // Static technically doesn't hurt anything, but it's just the completely wrong idea
     80     if (Util.isStatic(timeMethod)) {
     81       throw new InvalidBenchmarkException(
     82           "Microbenchmark methods must not be static: " + timeMethod.getName());
     83     }
     84     return timeMethod;
     85   }
     86 }
     87