You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:28:33 UTC

[sling-org-apache-sling-junit-performance] branch master created (now 38d17a0)

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

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


      at 38d17a0  SLING-7167 Adjust READMEs

This branch includes the following new commits:

     new 918b640  SLING-3756 - Create an improved JUnit test runner for performance tests
     new 57e48c9  SLING-3762 - add annotations support to PerformanceRunner. Contributed by Francesco Mari, thanks!
     new 4c89eae  Updated to parent version 20
     new 1b8651f  Update to Sling Parent POM 22 with baselining enabled
     new a84a9a8  [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0
     new 01b674c  [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0
     new a882899  [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0
     new 615f28c  [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0
     new 7bbe3be  SLING-4698 - Set parent.relativePath to empty for all modules
     new 91d5b3a  Update to Sling Parent 23
     new d15f44b  set parent version to 24 and add empty relativePath where missing
     new 4ad752f  Update the main reactor to parent 25
     new 01c49ad  Switch to parent pom 26
     new 38d17a0  SLING-7167 Adjust READMEs

The 14 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-junit-performance] 03/14: Updated to parent version 20

Posted by ro...@apache.org.
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 4c89eae474f6bdb16f4e0bd52a075b9e0b1f36d5
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Aug 1 19:16:26 2014 +0000

    Updated to parent version 20
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1615208 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index cc2f17e..199483d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>19</version>
+        <version>20</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 14/14: SLING-7167 Adjust READMEs

Posted by ro...@apache.org.
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 38d17a0e399a74fb0fbf105803992660240eb42f
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Oct 3 09:36:33 2017 +0000

    SLING-7167 Adjust READMEs
    
    add missing README
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1810781 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3b8db51
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Apache Sling JUnit Performance
+
+This module is part of the [Apache Sling](https://sling.apache.org) project.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 04/14: Update to Sling Parent POM 22 with baselining enabled

Posted by ro...@apache.org.
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 1b8651f65326a132396d76c42dd1ef2102613aa1
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Oct 1 06:36:14 2014 +0000

    Update to Sling Parent POM 22 with baselining enabled
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1628610 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 199483d..80f02ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>20</version>
+        <version>22</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 11/14: set parent version to 24 and add empty relativePath where missing

Posted by ro...@apache.org.
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 d15f44bf108b5b8f3d53f7ce956031483376bdf2
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Jul 7 08:09:17 2015 +0000

    set parent version to 24 and add empty relativePath where missing
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1689593 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 18f4e5b..8f095a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>23</version>
+        <version>24</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 05/14: [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0

Posted by ro...@apache.org.
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 a84a9a877d08ec9070b85ad27742ac7e30ed7bf5
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Thu Jan 22 12:39:57 2015 +0000

    [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1653831 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 80f02ce..fc49c5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,8 +19,7 @@
     under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -31,7 +30,7 @@
     </parent>
 
     <artifactId>org.apache.sling.junit.performance</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling JUnit Performance</name>
@@ -67,4 +66,10 @@
             <scope>provided</scope>
         </dependency>
     </dependencies>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</developerConnection>
+    <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.junit.performance-1.0.0</url>
+  </scm>
 </project>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 08/14: [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0

Posted by ro...@apache.org.
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 615f28c3dd78b07a4411e5f81291422e0dd6ba66
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Thu Jan 22 12:47:35 2015 +0000

    [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1653834 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index fc49c5a..80f02ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,8 @@
     under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -30,7 +31,7 @@
     </parent>
 
     <artifactId>org.apache.sling.junit.performance</artifactId>
-    <version>1.0.0</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling JUnit Performance</name>
@@ -66,10 +67,4 @@
             <scope>provided</scope>
         </dependency>
     </dependencies>
-
-  <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</connection>
-    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</developerConnection>
-    <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.junit.performance-1.0.0</url>
-  </scm>
 </project>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 12/14: Update the main reactor to parent 25

Posted by ro...@apache.org.
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 4ad752f439d844adba183d5b097717b36366b4f2
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Mon Oct 5 10:03:45 2015 +0000

    Update the main reactor to parent 25
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1706780 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 8f095a7..673437f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>24</version>
+        <version>25</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 07/14: [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0

Posted by ro...@apache.org.
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 a882899e43fb8fa4b9b71f8a2f9e0fdf4cc2413f
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Thu Jan 22 12:42:43 2015 +0000

    [maven-release-plugin] prepare release org.apache.sling.junit.performance-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1653833 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 80f02ce..fc49c5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,8 +19,7 @@
     under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -31,7 +30,7 @@
     </parent>
 
     <artifactId>org.apache.sling.junit.performance</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling JUnit Performance</name>
@@ -67,4 +66,10 @@
             <scope>provided</scope>
         </dependency>
     </dependencies>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</developerConnection>
+    <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.junit.performance-1.0.0</url>
+  </scm>
 </project>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 01/14: SLING-3756 - Create an improved JUnit test runner for performance tests

Posted by ro...@apache.org.
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 918b6403c2d293a8c257a91549a557a5691e16b6
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Thu Jul 10 14:09:33 2014 +0000

    SLING-3756 - Create an improved JUnit test runner for performance tests
    
    * applied patch from Francesco Mari (Thanks!!)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1609464 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  70 ++++++
 .../performance/impl/InvokePerformanceBlock.java   |  85 +++++++
 .../performance/impl/InvokePerformanceMethod.java  |  48 ++++
 .../sling/junit/performance/impl/Listeners.java    | 119 ++++++++++
 .../junit/performance/impl/PerformanceMethod.java  |  61 +++++
 .../performance/listener/StatisticsListener.java   |  68 ++++++
 .../sling/junit/performance/runner/Listen.java     |  30 +++
 .../sling/junit/performance/runner/Listener.java   |  58 +++++
 .../performance/runner/PerformanceRunner.java      | 145 ++++++++++++
 .../junit/performance/runner/PerformanceTest.java  |  37 +++
 .../performance/runner/PerformanceRunnerTest.java  | 247 +++++++++++++++++++++
 11 files changed, 968 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..cc2f17e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>19</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.junit.performance</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling JUnit Performance</name>
+    <description>Provides utilities for JUnit to run performance tests and report results</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <version>1.3</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-math</artifactId>
+            <version>2.2</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
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
new file mode 100644
index 0000000..8af19e5
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
@@ -0,0 +1,85 @@
+/*
+ * 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/InvokePerformanceMethod.java b/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
new file mode 100644
index 0000000..ed8b5c7
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
@@ -0,0 +1,48 @@
+/*
+ * 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 InvokePerformanceMethod extends Statement {
+
+    private final TestClass testClass;
+
+    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;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        listeners.iterationStarted(testClass.getName(), method.getName());
+        inner.evaluate();
+        listeners.iterationFinished(testClass.getName(), method.getName());
+    }
+
+}
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
new file mode 100644
index 0000000..1a7b861
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
@@ -0,0 +1,119 @@
+/*
+ * 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.apache.sling.junit.performance.runner.Listener;
+
+import java.util.List;
+
+public class Listeners {
+
+    private boolean isWarmUp;
+
+    private final List<Listener> listeners;
+
+    public Listeners(List<Listener> listeners) {
+        this.listeners = listeners;
+    }
+
+    private interface Invoker {
+
+        void invoke(Listener listener) throws Exception;
+
+    }
+
+    private void invoke(Invoker invoker) throws Exception {
+        for (Listener listener : listeners) {
+            invoker.invoke(listener);
+        }
+
+    }
+
+    public void warmUpStarted(final String className, final String testName) throws Exception {
+        isWarmUp = true;
+
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.warmUpStarted(className, testName);
+            }
+
+        });
+    }
+
+    public void warmUpFinished(final String className, final String testName) throws Exception {
+        isWarmUp = false;
+
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.warmUpFinished(className, testName);
+            }
+
+        });
+    }
+
+    public void executionStarted(final String className, final String testName) throws Exception {
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.executionStarted(className, testName);
+            }
+
+        });
+    }
+
+    public void executionFinished(final String className, final String testName) throws Exception {
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                listener.executionFinished(className, testName);
+            }
+
+        });
+    }
+
+    public void iterationStarted(final String className, final String testName) throws Exception {
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                if (isWarmUp) {
+                    listener.warmUpIterationStarted(className, testName);
+                } else {
+                    listener.executionIterationStarted(className, testName);
+                }
+            }
+
+        });
+    }
+
+    public void iterationFinished(final String className, final String testName) throws Exception {
+        invoke(new Invoker() {
+
+            public void invoke(Listener listener) throws Exception {
+                if (isWarmUp) {
+                    listener.warmUpIterationFinished(className, testName);
+                } else {
+                    listener.executionIterationFinished(className, testName);
+                }
+            }
+
+        });
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java b/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
new file mode 100644
index 0000000..296a030
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
@@ -0,0 +1,61 @@
+/*
+ * 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.apache.sling.junit.performance.runner.PerformanceTest;
+import org.junit.runners.model.FrameworkMethod;
+
+public class PerformanceMethod {
+
+    private final FrameworkMethod method;
+
+    public PerformanceMethod(FrameworkMethod method) {
+        this.method = method;
+    }
+
+    private PerformanceTest getPerformanceTestAnnotation() {
+        PerformanceTest performanceTest = method.getAnnotation(PerformanceTest.class);
+
+        if (performanceTest == null) {
+            throw new IllegalStateException("a performance method should be annotated with @PerformanceTest");
+        }
+
+        return performanceTest;
+    }
+
+    public int getWarmUpTime() {
+        return getPerformanceTestAnnotation().warmUpTime();
+    }
+
+    public int getWarmUpInvocations() {
+        return getPerformanceTestAnnotation().warmUpInvocations();
+    }
+
+    public int getRunTime() {
+        return getPerformanceTestAnnotation().runTime();
+    }
+
+    public int getRunInvocations() {
+        return getPerformanceTestAnnotation().runInvocations();
+    }
+
+    public String getName() {
+        return method.getName();
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java b/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
new file mode 100644
index 0000000..3bd7ad9
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
@@ -0,0 +1,68 @@
+/*
+ * 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.listener;
+
+import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
+import org.apache.sling.junit.performance.runner.Listener;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A performance test listener which computes statistics about the execution of a test and makes them available in form
+ * of a {@link org.apache.commons.math.stat.descriptive.DescriptiveStatistics} object.
+ * <p/>
+ * Clients of this listener are supposed to subclass it and to override the {@link #executionStatistics} method to react
+ * when new statistics for a method are available.
+ */
+public abstract class StatisticsListener extends Listener {
+
+    private DescriptiveStatistics statistics;
+
+    private long begin;
+
+    @Override
+    public void executionStarted(String className, String testName) throws Exception {
+        statistics = new DescriptiveStatistics();
+    }
+
+    @Override
+    public void executionIterationStarted(String className, String testName) throws Exception {
+        begin = System.nanoTime();
+    }
+
+    @Override
+    public void executionIterationFinished(String className, String testName) throws Exception {
+        statistics.addValue(TimeUnit.MILLISECONDS.convert(System.nanoTime() - begin, TimeUnit.NANOSECONDS));
+    }
+
+    @Override
+    public void executionFinished(String className, String testName) throws Exception {
+        executionStatistics(className, testName, statistics);
+    }
+
+    /**
+     * This method is called when new statistics are available for a performance method.
+     *
+     * @param className  Name of the class containing the performance test.
+     * @param testName   Name of the method implementing the performance test.
+     * @param statistics Statistics about the executions of the performance test.
+     * @throws Exception
+     */
+    protected abstract void executionStatistics(String className, String testName, DescriptiveStatistics statistics) throws Exception;
+
+}
diff --git a/src/main/java/org/apache/sling/junit/performance/runner/Listen.java b/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
new file mode 100644
index 0000000..5d9b422
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * Mark a static method or a static instance variable as a listener for a performance test. The variable or the result
+ * type of the method must be a {@link Listener} or a subclass of it.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Listen {
+
+}
diff --git a/src/main/java/org/apache/sling/junit/performance/runner/Listener.java b/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
new file mode 100644
index 0000000..a5d859c
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+/**
+ * Base class for Listener classes with empty methods for every possible event. A listener is made available to the
+ * {@link PerformanceRunner} using the {@link Listen} annotation.
+ */
+public class Listener {
+
+    public void warmUpStarted(String className, String testName) throws Exception {
+
+    }
+
+    public void warmUpFinished(String className, String testName) throws Exception {
+
+    }
+
+    public void executionStarted(String className, String testName) throws Exception {
+
+    }
+
+    public void executionFinished(String className, String testName) throws Exception {
+
+    }
+
+    public void warmUpIterationStarted(String className, String testName) throws Exception {
+
+    }
+
+    public void executionIterationStarted(String className, String testName) throws Exception {
+
+    }
+
+    public void warmUpIterationFinished(String className, String testName) throws Exception {
+
+    }
+
+    public void executionIterationFinished(String className, String testName) throws Exception {
+
+    }
+
+}
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
new file mode 100644
index 0000000..d9aa3de
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
@@ -0,0 +1,145 @@
+/*
+ * 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.apache.sling.junit.performance.impl.InvokePerformanceBlock;
+import org.apache.sling.junit.performance.impl.InvokePerformanceMethod;
+import org.apache.sling.junit.performance.impl.Listeners;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Custom runner to execute performance tests using JUnit.
+ * <p/>
+ * For a method to be executed as a performance test, it must be annotated with {@link PerformanceTest}. Every time this
+ * annotation is specified, the user must also specify the warm up and execution strategy, because these information are
+ * mandatory for the runner to work properly. The warm up and execution strategy can be provided in two ways: by
+ * specifying the number of executions to run, or by specifying the amount of time the method should run.
+ * <p/>
+ * 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.
+ */
+public class PerformanceRunner extends BlockJUnit4ClassRunner {
+
+    private Listeners listeners;
+
+    public PerformanceRunner(Class<?> testClass) throws InitializationError {
+        super(testClass);
+
+        try {
+            listeners = new Listeners(readListeners());
+        } catch (Exception e) {
+            throw new InitializationError(e);
+        }
+    }
+
+    @Override
+    protected List<FrameworkMethod> computeTestMethods() {
+        return getTestClass().getAnnotatedMethods(PerformanceTest.class);
+    }
+
+    @Override
+    protected Statement methodBlock(FrameworkMethod method) {
+        return new InvokePerformanceBlock(getTestClass(), method, super.methodBlock(method), listeners);
+    }
+
+    @Override
+    protected Statement methodInvoker(FrameworkMethod method, Object test) {
+        return new InvokePerformanceMethod(getTestClass(), method, super.methodInvoker(method, test), listeners);
+    }
+
+    private List<Listener> readListeners() throws Exception {
+        List<Listener> listeners = new ArrayList<Listener>();
+
+        listeners.addAll(readListenersFromStaticFields());
+        listeners.addAll(readListenersFromStaticMethods());
+
+        return listeners;
+    }
+
+    private List<Listener> readListenersFromStaticMethods() throws Exception {
+        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);
+            }
+
+            if (listener == null) {
+                throw new IllegalArgumentException("a @Listen method must return a non-null value");
+            }
+
+            listeners.add(listener);
+        }
+
+        return listeners;
+    }
+
+    private List<Listener> readListenersFromStaticFields() throws Exception {
+        List<Listener> reporters = 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");
+            }
+
+            reporters.add(listener);
+        }
+
+        return reporters;
+    }
+
+}
+
diff --git a/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java b/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
new file mode 100644
index 0000000..19442a4
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * Annotate a method to mark it as a performance test. It also specifies the warm up and execution strategy.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PerformanceTest {
+
+    int warmUpTime() default 0;
+
+    int runTime() default 0;
+
+    int runInvocations() default 0;
+
+    int warmUpInvocations() default 0;
+
+}
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
new file mode 100644
index 0000000..5141b5a
--- /dev/null
+++ b/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+
+public class PerformanceRunnerTest {
+
+    private Result runTest(Class<?> testClass) {
+        return JUnitCore.runClasses(testClass);
+    }
+
+    private void assertTestFails(Class<?> testClass, String message) {
+        Result result = runTest(testClass);
+
+        boolean isInitializationError = false;
+
+        for (Failure failure : result.getFailures()) {
+            isInitializationError = isInitializationError || failure.getException().getMessage().equals(message);
+        }
+
+        Assert.assertEquals(true, isInitializationError);
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class PrivateListenerField {
+
+        @Listen
+        private static Listener listener = new Listener();
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testPrivateListenerField() {
+        assertTestFails(PrivateListenerField.class, "a @Listen field must be public");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class InstanceListenerField {
+
+        @Listen
+        public Listener listener = new Listener();
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testInstanceListenerField() {
+        assertTestFails(InstanceListenerField.class, "a @Listen field must be static");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class WrongTypeListenerField {
+
+        @Listen
+        public static Integer listener = 42;
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testWrongTypeListenerField() {
+        assertTestFails(WrongTypeListenerField.class, "a @Listen field must be of type Listener");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class NullListenerField {
+
+        @Listen
+        public static Listener listener = null;
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testNullListenerField() {
+        assertTestFails(NullListenerField.class, "a @Listen field must not be null");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class PrivateListenerMethod {
+
+        @Listen
+        private static Listener listener() {
+            return new Listener();
+        }
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testPrivateListenerMethod() {
+        assertTestFails(PrivateListenerMethod.class, "a @Listen method must be public");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class InstanceListenerMethod {
+
+        @Listen
+        public Listener listener() {
+            return new Listener();
+        }
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testInstanceListenerMethod() {
+        assertTestFails(InstanceListenerMethod.class, "a @Listen method must be static");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class WrongTypeListenerMethod {
+
+        @Listen
+        public static Integer listener() {
+            return 42;
+        }
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testWrongTypeListenerMethod() {
+        assertTestFails(WrongTypeListenerMethod.class, "a @Listen method must be of type Listener");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class BuggyListenerMethod {
+
+        @Listen
+        public static Listener listener() {
+            throw new RuntimeException();
+        }
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testBuggyListenerMethod() {
+        assertTestFails(BuggyListenerMethod.class, "error while invoking the @Listen method");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class NullListenerMethod {
+
+        @Listen
+        public static Listener listener() {
+            return null;
+        }
+
+        @PerformanceTest
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testNullListenerMethod() {
+        assertTestFails(NullListenerMethod.class, "a @Listen method must return a non-null value");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class ExecutionStrategyNotSpecified {
+
+        @PerformanceTest(warmUpInvocations = 10)
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testExecutionStrategyNotSpecified() {
+        assertTestFails(ExecutionStrategyNotSpecified.class, "no time or number of invocations specified");
+    }
+
+    @RunWith(PerformanceRunner.class)
+    public static class WarmUpStrategyNotSpecified {
+
+        @PerformanceTest(runInvocations = 10)
+        public void test() {
+
+        }
+
+    }
+
+    @Test
+    public void testWarmUpStrategyNotSpecified() {
+        assertTestFails(WarmUpStrategyNotSpecified.class, "no time or number of invocations specified");
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 10/14: Update to Sling Parent 23

Posted by ro...@apache.org.
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 91d5b3ae68b39af3ae6ab974e4220b36ebec5257
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu Jun 25 13:08:16 2015 +0000

    Update to Sling Parent 23
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1687500 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index fdf26c2..18f4e5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>22</version>
+        <version>23</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 13/14: Switch to parent pom 26

Posted by ro...@apache.org.
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 01c49adda8d019bcb2407e4cdd9097940ea845c8
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun Jan 3 14:07:46 2016 +0000

    Switch to parent pom 26
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1722720 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 673437f..2ab7cad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>25</version>
+        <version>26</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 06/14: [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0

Posted by ro...@apache.org.
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 01b674c0353125000bb91a67f6c0423202015e2e
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Thu Jan 22 12:42:23 2015 +0000

    [maven-release-plugin] rollback the release of org.apache.sling.junit.performance-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1653832 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index fc49c5a..80f02ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,8 @@
     under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -30,7 +31,7 @@
     </parent>
 
     <artifactId>org.apache.sling.junit.performance</artifactId>
-    <version>1.0.0</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling JUnit Performance</name>
@@ -66,10 +67,4 @@
             <scope>provided</scope>
         </dependency>
     </dependencies>
-
-  <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</connection>
-    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.junit.performance-1.0.0</developerConnection>
-    <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.junit.performance-1.0.0</url>
-  </scm>
 </project>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 02/14: SLING-3762 - add annotations support to PerformanceRunner. Contributed by Francesco Mari, thanks!

Posted by ro...@apache.org.
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 <bd...@apache.org>
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
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-junit-performance] 09/14: SLING-4698 - Set parent.relativePath to empty for all modules

Posted by ro...@apache.org.
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 7bbe3be1314793b1571070cf81ae7df9049c7de4
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 7 10:14:40 2015 +0000

    SLING-4698 - Set parent.relativePath to empty for all modules
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1678154 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 80f02ce..fdf26c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
         <version>22</version>
-        <relativePath>../../../parent/pom.xml</relativePath>
+        <relativePath/>
     </parent>
 
     <artifactId>org.apache.sling.junit.performance</artifactId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.