This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-junit-performance.git

commit 57e48c90731afe273d6f1c78c463369b9d5c8afb
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Tue Jul 15 14:27:08 2014 +0000

    SLING-3762 - add annotations support to PerformanceRunner. Contributed by 
Francesco Mari, thanks!
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1610715 
13f79535-47bb-0310-9956-ffa450edef68
---
 .../performance/impl/InvokePerformanceBlock.java   |  85 ------
 .../sling/junit/performance/impl/Listeners.java    |  74 +++--
 ...InvokePerformanceMethod.java => RunAfters.java} |  44 ++-
 ...nvokePerformanceMethod.java => RunBefores.java} |  28 +-
 ...Method.java => RunExecutionFinishedEvents.java} |  36 ++-
 ...va => RunExecutionIterationFinishedEvents.java} |  36 ++-
 ...ava => RunExecutionIterationStartedEvents.java} |  27 +-
 ...eMethod.java => RunExecutionStartedEvents.java} |  27 +-
 ...kePerformanceMethod.java => RunIterations.java} |  49 ++-
 ...InvokePerformanceMethod.java => RunSerial.java} |  25 +-
 ...nceMethod.java => RunWarmUpFinishedEvents.java} |  53 ++--
 ....java => RunWarmUpIterationFinishedEvents.java} |  36 ++-
 ...d.java => RunWarmUpIterationStartedEvents.java} |  27 +-
 ...anceMethod.java => RunWarmUpStartedEvents.java} |  27 +-
 .../runner/AfterPerformanceIteration.java          |  28 ++
 .../performance/runner/AfterPerformanceTest.java   |  28 ++
 .../junit/performance/runner/AfterWarmUp.java      |  28 ++
 .../performance/runner/AfterWarmUpIteration.java   |  28 ++
 .../runner/BeforePerformanceIteration.java         |  28 ++
 .../performance/runner/BeforePerformanceTest.java  |  25 ++
 .../junit/performance/runner/BeforeWarmUp.java     |  28 ++
 .../performance/runner/BeforeWarmUpIteration.java  |  25 ++
 .../performance/runner/PerformanceRunner.java      | 335 ++++++++++++++++++---
 .../runner/PerformanceRunnerDynamicsTest.java      | 323 ++++++++++++++++++++
 .../performance/runner/PerformanceRunnerTest.java  |  42 +--
 25 files changed, 1134 insertions(+), 358 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
