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.element;
28  
29  import static org.junit.Assert.assertEquals;
30  import static org.junit.Assert.assertFalse;
31  import static org.junit.Assert.assertNotNull;
32  import static org.junit.Assert.assertNull;
33  import static org.junit.Assert.fail;
34  
35  import java.lang.reflect.Method;
36  import java.util.HashSet;
37  import java.util.Iterator;
38  import java.util.Set;
39  
40  import org.junit.Before;
41  import org.junit.Test;
42  import org.perfidix.AbstractConfig;
43  import org.perfidix.annotation.AfterEachRun;
44  import org.perfidix.annotation.AfterLastRun;
45  import org.perfidix.annotation.BeforeEachRun;
46  import org.perfidix.annotation.BeforeFirstRun;
47  import org.perfidix.annotation.Bench;
48  import org.perfidix.annotation.SkipBench;
49  import org.perfidix.exceptions.PerfidixMethodCheckException;
50  import org.perfidix.exceptions.PerfidixMethodInvocationException;
51  import org.perfidix.meter.AbstractMeter;
52  import org.perfidix.meter.CountingMeter;
53  import org.perfidix.meter.Time;
54  import org.perfidix.meter.TimeMeter;
55  import org.perfidix.result.BenchmarkResult;
56  import org.perfidix.result.ClassResult;
57  import org.perfidix.result.MethodResult;
58  
59  /**
60   * Test case for the BenchmarkExecutor. Note that all classes used in this
61   * testcase are not allowed to be internal classes because of the reflective
62   * invocation. This is not working with encapsulated classes.
63   * 
64   * @author Sebastian Graf, University of Konstanz
65   */
66  public class BenchmarkExecutorTest {
67  
68      /** Method name to test */
69      private final static String METHODNAME = "bench";
70  
71      private transient Set<AbstractMeter> meter;
72      /** static int to check the beforefirstcounter */
73      public static int once;
74      /** static int to check the beforeeachcounter */
75      public static int each;
76  
77      private transient BenchmarkResult res;
78  
79      /**
80       * Simple SetUp.
81       */
82      @Before
83      public void setUp() {
84          res = new BenchmarkResult();
85          meter = new HashSet<AbstractMeter>();
86          meter.add(new TimeMeter(Time.MilliSeconds));
87          meter.add(new CountingMeter());
88  
89          once = 0;
90          each = 0;
91          BenchmarkExecutor.initialize(new CheckConfig(meter), res);
92      }
93  
94      /**
95       * Test method for
96       * {@link org.perfidix.element.BenchmarkExecutor#getExecutor(org.perfidix.element.BenchmarkElement)}
97       */
98      @Test
99      public void testGetExecutor() {
100         final NormalClass getInstanceClass = new NormalClass();
101         Method meth;
102         try {
103             meth = getInstanceClass.getClass().getMethod(METHODNAME);
104 
105             final BenchmarkMethod elem1 = new BenchmarkMethod(meth);
106             final BenchmarkMethod elem2 = new BenchmarkMethod(meth);
107 
108             final BenchmarkExecutor exec1 = BenchmarkExecutor.getExecutor(new BenchmarkElement(elem1));
109             final BenchmarkExecutor exec2 = BenchmarkExecutor.getExecutor(new BenchmarkElement(elem2));
110 
111             assertEquals("Singleton test of executor", exec1, exec2);
112         } catch (final SecurityException e) {
113             fail(e.getMessage());
114         } catch (final NoSuchMethodException e) {
115             fail(e.getMessage());
116         }
117     }
118 
119     /**
120      * Test method for {@link org.perfidix.element.BenchmarkExecutor#executeBeforeMethods(java.lang.Object)}
121      */
122     @Test
123     public void testExecuteBeforeMethods() {
124         try {
125             final Method meth = BeforeClass.class.getMethod("bench");
126             final Object objToExecute = BeforeClass.class.newInstance();
127 
128             final BenchmarkMethod elem = new BenchmarkMethod(meth);
129 
130             final BenchmarkExecutor exec = BenchmarkExecutor.getExecutor(new BenchmarkElement(elem));
131 
132             exec.executeBeforeMethods(objToExecute);
133             exec.executeBeforeMethods(objToExecute);
134 
135             assertEquals("Once should be inoked once", 1, once);
136             assertEquals("Each should be invoked twice", 2, each);
137         } catch (final SecurityException e) {
138             fail(e.getMessage());
139         } catch (final NoSuchMethodException e) {
140             fail(e.getMessage());
141         } catch (final InstantiationException e) {
142             fail(e.getMessage());
143         } catch (final IllegalAccessException e) {
144             fail(e.getMessage());
145         }
146 
147     }
148 
149     /**
150      * Test method for {@link org.perfidix.element.BenchmarkExecutor#executeBench(Object)} .
151      */
152     @Test
153     public void testExecuteBench() {
154         try {
155             final Method meth = NormalClass.class.getMethod(METHODNAME);
156             final Object objToExecute = NormalClass.class.newInstance();
157             final BenchmarkMethod elem = new BenchmarkMethod(meth);
158             final BenchmarkExecutor exec = BenchmarkExecutor.getExecutor(new BenchmarkElement(elem));
159             exec.executeBench(objToExecute);
160 
161             assertEquals("Each is invoked just once", 1, each);
162             assertEquals("Set should be included in the frameworks as well", meter, res.getRegisteredMeters());
163             final Iterator<ClassResult> classResIter = res.getIncludedResults().iterator();
164             final ClassResult classRes = classResIter.next();
165             assertFalse("Iterator of classes should only contain one element", classResIter.hasNext());
166             assertEquals("Meters should all be registered", meter, classRes.getRegisteredMeters());
167             assertEquals("Classes has to be included in a correct way", objToExecute.getClass(), classRes
168                 .getRelatedElement());
169             assertEquals("The NormalClass should be included", NormalClass.class, classRes
170                 .getRelatedElement());
171 
172             final Iterator<MethodResult> methResIter = classRes.getIncludedResults().iterator();
173             final MethodResult methRes = methResIter.next();
174             assertFalse("Only one result should be there", methResIter.hasNext());
175             assertEquals("The set has to match", meter, methRes.getRegisteredMeters());
176             assertEquals("The method should be the same than for the related element", meth, methRes
177                 .getRelatedElement());
178         } catch (final SecurityException e) {
179             fail(e.getMessage());
180         } catch (final NoSuchMethodException e) {
181             fail(e.getMessage());
182         } catch (final InstantiationException e) {
183             fail(e.getMessage());
184         } catch (final IllegalAccessException e) {
185             fail(e.getMessage());
186         }
187 
188     }
189 
190     /**
191      * Test method for {@link org.perfidix.element.BenchmarkExecutor#executeAfterMethods(java.lang.Object)}
192      */
193     @Test
194     public void testExecuteAfterMethods() {
195         try {
196             final Method meth = AfterClass.class.getMethod(METHODNAME);
197             final Object objToExecute = AfterClass.class.newInstance();
198 
199             final BenchmarkMethod elem = new BenchmarkMethod(meth);
200 
201             final BenchmarkExecutor exec = BenchmarkExecutor.getExecutor(new BenchmarkElement(elem));
202 
203             exec.executeAfterMethods(objToExecute);
204             exec.executeAfterMethods(objToExecute);
205 
206             assertEquals("Once should be invoked once", 1, once);
207             assertEquals("Each should be invoked twice", 2, each);
208         } catch (final SecurityException e) {
209             fail(e.getMessage());
210         } catch (final NoSuchMethodException e) {
211             fail(e.getMessage());
212         } catch (final InstantiationException e) {
213             fail(e.getMessage());
214         } catch (final IllegalAccessException e) {
215             fail(e.getMessage());
216         }
217 
218     }
219 
220     /**
221      * Test method for {@link org.perfidix.element.BenchmarkExecutor#checkMethod(Object, Method, Class)} and
222      * {@link org.perfidix.element.BenchmarkExecutor#invokeMethod(Object, Method, Class)}
223      */
224     @Test
225     public void testCheckAndExecute() {
226         try {
227             final Object falseObj = new Object();
228             final Object correctObj = new CheckAndExecuteClass();
229 
230             assertEquals("Two methods should be included", 2,
231                 correctObj.getClass().getDeclaredMethods().length);
232 
233             final Method correctMethod = CheckAndExecuteClass.class.getMethod("correctMethod");
234             final Method falseMethod = CheckAndExecuteClass.class.getMethod("incorrectMethod");
235 
236             final PerfidixMethodCheckException excep1 =
237                 BenchmarkExecutor.checkMethod(falseObj, SkipBench.class, correctMethod);
238             assertNotNull("Exception 1 shouldn't be null", excep1);
239 
240             final PerfidixMethodCheckException excep2 =
241                 BenchmarkExecutor.checkMethod(correctObj, SkipBench.class, falseMethod);
242             assertNotNull("Exception 2 shouldn't be null", excep2);
243 
244             final PerfidixMethodCheckException excep3 =
245                 BenchmarkExecutor.checkMethod(correctObj, SkipBench.class, correctMethod);
246             assertNull("Exception 3 shouldn't be null", excep3);
247 
248             final PerfidixMethodInvocationException excep4 =
249                 BenchmarkExecutor.invokeMethod(correctObj, SkipBench.class, correctMethod);
250             assertNull("Exception 4 shouldn't be null", excep4);
251 
252             assertEquals("invokation of beforeFirst should be occured just once", 1, once);
253         } catch (final SecurityException e) {
254             fail(e.getMessage());
255         } catch (final NoSuchMethodException e) {
256             fail(e.getMessage());
257         }
258     }
259 }
260 
261 class CheckAndExecuteClass {
262 
263     public void correctMethod() {
264         BenchmarkExecutorTest.once++;
265     }
266 
267     public Object incorrectMethod() {
268         return null;
269     }
270 
271 }
272 
273 class NormalClass {
274 
275     @Bench
276     public void bench() {
277         BenchmarkExecutorTest.each++;
278     }
279 
280 }
281 
282 class AfterClass {
283 
284     @Bench
285     public void bench() {
286         // empty method, just for counting
287     }
288 
289     @AfterLastRun
290     public void afterLast() {
291         BenchmarkExecutorTest.once++;
292     }
293 
294     @AfterEachRun
295     public void afterEach() {
296         BenchmarkExecutorTest.each++;
297     }
298 
299 }
300 
301 class BeforeClass {
302 
303     @Bench
304     public void bench() {
305         // empty method, just for counting
306     }
307 
308     @BeforeFirstRun
309     public void beforeFirst() {
310         BenchmarkExecutorTest.once++;
311     }
312 
313     @BeforeEachRun
314     public void beforeEach() {
315         BenchmarkExecutorTest.each++;
316     }
317 
318 }
319 
320 class CheckConfig extends AbstractConfig {
321 
322     protected CheckConfig(Set<AbstractMeter> meter) {
323         super(1, meter, AbstractConfig.LISTENERS, AbstractConfig.ARRAN,
324             AbstractConfig.GARBAGE_PROB);
325     }
326 }