View Javadoc

1   /**
2    * Copyright (c) 2012, University of Konstanz, Distributed Systems Group
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    * * Redistributions of source code must retain the above copyright
8    * notice, this list of conditions and the following disclaimer.
9    * * Redistributions in binary form must reproduce the above copyright
10   * notice, this list of conditions and the following disclaimer in the
11   * documentation and/or other materials provided with the distribution.
12   * * Neither the name of the University of Konstanz nor the
13   * names of its contributors may be used to endorse or promote products
14   * derived from this software without specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package org.perfidix;
28  
29  import org.perfidix.AbstractConfig.StandardConfig;
30  import org.perfidix.ouput.TabularSummaryOutput;
31  import org.perfidix.result.BenchmarkResult;
32  
33  /**
34   * This is the main class, consisting of all the factory methods needed in order
35   * to perform a benchmark run. Instead of running the bench with a {@link Benchmark} instance, this class just
36   * takes all classes as a String and
37   * gives less control over the Benchmark itself. The Classes to be given are
38   * either Benchmark-Classes or (one single) Config-Class. Additionaly, this
39   * class holds multiple utility-methods to get Bench-Classes and Config out of a
40   * set of Strings.
41   * <p>
42   * 
43   * <pre>
44   * 
45   * public class MyBenchmark {
46   * 
47   *     public static void main(final String[] args) {
48   *         final String classNames = {
49   *             &quot;Class1&quot;, &quot;Class2&quot;, &quot;Class3&quot;, &quot;MyConfig1&quot;
50   *         };
51   * 
52   *         // either...
53   *         final BenchmarkResult result = Perfidix.runBenchs(classNames);
54   *         new TabularSummaryOutput.visitBenchmark(result);
55   * 
56   *         // ...or...
57   *         Perfidix.main(classNames);
58   *     }
59   * }
60   * 
61   * </pre>
62   * 
63   * </p>
64   * 
65   * @see AbstractConfig
66   * @see BenchmarkResult
67   * @author Sebastian Graf, University of Konstanz
68   */
69  public final class Perfidix {
70  
71      /**
72       * private constructor.
73       */
74      private Perfidix() {
75      }
76  
77      /**
78       * Running one Benchmark.
79       * 
80       * @param benchs
81       *            to be inserted
82       * @return one {@link BenchmarkResult} object with the results
83       * @throws ClassNotFoundException
84       *             if class cannot be found
85       * @throws IllegalAccessException
86       *             if conf cannot be instantiated
87       * @throws InstantiationException
88       *             if conf cannot be instantiated
89       */
90      public static BenchmarkResult runBenchs(final String[] benchs) throws ClassNotFoundException,
91          InstantiationException, IllegalAccessException {
92          final AbstractConfig conf = getConfiguration(benchs);
93  
94          final Benchmark bench = new Benchmark(conf);
95          return setUpBenchmark(benchs, bench).run();
96      }
97  
98      /**
99       * Setting up an existing benchmark with the given number of class-files
100      * 
101      * @param classes
102      *            to be benched
103      * @param benchmark
104      *            to be set up
105      * @return the same {@link Benchmark} object with the classes
106      * @throws ClassNotFoundException
107      *             thrown if class was not found.
108      */
109     public static Benchmark setUpBenchmark(final String[] classes, final Benchmark benchmark)
110         throws ClassNotFoundException {
111         for (final String each : classes) {
112             benchmark.add(Class.forName(each));
113         }
114         return benchmark;
115     }
116 
117     /**
118      * Getting a configuration out of the class-files. If none is avaliable, the {@link StandardConfig} is
119      * given back. The {@link AbstractConfig} instance
120      * has to have a parameter-free constructor.
121      * 
122      * @param classes
123      *            to be examined. Only one instance of an {@link AbstractConfig} is allowed.
124      * @return the {@link AbstractConfig} instance or the {@link StandardConfig} if none was found.
125      * @throws ClassNotFoundException
126      *             thrown if a class was not found.
127      * @throws InstantiationException
128      *             thrown if the {@link AbstractConfig} instance was not able to
129      *             be instaniated
130      * @throws IllegalAccessException
131      *             thrown if the {@link AbstractConfig} instance was not able to
132      *             be instaniated
133      */
134     public static AbstractConfig getConfiguration(final String[] classes) throws ClassNotFoundException,
135         InstantiationException, IllegalAccessException {
136         AbstractConfig conf = null;
137         for (String each : classes) {
138             final Class<?> clazz = Class.forName(each);
139             final Class<?> superclazz = clazz.getSuperclass();
140             if (superclazz.equals(AbstractConfig.class)) {
141                 if (conf == null) {
142                     conf = (AbstractConfig)clazz.newInstance();
143                 } else {
144                     throw new IllegalArgumentException("Only one config-class allowed");
145                 }
146             }
147         }
148         if (conf == null) {
149             conf = new StandardConfig();
150         }
151         return conf;
152     }
153 
154     /**
155      * Main method for invoking benchs with classes as strings.
156      * 
157      * @param args
158      *            the classes
159      * @throws ClassNotFoundException
160      *             if class cannot be found
161      * @throws IllegalAccessException
162      *             if conf cannot be instantiated
163      * @throws InstantiationException
164      *             if conf cannot be instantiated
165      */
166     public static void main(final String[] args) throws ClassNotFoundException, InstantiationException,
167         IllegalAccessException {
168         final BenchmarkResult res = runBenchs(args);
169         new TabularSummaryOutput().visitBenchmark(res);
170     }
171 }