deleted file mode 100644
index 8af19e5..0000000
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.sling.junit.performance.impl;
-
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
-
-public class InvokePerformanceBlock extends Statement {
-
-    private final PerformanceMethod method;
-
-    private final Statement inner;
-
-    private final Listeners listeners;
-
-    private final TestClass testClass;
-
-    public InvokePerformanceBlock(TestClass testClass, FrameworkMethod method, 
Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
-        this.listeners = listeners;
-    }
-
-    @Override
-    public void evaluate() throws Throwable {
-
-        // Run warm-up invocations
-
-        listeners.warmUpStarted(testClass.getName(), method.getName());
-        run(method.getWarmUpInvocations(), method.getWarmUpTime());
-        listeners.warmUpFinished(testClass.getName(), method.getName());
-
-        // Run performance invocations
-
-        listeners.executionStarted(testClass.getName(), method.getName());
-        run(method.getRunInvocations(), method.getRunTime());
-        listeners.executionFinished(testClass.getName(), method.getName());
-    }
-
-    private void run(int invocations, int time) throws Throwable {
-        if (invocations > 0) {
-            runByInvocations(invocations);
-            return;
-        }
-
-        if (time > 0) {
-            runByTime(time);
-            return;
-        }
-
-        throw new IllegalArgumentException("no time or number of invocations 
specified");
-    }
-
-    private void runByInvocations(int invocations) throws Throwable {
-        for (int i = 0; i < invocations; i++) {
-            inner.evaluate();
-        }
-    }
-
-    private void runByTime(int seconds) throws Throwable {
-        long end = System.currentTimeMillis() + seconds * 1000;
-
-        while (System.currentTimeMillis() < end) {
-            inner.evaluate();
-        }
-    }
-
-}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java 
b/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
index 1a7b861..33d4020 100644
--- a/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
+++ b/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
@@ -19,12 +19,11 @@ package org.apache.sling.junit.performance.impl;
 
 import org.apache.sling.junit.performance.runner.Listener;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class Listeners {
 
-    private boolean isWarmUp;
-
     private final List<Listener> listeners;
 
     public Listeners(List<Listener> listeners) {
@@ -37,17 +36,22 @@ public class Listeners {
 
     }
 
-    private void invoke(Invoker invoker) throws Exception {
+    private List<Throwable> invoke(Invoker invoker) {
+        List<Throwable> errors = new ArrayList<Throwable>();
+
         for (Listener listener : listeners) {
-            invoker.invoke(listener);
+            try {
+                invoker.invoke(listener);
+            } catch (Throwable t) {
+                errors.add(t);
+            }
         }
 
+        return errors;
     }
 
-    public void warmUpStarted(final String className, final String testName) 
throws Exception {
-        isWarmUp = true;
-
-        invoke(new Invoker() {
+    public List<Throwable> warmUpStarted(final String className, final String 
testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
                 listener.warmUpStarted(className, testName);
@@ -56,10 +60,8 @@ public class Listeners {
         });
     }
 
-    public void warmUpFinished(final String className, final String testName) 
throws Exception {
-        isWarmUp = false;
-
-        invoke(new Invoker() {
+    public List<Throwable> warmUpFinished(final String className, final String 
testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
                 listener.warmUpFinished(className, testName);
@@ -68,8 +70,8 @@ public class Listeners {
         });
     }
 
-    public void executionStarted(final String className, final String 
testName) throws Exception {
-        invoke(new Invoker() {
+    public List<Throwable> executionStarted(final String className, final 
String testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
                 listener.executionStarted(className, testName);
@@ -78,8 +80,8 @@ public class Listeners {
         });
     }
 
-    public void executionFinished(final String className, final String 
testName) throws Exception {
-        invoke(new Invoker() {
+    public List<Throwable> executionFinished(final String className, final 
String testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
                 listener.executionFinished(className, testName);
@@ -88,29 +90,41 @@ public class Listeners {
         });
     }
 
-    public void iterationStarted(final String className, final String 
testName) throws Exception {
-        invoke(new Invoker() {
+    public List<Throwable> warmUpIterationStarted(final String className, 
final String testName) {
+        return invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.warmUpIterationStarted(className, testName);
+            }
+
+        });
+    }
+
+    public List<Throwable> warmUpIterationFinished(final String className, 
final String testName) {
+        return invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.warmUpIterationFinished(className, testName);
+            }
+
+        });
+    }
+
+    public List<Throwable> executionIterationStarted(final String className, 
final String testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
-                if (isWarmUp) {
-                    listener.warmUpIterationStarted(className, testName);
-                } else {
-                    listener.executionIterationStarted(className, testName);
-                }
+                listener.executionIterationStarted(className, testName);
             }
 
         });
     }
 
-    public void iterationFinished(final String className, final String 
testName) throws Exception {
-        invoke(new Invoker() {
+    public List<Throwable> executionIterationFinished(final String className, 
final String testName) {
+        return invoke(new Invoker() {
 
             public void invoke(Listener listener) throws Exception {
-                if (isWarmUp) {
-                    listener.warmUpIterationFinished(className, testName);
-                } else {
-                    listener.executionIterationFinished(className, testName);
-                }
+                listener.executionIterationFinished(className, testName);
             }
 
         });
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 b/src/main/java/org/apache/sling/junit/performance/impl/RunAfters.java
similarity index 52%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to src/main/java/org/apache/sling/junit/performance/impl/RunAfters.java
index ed8b5c7..447432e 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ b/src/main/java/org/apache/sling/junit/performance/impl/RunAfters.java
@@ -18,31 +18,45 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.ArrayList;
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunAfters extends Statement {
 
-    private final PerformanceMethod method;
+    private final Statement next;
 
-    private final Statement inner;
+    private final Object target;
 
-    private final Listeners listeners;
+    private final List<FrameworkMethod> afters;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
-        this.listeners = listeners;
+    public RunAfters(Statement next, List<FrameworkMethod> afters, Object 
target) {
+        this.next = next;
+        this.afters = afters;
+        this.target = target;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = new ArrayList<Throwable>();
+
+        try {
+            next.evaluate();
+        } catch (Throwable e) {
+            errors.add(e);
+        } finally {
+            for (FrameworkMethod each : afters) {
+                try {
+                    each.invokeExplosively(target);
+                } catch (Throwable e) {
+                    errors.add(e);
+                }
+            }
+        }
+
+        MultipleFailureException.assertEmpty(errors);
     }
 
-}
+}
\ No newline at end of file
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 b/src/main/java/org/apache/sling/junit/performance/impl/RunBefores.java
similarity index 59%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to src/main/java/org/apache/sling/junit/performance/impl/RunBefores.java
index ed8b5c7..5e2725d 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ b/src/main/java/org/apache/sling/junit/performance/impl/RunBefores.java
@@ -19,30 +19,30 @@ package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunBefores extends Statement {
 
-    private final PerformanceMethod method;
+    private final Statement next;
 
-    private final Statement inner;
+    private final Object target;
 
-    private final Listeners listeners;
+    private final List<FrameworkMethod> befores;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
-        this.listeners = listeners;
+    public RunBefores(Statement next, List<FrameworkMethod> befores, Object 
target) {
+        this.next = next;
+        this.befores = befores;
+        this.target = target;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        for (FrameworkMethod before : befores) {
+            before.invokeExplosively(target);
+        }
+
+        next.evaluate();
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionFinishedEvents.java
similarity index 57%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunExecutionFinishedEvents.java
index ed8b5c7..4d43ff1 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionFinishedEvents.java
@@ -18,31 +18,43 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.ArrayList;
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunExecutionFinishedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunExecutionFinishedEvents(Listeners listeners, TestClass test, 
FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = new ArrayList<Throwable>();
+
+        try {
+            statement.evaluate();
+        } catch (Throwable t) {
+            errors.add(t);
+        } finally {
+            errors.addAll(listeners.executionFinished(test.getName(), 
method.getName()));
+        }
+
+        MultipleFailureException.assertEmpty(errors);
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationFinishedEvents.java
similarity index 56%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationFinishedEvents.java
index ed8b5c7..b99f5d4 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationFinishedEvents.java
@@ -18,31 +18,43 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.ArrayList;
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunExecutionIterationFinishedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunExecutionIterationFinishedEvents(Listeners listeners, TestClass 
test, FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = new ArrayList<Throwable>();
+
+        try {
+            statement.evaluate();
+        } catch (Throwable t) {
+            errors.add(t);
+        } finally {
+            errors.addAll(listeners.executionIterationFinished(test.getName(), 
method.getName()));
+        }
+
+        MultipleFailureException.assertEmpty(errors);
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationStartedEvents.java
similarity index 62%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationStartedEvents.java
index ed8b5c7..af98c1f 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionIterationStartedEvents.java
@@ -18,31 +18,34 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunExecutionIterationStartedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunExecutionIterationStartedEvents(Listeners listeners, TestClass 
test, FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = 
listeners.executionIterationStarted(test.getName(), method.getName());
+        MultipleFailureException.assertEmpty(errors);
+        statement.evaluate();
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionStartedEvents.java
similarity index 63%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunExecutionStartedEvents.java
index ed8b5c7..4f0d924 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunExecutionStartedEvents.java
@@ -18,31 +18,34 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunExecutionStartedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunExecutionStartedEvents(Listeners listeners, TestClass test, 
FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = listeners.executionStarted(test.getName(), 
method.getName());
+        MultipleFailureException.assertEmpty(errors);
+        statement.evaluate();
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 b/src/main/java/org/apache/sling/junit/performance/impl/RunIterations.java
similarity index 50%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to src/main/java/org/apache/sling/junit/performance/impl/RunIterations.java
index ed8b5c7..c68d443 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ b/src/main/java/org/apache/sling/junit/performance/impl/RunIterations.java
@@ -17,32 +17,49 @@
 
 package org.apache.sling.junit.performance.impl;
 
-import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+public class RunIterations extends Statement {
 
-    private final TestClass testClass;
+    private final int invocations;
 
-    private final PerformanceMethod method;
+    private final int seconds;
 
-    private final Statement inner;
+    private final Statement iteration;
 
-    private final Listeners listeners;
-
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
-        this.listeners = listeners;
+    public RunIterations(int invocations, int seconds, Statement iteration) {
+        this.invocations = invocations;
+        this.seconds = seconds;
+        this.iteration = iteration;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        if (invocations > 0) {
+            runByInvocations();
+            return;
+        }
+
+        if (seconds > 0) {
+            runByTime();
+            return;
+        }
+
+        throw new IllegalArgumentException("Number of invocations or seconds 
not provided");
+    }
+
+    private void runByTime() throws Throwable {
+        long end = System.currentTimeMillis() + seconds * 1000;
+
+        while (System.currentTimeMillis() < end) {
+            iteration.evaluate();
+        }
+    }
+
+    private void runByInvocations() throws Throwable {
+        for (int i = 0; i < invocations; i++) {
+            iteration.evaluate();
+        }
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 b/src/main/java/org/apache/sling/junit/performance/impl/RunSerial.java
similarity index 56%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to src/main/java/org/apache/sling/junit/performance/impl/RunSerial.java
index ed8b5c7..a65b69d 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ b/src/main/java/org/apache/sling/junit/performance/impl/RunSerial.java
@@ -17,32 +17,21 @@
 
 package org.apache.sling.junit.performance.impl;
 
-import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+public class RunSerial extends Statement {
 
-    private final TestClass testClass;
+    private final Statement[] statements;
 
-    private final PerformanceMethod method;
-
-    private final Statement inner;
-
-    private final Listeners listeners;
-
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
-        this.listeners = listeners;
+    public RunSerial(Statement... statements) {
+        this.statements = statements;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        for (Statement statement : statements) {
+            statement.evaluate();
+        }
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpFinishedEvents.java
similarity index 51%
rename from 
src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
rename to 
src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpFinishedEvents.java
index 296a030..8fe4b8d 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpFinishedEvents.java
@@ -17,45 +17,44 @@
 
 package org.apache.sling.junit.performance.impl;
 
-import org.apache.sling.junit.performance.runner.PerformanceTest;
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
 
-public class PerformanceMethod {
+import java.util.ArrayList;
+import java.util.List;
 
-    private final FrameworkMethod method;
-
-    public PerformanceMethod(FrameworkMethod method) {
-        this.method = method;
-    }
+public class RunWarmUpFinishedEvents extends Statement {
 
-    private PerformanceTest getPerformanceTestAnnotation() {
-        PerformanceTest performanceTest = 
method.getAnnotation(PerformanceTest.class);
+    private final Listeners listeners;
 
-        if (performanceTest == null) {
-            throw new IllegalStateException("a performance method should be 
annotated with @PerformanceTest");
-        }
+    private final TestClass test;
 
-        return performanceTest;
-    }
+    private final FrameworkMethod method;
 
-    public int getWarmUpTime() {
-        return getPerformanceTestAnnotation().warmUpTime();
-    }
+    private final Statement statement;
 
-    public int getWarmUpInvocations() {
-        return getPerformanceTestAnnotation().warmUpInvocations();
+    public RunWarmUpFinishedEvents(Listeners listeners, TestClass test, 
FrameworkMethod method, Statement statement) {
+        this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
-    public int getRunTime() {
-        return getPerformanceTestAnnotation().runTime();
-    }
+    @Override
+    public void evaluate() throws Throwable {
+        List<Throwable> errors = new ArrayList<Throwable>();
 
-    public int getRunInvocations() {
-        return getPerformanceTestAnnotation().runInvocations();
-    }
+        try {
+            statement.evaluate();
+        } catch (Throwable t) {
+            errors.add(t);
+        } finally {
+            errors.addAll(listeners.warmUpFinished(test.getName(), 
method.getName()));
+        }
 
-    public String getName() {
-        return method.getName();
+        MultipleFailureException.assertEmpty(errors);
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationFinishedEvents.java
similarity index 57%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationFinishedEvents.java
index ed8b5c7..dd767e5 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationFinishedEvents.java
@@ -18,31 +18,43 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.ArrayList;
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunWarmUpIterationFinishedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunWarmUpIterationFinishedEvents(Listeners listeners, TestClass 
test, FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = new ArrayList<Throwable>();
+
+        try {
+            statement.evaluate();
+        } catch (Throwable t) {
+            errors.add(t);
+        } finally {
+            errors.addAll(listeners.warmUpIterationFinished(test.getName(), 
method.getName()));
+        }
+
+        MultipleFailureException.assertEmpty(errors);
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationStartedEvents.java
similarity index 63%
copy from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
copy to 
src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationStartedEvents.java
index ed8b5c7..c8b40a2 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpIterationStartedEvents.java
@@ -18,31 +18,34 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunWarmUpIterationStartedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunWarmUpIterationStartedEvents(Listeners listeners, TestClass 
test, FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = 
listeners.warmUpIterationStarted(test.getName(), method.getName());
+        MultipleFailureException.assertEmpty(errors);
+        statement.evaluate();
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpStartedEvents.java
similarity index 64%
rename from 
src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
rename to 
src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpStartedEvents.java
index ed8b5c7..028b5be 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/impl/RunWarmUpStartedEvents.java
@@ -18,31 +18,34 @@
 package org.apache.sling.junit.performance.impl;
 
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
 import org.junit.runners.model.TestClass;
 
-public class InvokePerformanceMethod extends Statement {
+import java.util.List;
 
-    private final TestClass testClass;
+public class RunWarmUpStartedEvents extends Statement {
 
-    private final PerformanceMethod method;
+    private final Listeners listeners;
 
-    private final Statement inner;
+    private final TestClass test;
 
-    private final Listeners listeners;
+    private final FrameworkMethod method;
+
+    private final Statement statement;
 
-    public InvokePerformanceMethod(TestClass testClass, FrameworkMethod 
method, Statement inner, Listeners listeners) {
-        this.testClass = testClass;
-        this.method = new PerformanceMethod(method);
-        this.inner = inner;
+    public RunWarmUpStartedEvents(Listeners listeners, TestClass test, 
FrameworkMethod method, Statement statement) {
         this.listeners = listeners;
+        this.test = test;
+        this.method = method;
+        this.statement = statement;
     }
 
     @Override
     public void evaluate() throws Throwable {
-        listeners.iterationStarted(testClass.getName(), method.getName());
-        inner.evaluate();
-        listeners.iterationFinished(testClass.getName(), method.getName());
+        List<Throwable> errors = listeners.warmUpStarted(test.getName(), 
method.getName());
+        MultipleFailureException.assertEmpty(errors);
+        statement.evaluate();
     }
 
 }
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceIteration.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceIteration.java
new file mode 100644
index 0000000..5f7eec3
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceIteration.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method after each performance execution of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterPerformanceIteration {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceTest.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceTest.java
new file mode 100644
index 0000000..03a476c
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterPerformanceTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method after every performance iteration of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterPerformanceTest {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUp.java 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUp.java
new file mode 100644
index 0000000..bb4f082
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUp.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method after each warm up iteration of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterWarmUp {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUpIteration.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUpIteration.java
new file mode 100644
index 0000000..b0d19ff
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/AfterWarmUpIteration.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method after each warm up iteration of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterWarmUpIteration {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceIteration.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceIteration.java
new file mode 100644
index 0000000..8e1a1d1
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceIteration.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method before each performance iteration of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforePerformanceIteration {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceTest.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceTest.java
new file mode 100644
index 0000000..b1a5d00
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforePerformanceTest.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforePerformanceTest {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUp.java 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUp.java
new file mode 100644
index 0000000..22e3dac
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUp.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Execute the annotated method before every warm up iterations of the 
performance test.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforeWarmUp {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUpIteration.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUpIteration.java
new file mode 100644
index 0000000..1aff58e
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/BeforeWarmUpIteration.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforeWarmUpIteration {
+}
diff --git 
a/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
 
b/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
index d9aa3de..c98472a 100644
--- 
a/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
+++ 
b/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
@@ -17,9 +17,7 @@
 
 package org.apache.sling.junit.performance.runner;
 
-import org.apache.sling.junit.performance.impl.InvokePerformanceBlock;
-import org.apache.sling.junit.performance.impl.InvokePerformanceMethod;
-import org.apache.sling.junit.performance.impl.Listeners;
+import org.apache.sling.junit.performance.impl.*;
 import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.model.FrameworkField;
 import org.junit.runners.model.FrameworkMethod;
@@ -40,6 +38,11 @@ import java.util.List;
  * The runner can also invoke one or more {@link Listener}. The listener is 
specified as a static variable of the test
  * class or as the result of a static method. The listeners are made available 
to the runner by annotating them with the
  * {@link Listen} annotation.
+ * <p/>
+ * The runner support lifecycle methods which are executed at various stages 
of the performance test. These methods are
+ * annotated with {@link BeforePerformanceIteration}, {@link 
AfterPerformanceIteration}, {@link BeforePerformanceTest},
+ * {@link AfterPerformanceTest}, {@link BeforeWarmUpIteration}, {@link 
AfterWarmUpIteration}, {@link BeforeWarmUp} and
+ * {@link AfterWarmUp}. Every other standard JUnit annotation is also 
supported.
  */
 public class PerformanceRunner extends BlockJUnit4ClassRunner {
 
@@ -49,28 +52,278 @@ public class PerformanceRunner extends 
BlockJUnit4ClassRunner {
         super(testClass);
 
         try {
-            listeners = new Listeners(readListeners());
-        } catch (Exception e) {
+            listeners = new Listeners(getListeners());
+        } catch (Throwable e) {
             throw new InitializationError(e);
         }
     }
 
     @Override
-    protected List<FrameworkMethod> computeTestMethods() {
-        return getTestClass().getAnnotatedMethods(PerformanceTest.class);
+    protected void collectInitializationErrors(List<Throwable> errors) {
+        super.collectInitializationErrors(errors);
+
+        validatePublicVoidNoArgMethods(PerformanceTest.class, false, errors);
+        validatePublicVoidNoArgMethods(BeforeWarmUpIteration.class, false, 
errors);
+        validatePublicVoidNoArgMethods(AfterWarmUpIteration.class, false, 
errors);
+        validatePublicVoidNoArgMethods(BeforeWarmUp.class, false, errors);
+        validatePublicVoidNoArgMethods(AfterWarmUp.class, false, errors);
+        validatePublicVoidNoArgMethods(BeforePerformanceIteration.class, 
false, errors);
+        validatePublicVoidNoArgMethods(AfterPerformanceIteration.class, false, 
errors);
+        validatePublicVoidNoArgMethods(BeforePerformanceTest.class, false, 
errors);
+        validatePublicVoidNoArgMethods(AfterPerformanceTest.class, false, 
errors);
+        validatePerformanceTestsExecutionStrategy(errors);
+        validateListenMethodsReturnType(errors);
+        validateListenMethodsStatic(errors);
+        validateListenMethodPublic(errors);
+        validateListenFieldsType(errors);
+        validateListenFieldsStatic(errors);
+        validateListenFieldPublic(errors);
+    }
+
+    private void validatePerformanceTestsExecutionStrategy(List<Throwable> 
errors) {
+        for (FrameworkMethod method : 
getTestClass().getAnnotatedMethods(PerformanceTest.class)) {
+            int warmUpInvocations = getWarmUpInvocations(method);
+            int warmUpTime = getWarmUpTime(method);
+
+            if (warmUpInvocations <= 0 && warmUpTime <= 0) {
+                errors.add(new Error("Method " + method.getName() + "() should 
provide a valid warmUpInvocations or warmUpTime"));
+            }
+
+            if (warmUpInvocations > 0 && warmUpTime > 0) {
+                errors.add(new Error("Method " + method.getName() + "() 
provides both a valid warmUpInvocations and a warmUpTime"));
+            }
+
+            int runInvocations = getRunInvocations(method);
+            int runTime = getRunTime(method);
+
+            if (runInvocations <= 0 && runTime <= 0) {
+                errors.add(new Error("Method " + method.getName() + "() should 
provide a valid runInvocations or runTime"));
+            }
+
+            if (runInvocations > 0 && runTime > 0) {
+                errors.add(new Error("Method " + method.getName() + "() 
provides both a valid runInvocations or runTime"));
+            }
+        }
+    }
+
+    private void validateListenMethodsReturnType(List<Throwable> errors) {
+        for (FrameworkMethod method : 
getTestClass().getAnnotatedMethods(Listen.class)) {
+            if (Listener.class.isAssignableFrom(method.getReturnType())) {
+                continue;
+            }
+
+            errors.add(new Error("Method " + method.getName() + "() should 
return an object of type Listener"));
+        }
+    }
+
+    private void validateListenMethodsStatic(List<Throwable> errors) {
+        for (FrameworkMethod method : 
getTestClass().getAnnotatedMethods(Listen.class)) {
+            if (method.isStatic()) {
+                continue;
+            }
+
+            errors.add(new Error("Method " + method.getName() + "() should be 
static"));
+        }
+    }
+
+    private void validateListenMethodPublic(List<Throwable> errors) {
+        for (FrameworkMethod method : 
getTestClass().getAnnotatedMethods(Listen.class)) {
+            if (method.isPublic()) {
+                continue;
+            }
+
+            errors.add(new Error("Method " + method.getName() + "() should be 
public"));
+        }
+    }
+
+    private void validateListenFieldsType(List<Throwable> errors) {
+        for (FrameworkField field : 
getTestClass().getAnnotatedFields(Listen.class)) {
+            if (Listener.class.isAssignableFrom(field.getType())) {
+                continue;
+            }
+
+            errors.add(new Error("Field " + field.getName() + " should be of 
type Listener"));
+        }
+    }
+
+    private void validateListenFieldsStatic(List<Throwable> errors) {
+        for (FrameworkField field : 
getTestClass().getAnnotatedFields(Listen.class)) {
+            if (field.isStatic()) {
+                continue;
+            }
+
+            errors.add(new Error("Field " + field.getName() + " should be 
static"));
+        }
+    }
+
+    private void validateListenFieldPublic(List<Throwable> errors) {
+        for (FrameworkField field : 
getTestClass().getAnnotatedFields(Listen.class)) {
+            if (field.isPublic()) {
+                continue;
+            }
+
+            errors.add(new Error("Field " + field.getName() + " should be 
public"));
+        }
     }
 
     @Override
-    protected Statement methodBlock(FrameworkMethod method) {
-        return new InvokePerformanceBlock(getTestClass(), method, 
super.methodBlock(method), listeners);
+    protected List<FrameworkMethod> computeTestMethods() {
+        return getTestClass().getAnnotatedMethods(PerformanceTest.class);
     }
 
     @Override
     protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        return new InvokePerformanceMethod(getTestClass(), method, 
super.methodInvoker(method, test), listeners);
+        Statement methodInvoker = super.methodInvoker(method, test);
+
+        Statement invokeWarmUp = methodInvoker;
+
+        invokeWarmUp = withWarmUpIterationStartedEvents(method, test, 
invokeWarmUp);
+        invokeWarmUp = withWarmUpIterationFinishedEvents(method, test, 
invokeWarmUp);
+        invokeWarmUp = withBeforeWarmUpIterations(method, test, invokeWarmUp);
+        invokeWarmUp = withAfterWarmUpIterations(method, test, invokeWarmUp);
+        invokeWarmUp = withWarmUpIterations(method, test, invokeWarmUp);
+        invokeWarmUp = withWarmUpStartedEvents(method, test, invokeWarmUp);
+        invokeWarmUp = withWarmUpFinishedEvents(method, test, invokeWarmUp);
+        invokeWarmUp = withBeforeWarmUps(method, test, invokeWarmUp);
+        invokeWarmUp = withAfterWarmUps(method, test, invokeWarmUp);
+
+        Statement invokePerformanceTest = methodInvoker;
+
+        invokePerformanceTest = withExecutionIterationStartedEvents(method, 
test, invokePerformanceTest);
+        invokePerformanceTest = withExecutionIterationFinishedEvents(method, 
test, invokePerformanceTest);
+        invokePerformanceTest = withBeforePerformanceIterations(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withAfterPerformanceIterations(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withPerformanceIterations(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withExecutionStartedEvents(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withExecutionFinishedEvents(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withBeforePerformanceTests(method, test, 
invokePerformanceTest);
+        invokePerformanceTest = withAfterPerformanceTests(method, test, 
invokePerformanceTest);
+
+        return new RunSerial(invokeWarmUp, invokePerformanceTest);
     }
 
-    private List<Listener> readListeners() throws Exception {
+
+    protected Statement withBeforeWarmUpIterations(FrameworkMethod method, 
Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(BeforeWarmUpIteration.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunBefores(next, methods, test);
+    }
+
+    protected Statement withAfterWarmUpIterations(FrameworkMethod method, 
Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(AfterWarmUpIteration.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunAfters(next, methods, test);
+    }
+
+    protected Statement withWarmUpIterations(FrameworkMethod method, Object 
test, Statement iteration) {
+        return new RunIterations(getWarmUpInvocations(method), 
getWarmUpTime(method), iteration);
+    }
+
+    protected Statement withBeforeWarmUps(FrameworkMethod method, Object test, 
Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(BeforeWarmUp.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunBefores(next, methods, test);
+    }
+
+    protected Statement withAfterWarmUps(FrameworkMethod method, Object test, 
Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(AfterWarmUp.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunAfters(next, methods, test);
+    }
+
+    protected Statement withBeforePerformanceIterations(FrameworkMethod 
method, Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(BeforePerformanceIteration.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunBefores(next, methods, test);
+    }
+
+    protected Statement withAfterPerformanceIterations(FrameworkMethod method, 
Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(AfterPerformanceIteration.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunAfters(next, methods, test);
+    }
+
+    protected Statement withPerformanceIterations(FrameworkMethod method, 
Object test, Statement iteration) {
+        return new RunIterations(getRunInvocations(method), 
getRunTime(method), iteration);
+    }
+
+    protected Statement withBeforePerformanceTests(FrameworkMethod method, 
Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(BeforePerformanceTest.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunBefores(next, methods, test);
+    }
+
+    protected Statement withAfterPerformanceTests(FrameworkMethod method, 
Object test, Statement next) {
+        List<FrameworkMethod> methods = 
getTestClass().getAnnotatedMethods(AfterPerformanceTest.class);
+
+        if (methods.size() == 0) {
+            return next;
+        }
+
+        return new RunAfters(next, methods, test);
+    }
+
+    protected Statement withWarmUpIterationStartedEvents(FrameworkMethod 
method, Object test, Statement next) {
+        return new RunWarmUpIterationStartedEvents(listeners, getTestClass(), 
method, next);
+    }
+
+    protected Statement withWarmUpIterationFinishedEvents(FrameworkMethod 
method, Object test, Statement next) {
+        return new RunWarmUpIterationFinishedEvents(listeners, getTestClass(), 
method, next);
+    }
+
+    protected Statement withWarmUpStartedEvents(FrameworkMethod method, Object 
test, Statement next) {
+        return new RunWarmUpStartedEvents(listeners, getTestClass(), method, 
next);
+    }
+
+    protected Statement withWarmUpFinishedEvents(FrameworkMethod method, 
Object test, Statement next) {
+        return new RunWarmUpFinishedEvents(listeners, getTestClass(), method, 
next);
+    }
+
+    protected Statement withExecutionIterationStartedEvents(FrameworkMethod 
method, Object test, Statement next) {
+        return new RunExecutionIterationStartedEvents(listeners, 
getTestClass(), method, next);
+    }
+
+    protected Statement withExecutionIterationFinishedEvents(FrameworkMethod 
method, Object test, Statement next) {
+        return new RunExecutionIterationFinishedEvents(listeners, 
getTestClass(), method, next);
+    }
+
+    protected Statement withExecutionStartedEvents(FrameworkMethod method, 
Object test, Statement next) {
+        return new RunExecutionStartedEvents(listeners, getTestClass(), 
method, next);
+    }
+
+    protected Statement withExecutionFinishedEvents(FrameworkMethod method, 
Object test, Statement next) {
+        return new RunExecutionFinishedEvents(listeners, getTestClass(), 
method, next);
+    }
+
+    private List<Listener> getListeners() throws Throwable {
         List<Listener> listeners = new ArrayList<Listener>();
 
         listeners.addAll(readListenersFromStaticFields());
@@ -79,32 +332,14 @@ public class PerformanceRunner extends 
BlockJUnit4ClassRunner {
         return listeners;
     }
 
-    private List<Listener> readListenersFromStaticMethods() throws Exception {
+    private List<Listener> readListenersFromStaticMethods() throws Throwable {
         List<Listener> listeners = new ArrayList<Listener>();
 
         for (FrameworkMethod method : 
getTestClass().getAnnotatedMethods(Listen.class)) {
-            if (!method.isPublic()) {
-                throw new IllegalArgumentException("a @Listen method must be 
public");
-            }
-
-            if (!method.isStatic()) {
-                throw new IllegalArgumentException("a @Listen method must be 
static");
-            }
-
-            if (!Listener.class.isAssignableFrom(method.getReturnType())) {
-                throw new IllegalArgumentException("a @Listen method must be 
of type Listener");
-            }
-
-            Listener listener = null;
-
-            try {
-                listener = (Listener) method.invokeExplosively(null);
-            } catch (Throwable throwable) {
-                throw new RuntimeException("error while invoking the @Listen 
method", throwable);
-            }
+            Listener listener = (Listener) method.invokeExplosively(null);
 
             if (listener == null) {
-                throw new IllegalArgumentException("a @Listen method must 
return a non-null value");
+                throw new IllegalArgumentException("Method " + 
method.getName() + "() should not return null");
             }
 
             listeners.add(listener);
@@ -114,31 +349,35 @@ public class PerformanceRunner extends 
BlockJUnit4ClassRunner {
     }
 
     private List<Listener> readListenersFromStaticFields() throws Exception {
-        List<Listener> reporters = new ArrayList<Listener>();
+        List<Listener> listeners = new ArrayList<Listener>();
 
         for (FrameworkField field : 
getTestClass().getAnnotatedFields(Listen.class)) {
-            if (!field.isPublic()) {
-                throw new IllegalArgumentException("a @Listen field must be 
public");
-            }
-
-            if (!field.isStatic()) {
-                throw new IllegalArgumentException("a @Listen field must be 
static");
-            }
-
-            if (!Listener.class.isAssignableFrom(field.getType())) {
-                throw new IllegalArgumentException("a @Listen field must be of 
type Listener");
-            }
-
             Listener listener = (Listener) field.get(null);
 
             if (listener == null) {
-                throw new IllegalArgumentException("a @Listen field must not 
be null");
+                throw new IllegalArgumentException("Field " + field.getName() 
+ " should not be null");
             }
 
-            reporters.add(listener);
+            listeners.add(listener);
         }
 
-        return reporters;
+        return listeners;
+    }
+
+    private int getWarmUpInvocations(FrameworkMethod method) {
+        return method.getAnnotation(PerformanceTest.class).warmUpInvocations();
+    }
+
+    private int getWarmUpTime(FrameworkMethod method) {
+        return method.getAnnotation(PerformanceTest.class).warmUpTime();
+    }
+
+    private int getRunInvocations(FrameworkMethod method) {
+        return method.getAnnotation(PerformanceTest.class).runInvocations();
+    }
+
+    private int getRunTime(FrameworkMethod method) {
+        return method.getAnnotation(PerformanceTest.class).runTime();
     }
 
 }
diff --git 
a/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerDynamicsTest.java
 
b/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerDynamicsTest.java
new file mode 100644
index 0000000..ecd5804
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerDynamicsTest.java
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sling.junit.performance.runner;
+
+import org.junit.*;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PerformanceRunnerDynamicsTest {
+
+    @RunWith(PerformanceRunner.class)
+    public static class AnnotationOrder {
+
+        public static List<String> executions = new ArrayList<String>();
+
+        @BeforeWarmUpIteration
+        public void beforeWarmUpIteration() {
+            executions.add("before warm up iteration");
+        }
+
+        @AfterWarmUpIteration
+        public void afterWarmUpIteration() {
+            executions.add("after warm up iteration");
+        }
+
+        @BeforeWarmUp
+        public void beforeWarmUp() {
+            executions.add("before warm up");
+        }
+
+        @AfterWarmUp
+        public void afterWarmUp() {
+            executions.add("after warm up");
+        }
+
+        @BeforePerformanceIteration
+        public void beforePerformanceIteration() {
+            executions.add("before performance iteration");
+        }
+
+        @AfterPerformanceIteration
+        public void afterPerformanceIteration() {
+            executions.add("after performance iteration");
+        }
+
+        @BeforePerformanceTest
+        public void beforePerformanceTest() {
+            executions.add("before performance test");
+        }
+
+        @AfterPerformanceTest
+        public void afterPerformanceTest() {
+            executions.add("after performance test");
+        }
+
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
+        public void performanceTest() {
+            executions.add("performance test");
+        }
+
+    }
+
+    @Test
+    public void testAnnotationOrder() {
+        List<String> expected = new ArrayList<String>();
+
+        expected.add("before warm up");
+        expected.add("before warm up iteration");
+        expected.add("performance test");
+        expected.add("after warm up iteration");
+        expected.add("after warm up");
+        expected.add("before performance test");
+        expected.add("before performance iteration");
+        expected.add("performance test");
+        expected.add("after performance iteration");
+        expected.add("after performance test");
+
+        JUnitCore.runClasses(AnnotationOrder.class);
+
+        Assert.assertEquals(expected, AnnotationOrder.executions);
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class ExistingJUnitAnnotations {
+
+        public static List<String> executions = new ArrayList<String>();
+
+        @BeforeClass
+        public static void beforeClass() {
+            executions.add("junit before class");
+        }
+
+        @AfterClass
+        public static void afterClass() {
+            executions.add("junit after class");
+        }
+
+        @Before
+        public void before() {
+            executions.add("junit before");
+        }
+
+        @After
+        public void after() {
+            executions.add("junit after");
+        }
+
+        @BeforeWarmUpIteration
+        public void beforeWarmUpIteration() {
+            executions.add("before warm up iteration");
+        }
+
+        @AfterWarmUpIteration
+        public void afterWarmUpIteration() {
+            executions.add("after warm up iteration");
+        }
+
+        @BeforeWarmUp
+        public void beforeWarmUp() {
+            executions.add("before warm up");
+        }
+
+        @AfterWarmUp
+        public void afterWarmUp() {
+            executions.add("after warm up");
+        }
+
+        @BeforePerformanceIteration
+        public void beforePerformanceIteration() {
+            executions.add("before performance iteration");
+        }
+
+        @AfterPerformanceIteration
+        public void afterPerformanceIteration() {
+            executions.add("after performance iteration");
+        }
+
+        @BeforePerformanceTest
+        public void beforePerformanceTest() {
+            executions.add("before performance test");
+        }
+
+        @AfterPerformanceTest
+        public void afterPerformanceTest() {
+            executions.add("after performance test");
+        }
+
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
+        public void performanceTest() {
+            executions.add("performance test");
+        }
+
+    }
+
+    @Test
+    public void testExistingJUnitAnnotations() {
+        List<String> expected = new ArrayList<String>();
+
+        expected.add("junit before class");
+        expected.add("junit before");
+        expected.add("before warm up");
+        expected.add("before warm up iteration");
+        expected.add("performance test");
+        expected.add("after warm up iteration");
+        expected.add("after warm up");
+        expected.add("before performance test");
+        expected.add("before performance iteration");
+        expected.add("performance test");
+        expected.add("after performance iteration");
+        expected.add("after performance test");
+        expected.add("junit after");
+        expected.add("junit after class");
+
+        JUnitCore.runClasses(ExistingJUnitAnnotations.class);
+
+        Assert.assertEquals(expected, ExistingJUnitAnnotations.executions);
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class PerformanceListeners {
+
+        public static List<String> executions = new ArrayList<String>();
+
+        @Listen
+        public static Listener listener = new Listener() {
+
+            @Override
+            public void warmUpStarted(String className, String testName) 
throws Exception {
+                executions.add("warm up started event");
+            }
+
+            @Override
+            public void warmUpFinished(String className, String testName) 
throws Exception {
+                executions.add("warm up finished event");
+            }
+
+            @Override
+            public void executionStarted(String className, String testName) 
throws Exception {
+                executions.add("execution started event");
+            }
+
+            @Override
+            public void executionFinished(String className, String testName) 
throws Exception {
+                executions.add("execution finished event");
+            }
+
+            @Override
+            public void warmUpIterationStarted(String className, String 
testName) throws Exception {
+                executions.add("warm up iteration started event");
+            }
+
+            @Override
+            public void executionIterationStarted(String className, String 
testName) throws Exception {
+                executions.add("execution iteration started event");
+            }
+
+            @Override
+            public void warmUpIterationFinished(String className, String 
testName) throws Exception {
+                executions.add("warm up iteration finished event");
+            }
+
+            @Override
+            public void executionIterationFinished(String className, String 
testName) throws Exception {
+                executions.add("execution iteration finished event");
+            }
+
+        };
+
+        @BeforeWarmUpIteration
+        public void beforeWarmUpIteration() {
+            executions.add("before warm up iteration");
+        }
+
+        @AfterWarmUpIteration
+        public void afterWarmUpIteration() {
+            executions.add("after warm up iteration");
+        }
+
+        @BeforeWarmUp
+        public void beforeWarmUp() {
+            executions.add("before warm up");
+        }
+
+        @AfterWarmUp
+        public void afterWarmUp() {
+            executions.add("after warm up");
+        }
+
+        @BeforePerformanceIteration
+        public void beforePerformanceIteration() {
+            executions.add("before performance iteration");
+        }
+
+        @AfterPerformanceIteration
+        public void afterPerformanceIteration() {
+            executions.add("after performance iteration");
+        }
+
+        @BeforePerformanceTest
+        public void beforePerformanceTest() {
+            executions.add("before performance test");
+        }
+
+        @AfterPerformanceTest
+        public void afterPerformanceTest() {
+            executions.add("after performance test");
+        }
+
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
+        public void performanceTest() {
+            executions.add("performance test");
+        }
+
+    }
+
+    @Test
+    public void testPerformanceListeners() {
+        List<String> expected = new ArrayList<String>();
+
+        expected.add("before warm up");
+        expected.add("warm up started event");
+        expected.add("before warm up iteration");
+        expected.add("warm up iteration started event");
+        expected.add("performance test");
+        expected.add("warm up iteration finished event");
+        expected.add("after warm up iteration");
+        expected.add("warm up finished event");
+        expected.add("after warm up");
+
+        expected.add("before performance test");
+        expected.add("execution started event");
+        expected.add("before performance iteration");
+        expected.add("execution iteration started event");
+        expected.add("performance test");
+        expected.add("execution iteration finished event");
+        expected.add("after performance iteration");
+        expected.add("execution finished event");
+        expected.add("after performance test");
+
+        JUnitCore.runClasses(PerformanceListeners.class);
+
+        Assert.assertEquals(expected, PerformanceListeners.executions);
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
 
b/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
index 5141b5a..07c95e2 100644
--- 
a/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
+++ 
b/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
@@ -48,7 +48,7 @@ public class PerformanceRunnerTest {
         @Listen
         private static Listener listener = new Listener();
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -57,7 +57,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testPrivateListenerField() {
-        assertTestFails(PrivateListenerField.class, "a @Listen field must be 
public");
+        assertTestFails(PrivateListenerField.class, "Field listener should be 
public");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -66,7 +66,7 @@ public class PerformanceRunnerTest {
         @Listen
         public Listener listener = new Listener();
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -75,7 +75,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testInstanceListenerField() {
-        assertTestFails(InstanceListenerField.class, "a @Listen field must be 
static");
+        assertTestFails(InstanceListenerField.class, "Field listener should be 
static");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -84,7 +84,7 @@ public class PerformanceRunnerTest {
         @Listen
         public static Integer listener = 42;
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -93,7 +93,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testWrongTypeListenerField() {
-        assertTestFails(WrongTypeListenerField.class, "a @Listen field must be 
of type Listener");
+        assertTestFails(WrongTypeListenerField.class, "Field listener should 
be of type Listener");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -102,7 +102,7 @@ public class PerformanceRunnerTest {
         @Listen
         public static Listener listener = null;
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -111,7 +111,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testNullListenerField() {
-        assertTestFails(NullListenerField.class, "a @Listen field must not be 
null");
+        assertTestFails(NullListenerField.class, "Field listener should not be 
null");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -122,7 +122,7 @@ public class PerformanceRunnerTest {
             return new Listener();
         }
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -131,7 +131,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testPrivateListenerMethod() {
-        assertTestFails(PrivateListenerMethod.class, "a @Listen method must be 
public");
+        assertTestFails(PrivateListenerMethod.class, "Method listener() should 
be public");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -142,7 +142,7 @@ public class PerformanceRunnerTest {
             return new Listener();
         }
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -151,7 +151,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testInstanceListenerMethod() {
-        assertTestFails(InstanceListenerMethod.class, "a @Listen method must 
be static");
+        assertTestFails(InstanceListenerMethod.class, "Method listener() 
should be static");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -162,7 +162,7 @@ public class PerformanceRunnerTest {
             return 42;
         }
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -171,7 +171,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testWrongTypeListenerMethod() {
-        assertTestFails(WrongTypeListenerMethod.class, "a @Listen method must 
be of type Listener");
+        assertTestFails(WrongTypeListenerMethod.class, "Method listener() 
should return an object of type Listener");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -179,10 +179,10 @@ public class PerformanceRunnerTest {
 
         @Listen
         public static Listener listener() {
-            throw new RuntimeException();
+            throw new RuntimeException("error message");
         }
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -191,7 +191,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testBuggyListenerMethod() {
-        assertTestFails(BuggyListenerMethod.class, "error while invoking the 
@Listen method");
+        assertTestFails(BuggyListenerMethod.class, "error message");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -202,7 +202,7 @@ public class PerformanceRunnerTest {
             return null;
         }
 
-        @PerformanceTest
+        @PerformanceTest(warmUpInvocations = 1, runInvocations = 1)
         public void test() {
 
         }
@@ -211,7 +211,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testNullListenerMethod() {
-        assertTestFails(NullListenerMethod.class, "a @Listen method must 
return a non-null value");
+        assertTestFails(NullListenerMethod.class, "Method listener() should 
not return null");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -226,7 +226,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testExecutionStrategyNotSpecified() {
-        assertTestFails(ExecutionStrategyNotSpecified.class, "no time or 
number of invocations specified");
+        assertTestFails(ExecutionStrategyNotSpecified.class, "Method test() 
should provide a valid runInvocations or runTime");
     }
 
     @RunWith(PerformanceRunner.class)
@@ -241,7 +241,7 @@ public class PerformanceRunnerTest {
 
     @Test
     public void testWarmUpStrategyNotSpecified() {
-        assertTestFails(WarmUpStrategyNotSpecified.class, "no time or number 
of invocations specified");
+        assertTestFails(WarmUpStrategyNotSpecified.class, "Method test() 
should provide a valid warmUpInvocations or warmUpTime");
     }
 
 }

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to