sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From asa...@apache.org
Subject svn commit: r1609464 - in /sling/trunk/testing: junit/performance/ junit/performance/src/ junit/performance/src/main/ junit/performance/src/main/java/ junit/performance/src/main/java/org/ junit/performance/src/main/java/org/apache/ junit/performance/sr...
Date Thu, 10 Jul 2014 14:09:34 GMT
Author: asanso
Date: Thu Jul 10 14:09:33 2014
New Revision: 1609464

URL: http://svn.apache.org/r1609464
Log:
SLING-3756 - Create an improved JUnit test runner for performance tests

* applied patch from Francesco Mari (Thanks!!)

Added:
    sling/trunk/testing/junit/performance/
    sling/trunk/testing/junit/performance/pom.xml
    sling/trunk/testing/junit/performance/src/
    sling/trunk/testing/junit/performance/src/main/
    sling/trunk/testing/junit/performance/src/main/java/
    sling/trunk/testing/junit/performance/src/main/java/org/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
    sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
    sling/trunk/testing/junit/performance/src/test/
    sling/trunk/testing/junit/performance/src/test/java/
    sling/trunk/testing/junit/performance/src/test/java/org/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/
    sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
    sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/SamplePerformanceTest.java
Modified:
    sling/trunk/testing/samples/sample-tests/pom.xml
    sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareWithRuleTest.java

Added: sling/trunk/testing/junit/performance/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/pom.xml?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/pom.xml (added)
+++ sling/trunk/testing/junit/performance/pom.xml Thu Jul 10 14:09:33 2014
@@ -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

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceBlock.java
Thu Jul 10 14:09:33 2014
@@ -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();
+        }
+    }
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/InvokePerformanceMethod.java
Thu Jul 10 14:09:33 2014
@@ -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());
+    }
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/Listeners.java
Thu Jul 10 14:09:33 2014
@@ -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);
+                }
+            }
+
+        });
+    }
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/impl/PerformanceMethod.java
Thu Jul 10 14:09:33 2014
@@ -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();
+    }
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/listener/StatisticsListener.java
Thu Jul 10 14:09:33 2014
@@ -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;
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listen.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listen.java
Thu Jul 10 14:09:33 2014
@@ -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 {
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listener.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/Listener.java
Thu Jul 10 14:09:33 2014
@@ -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
{
+
+    }
+
+}

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceRunner.java
Thu Jul 10 14:09:33 2014
@@ -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;
+    }
+
+}
+

Added: sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
(added)
+++ sling/trunk/testing/junit/performance/src/main/java/org/apache/sling/junit/performance/runner/PerformanceTest.java
Thu Jul 10 14:09:33 2014
@@ -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;
+
+}

Added: sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
(added)
+++ sling/trunk/testing/junit/performance/src/test/java/org/apache/sling/junit/performance/runner/PerformanceRunnerTest.java
Thu Jul 10 14:09:33 2014
@@ -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");
+    }
+
+}

Modified: sling/trunk/testing/samples/sample-tests/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/sample-tests/pom.xml?rev=1609464&r1=1609463&r2=1609464&view=diff
==============================================================================
--- sling/trunk/testing/samples/sample-tests/pom.xml (original)
+++ sling/trunk/testing/samples/sample-tests/pom.xml Thu Jul 10 14:09:33 2014
@@ -97,6 +97,11 @@
             <version>1.0.9-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
-        
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.junit.performance</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareWithRuleTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareWithRuleTest.java?rev=1609464&r1=1609463&r2=1609464&view=diff
==============================================================================
--- sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareWithRuleTest.java
(original)
+++ sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareWithRuleTest.java
Thu Jul 10 14:09:33 2014
@@ -22,8 +22,6 @@ import org.apache.sling.junit.annotation
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.apache.sling.junit.rules.Service;
 

Added: sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/SamplePerformanceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/SamplePerformanceTest.java?rev=1609464&view=auto
==============================================================================
--- sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/SamplePerformanceTest.java
(added)
+++ sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/SamplePerformanceTest.java
Thu Jul 10 14:09:33 2014
@@ -0,0 +1,90 @@
+/*
+ * 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.testing.samples.sampletests;
+
+import org.apache.sling.junit.performance.runner.Listen;
+import org.apache.sling.junit.performance.runner.Listener;
+import org.apache.sling.junit.performance.runner.PerformanceRunner;
+import org.apache.sling.junit.performance.runner.PerformanceTest;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+
+// Performance tests are run using the PerformanceRunner custom test runner
+
+@RunWith(PerformanceRunner.class)
+public class SamplePerformanceTest {
+
+    private static HashMap<String, String> map;
+
+    private static String key;
+
+    private static String value;
+
+    // You can declare one or more listeners. Listeners are subclasses of Listener and are
provided by a static field
+    // or method annotated by @Listen
+
+    @Listen
+    public static Listener createTestDataListener = new Listener() {
+
+        @Override
+        public void warmUpStarted(String className, String testName) throws Exception {
+            map = new HashMap<String, String>();
+        }
+
+        @Override
+        public void executionFinished(String className, String testName) throws Exception
{
+            map = null;
+        }
+
+        @Override
+        public void warmUpIterationStarted(String className, String testName) throws Exception
{
+            generateRandomKeyValue();
+        }
+
+        @Override
+        public void executionIterationStarted(String className, String testName) throws Exception
{
+            generateRandomKeyValue();
+        }
+
+        private void generateRandomKeyValue() {
+            long time = System.nanoTime();
+
+            key = Long.toString(time);
+            value = Long.toString(time + 1);
+        }
+
+    };
+
+    // A performance test must be annotated with @PerformanceTest to be recognized by the
custom runner. This
+    // performance tests is executed using a strategy based on the number of invocations.
In this case, we want to
+    // execute the method 10 times to warm up, and 1000 times to measure the real performance.
+
+    @PerformanceTest(warmUpInvocations = 10, runInvocations = 1000)
+    public void testSameKeyDifferentValues() {
+        map.put("key", value);
+    }
+
+    // Another execution strategy is based on the number of seconds. In this case, we execute
the warm up for three
+    // seconds, then we measure the performance for five seconds.
+
+    @PerformanceTest(warmUpTime = 3, runTime = 5)
+    public void testDifferentKeysAndValues() {
+        map.put(key, value);
+    }
+
+}
\ No newline at end of file



Mime
View raw message