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