You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:26:45 UTC
[sling-tooling-jenkins] 05/27: SLING-2593 - Improvement for the
Sling performance tools. Adding patch provided from Christian Vazzolla.
Thanks Christian!
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.performance.base-0.0.2
in repository https://gitbox.apache.org/repos/asf/sling-tooling-jenkins.git
commit eb67a440c990e294c858ea91f2f84b36b7aa347d
Author: Antonio Sanso <as...@apache.org>
AuthorDate: Sat Sep 29 18:22:43 2012 +0000
SLING-2593 - Improvement for the Sling performance tools. Adding patch provided from Christian Vazzolla. Thanks Christian!
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/performance/base@1391855 13f79535-47bb-0310-9956-ffa450edef68
---
.../sling/performance/AbstractRepositoryTest.java | 12 +-
.../performance/FrameworkPerformanceMethod.java | 282 +++++++++++++++++++++
.../sling/performance/ParameterizedTestList.java | 70 +++++
.../sling/performance/PerformanceRunner.java | 209 +++++++++++++++
.../sling/performance/PerformanceSuiteState.java | 91 +++++++
.../org/apache/sling/performance/ReportLogger.java | 96 +++++++
.../annotation/AfterMethodInvocation.java | 25 ++
.../performance/annotation/AfterSpecificTest.java | 25 ++
.../sling/performance/annotation/AfterSuite.java | 25 ++
.../annotation/BeforeMethodInvocation.java | 25 ++
.../performance/annotation/BeforeSpecificTest.java | 25 ++
.../sling/performance/annotation/BeforeSuite.java | 25 ++
.../performance/annotation/PerformanceTest.java | 47 ++++
.../annotation/PerformanceTestSuite.java | 10 +
14 files changed, 958 insertions(+), 9 deletions(-)
diff --git a/src/main/java/org/apache/sling/performance/AbstractRepositoryTest.java b/src/main/java/org/apache/sling/performance/AbstractRepositoryTest.java
index f5f818d..ff542c5 100644
--- a/src/main/java/org/apache/sling/performance/AbstractRepositoryTest.java
+++ b/src/main/java/org/apache/sling/performance/AbstractRepositoryTest.java
@@ -26,7 +26,7 @@ import org.apache.sling.jcr.api.SlingRepository;
-public abstract class AbstractRepositoryTest extends AbstractTest {
+public abstract class AbstractRepositoryTest {
private static class ShutdownThread extends Thread {
@Override
@@ -34,7 +34,7 @@ public abstract class AbstractRepositoryTest extends AbstractTest {
try {
RepositoryUtil.stopRepository();
} catch(Exception e) {
- System.out.println("Exception in ShutdownThread:" + e);
+ //ignore for now
}
}
@@ -81,10 +81,4 @@ public abstract class AbstractRepositoryTest extends AbstractTest {
return testRoot;
}
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- if(session != null) {
- session.logout();
- }
- }}
+}
diff --git a/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java b/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java
new file mode 100644
index 0000000..1f151cc
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/FrameworkPerformanceMethod.java
@@ -0,0 +1,282 @@
+/*
+ * 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.performance;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.naming.directory.InvalidAttributesException;
+
+import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
+import org.apache.sling.performance.annotation.AfterMethodInvocation;
+import org.apache.sling.performance.annotation.BeforeMethodInvocation;
+import org.apache.sling.performance.annotation.PerformanceTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runners.model.FrameworkMethod;
+
+class FrameworkPerformanceMethod extends FrameworkMethod {
+
+ private Object target;
+ private PerformanceSuiteState performanceSuiteState;
+
+ public FrameworkPerformanceMethod(Method method, Object target, PerformanceSuiteState performanceSuiteState) {
+ super(method);
+ this.target = target;
+ this.performanceSuiteState = performanceSuiteState;
+
+ }
+
+ @Override
+ public Object invokeExplosively(Object target, Object... params) throws Throwable {
+ // Executes the test method on the supplied target
+
+ // Check if this is the first test running from this specific PerformanceSuite
+ // and run the BeforeSuite methods
+ if ((performanceSuiteState != null) && (performanceSuiteState.getBeforeSuiteMethod() != null)
+ && (performanceSuiteState.getTargetObjectSuite() != null)
+ && (performanceSuiteState.getNumberOfExecutedMethods() == 0)
+ && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)){
+ performanceSuiteState.getBeforeSuiteMethod().invoke(performanceSuiteState.getTargetObjectSuite());
+ }
+
+ // In case of a PerformanceSuite we need to run the methods annotated with Before and After
+ // ourselves as JUnit can't find them (JUnit is looking for them in the test suite class);
+ // in case we don't have to deal with a PerformanceSuite just skip this as JUnit will run the methods itself
+ if ((performanceSuiteState != null) && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)){
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, Before.class);
+ }
+
+ // Need to count the number of tests run from the PerformanceSuite
+ // so that we can call the AfterSuite method after the last test from the suite
+ // has run and the AfterSuite needs to run
+ performanceSuiteState.incrementNumberOfExecutedTestMethods();
+
+ Object response = null;
+
+ Method testMethodToInvoke = this.getMethod();
+
+ PerformanceTest performanceAnnotation = testMethodToInvoke.getAnnotation(PerformanceTest.class);
+
+ // retrieve the test configuration options
+ int warmuptime = performanceAnnotation.warmuptime();
+ int runtime = performanceAnnotation.runtime();
+ int warmupinvocations = performanceAnnotation.warmupinvocations();
+ int runinvocations = performanceAnnotation.runinvocations();
+
+ DescriptiveStatistics statistics = new DescriptiveStatistics();
+
+ //System.out.println("Warmup started - test :" + testMethodToInvoke.getName());
+
+ if (warmupinvocations != 0){
+ // Run the number of invocation specified in the annotation
+ // for warming up the system
+ for (int invocationIndex = 0; invocationIndex < warmupinvocations; invocationIndex++){
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeMethodInvocation.class);
+
+ //TODO: implement the method to run a before a specific test method
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeSpecificTest.class);
+
+ response = super.invokeExplosively(this.target, params);
+
+ //TODO: implement the method to run a after a specific test method
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterSpecificTest.class);
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterMethodInvocation.class);
+ }
+ }
+ else{
+ // Run a few iterations to warm up the system
+ long warmupEnd = System.currentTimeMillis() + warmuptime * 1000;
+ while (System.currentTimeMillis() < warmupEnd) {
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeMethodInvocation.class);
+
+ //TODO: implement the method to run a before a specific test method
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeSpecificTest.class);
+
+ response = super.invokeExplosively(this.target, params);
+
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterSpecificTest.class);
+ //TODO: implement the method to run a after a specific test method
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterMethodInvocation.class);
+ }
+ }
+
+ //System.out.println("Warmup ended - test :" + testMethodToInvoke.getName());
+ if (runinvocations != 0){
+ // Run the specified number of iterations and capture the execution times
+ for (int invocationIndex = 0; invocationIndex < runinvocations; invocationIndex++){
+
+ response = this.invokeTimedTestMethod(testMethodToInvoke, statistics, params);
+ }
+ }
+ else{
+ // Run test iterations and capture the execution times
+ long runtimeEnd = System.currentTimeMillis() + runtime * 1000;
+
+ while (System.currentTimeMillis() < runtimeEnd) {
+
+ response = this.invokeTimedTestMethod(testMethodToInvoke, statistics, params);
+
+ }
+ }
+
+ if (statistics.getN() > 0) {
+ ReportLogger.writeReport(this.target.getClass().getName(), this.performanceSuiteState.testSuiteName,
+ getMethod().getName() , statistics, ReportLogger.ReportType.TXT);
+ }
+
+ // In case of a PerformanceSuite we need to run the methods annotated with Before and After
+ // ourselves as JUnit can't find them; in case we don't have to deal with a PerformanceSuite
+ // just skip this as JUnit will run the methods itself
+ if ((performanceSuiteState != null)
+ && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)){
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, After.class);
+ }
+
+
+ // Check if this is the last test running from a PerformanceSuite
+ // and run the AfterSuite method
+ if ((performanceSuiteState != null) && (performanceSuiteState.getAfterSuiteMethod() != null)
+ && (performanceSuiteState.getTargetObjectSuite() != null)
+ && (performanceSuiteState.getNumberOfExecutedMethods() == performanceSuiteState.getNumberOfMethodsInSuite())
+ && !performanceSuiteState.testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)){
+ performanceSuiteState.getAfterSuiteMethod().invoke(performanceSuiteState.getTargetObjectSuite());
+
+ }
+
+ return response;
+ }
+
+ /**
+ * Method that runs 1 invocation of the timed test method
+ * @param testMethodToInvoke the test method to invoke
+ * @param statistics the statistics object that collects the results
+ * @param params the parameters for the invocation of the test method
+ * @return the response from the method invocation
+ * @throws Throwable
+ */
+ private Object invokeTimedTestMethod(Method testMethodToInvoke, DescriptiveStatistics statistics, Object... params)
+ throws Throwable{
+
+ Object response = null;
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeMethodInvocation.class);
+
+ //TODO: implement the method to run a before a specific test method
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, BeforeSpecificTest.class);
+
+ // timing the test method execution
+ //System.out.println("Start test: " + testMethodToInvoke.getName());
+ long start = System.nanoTime();
+ response = super.invokeExplosively(this.target, params);
+ long timeMilliseconds =TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
+ statistics.addValue(timeMilliseconds);
+
+ //System.out.println("End test: " + testMethodToInvoke.getName());
+
+ //System.out.println("Test execution time (ms): " + timeMilliseconds);
+
+ //TODO: implement the method to run a after a specific test method
+ //recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterSpecificTest.class);
+
+ recursiveCallSpecificMethod(this.target.getClass(), this.target, AfterMethodInvocation.class);
+
+ return response;
+ }
+
+ /**
+ * Recursively call a specific method annotated with a custom annotation
+ * @param test the test class that contains the method
+ * @param instance the instance on which will run the method
+ * @param methodAnnotation the method annotation to look for
+ * @throws InvocationTargetException
+ * @throws InvalidAttributesException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ */
+ @SuppressWarnings({"rawtypes"})
+ private void recursiveCallSpecificMethod(Class test, Object instance, Class<? extends Annotation> methodAnnotation) throws InvocationTargetException, InvalidAttributesException, IllegalAccessException, InstantiationException{
+ if (test.getSuperclass() != null){
+ recursiveCallSpecificMethod(test.getSuperclass(), instance, methodAnnotation);
+ }
+
+ Method testMethod = getSpecificTestMethod(test, methodAnnotation);
+ if (testMethod != null){
+ if (!testMethod.isAccessible()){
+ testMethod.setAccessible(true);
+ }
+ testMethod.invoke(instance);
+ }
+ }
+
+ /**
+ * Get the method annotated with the custom annotation
+ * @param testClass the test class on which to look for the method
+ * @param methodAnnotation the method annotation to look for
+ * @return
+ * @throws InvalidAttributesException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ */
+ @SuppressWarnings({"rawtypes"})
+ private Method getSpecificTestMethod(Class testClass, Class<? extends Annotation> methodAnnotation) throws InvalidAttributesException, IllegalAccessException, InstantiationException{
+
+ Method[] methodsToReturn = getSpecificMethods(testClass,methodAnnotation);
+ Method methodToReturn = null;
+ if (methodsToReturn.length == 1){
+ methodToReturn = methodsToReturn[0];
+ }
+ else if (methodsToReturn.length > 1){
+ throw new InvalidAttributesException("Only 1 non parameterized before method accepted");
+ }
+
+ return methodToReturn;
+ }
+
+
+ /**
+ * Retrieve all the specific methods from test class
+ * @param testClass the test class that we need to search in
+ * @param annotation the annotation that we should look for
+ * @return the list with the methods that have the specified annotation
+ */
+ @SuppressWarnings({"rawtypes"})
+ private Method[] getSpecificMethods(Class testClass, Class<? extends Annotation> annotation){
+ Method[] allMethods = testClass.getDeclaredMethods();
+
+ List<Method> methodListResult = new ArrayList<Method>();
+
+ for(Method testMethod : allMethods){
+ if (testMethod.isAnnotationPresent(annotation)){
+ methodListResult.add(testMethod);
+ }
+ }
+ return methodListResult.toArray(new Method[]{});
+ }
+
+}
+
+
diff --git a/src/main/java/org/apache/sling/performance/ParameterizedTestList.java b/src/main/java/org/apache/sling/performance/ParameterizedTestList.java
new file mode 100644
index 0000000..bfd7cd0
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/ParameterizedTestList.java
@@ -0,0 +1,70 @@
+/*
+ * 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.performance;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents the object that will be returned by the method
+ * in which a new PerformanceTestSuite is created
+ *
+ */
+public class ParameterizedTestList {
+
+ public static final String TEST_CASE_ONLY = "TESTCASEONLY";
+
+ private List<Object> testObjectList = new ArrayList<Object>();
+ private String testSuiteTitle = TEST_CASE_ONLY;
+ private Map<String, String> parameters = new LinkedHashMap<String, String>();
+ private Map<String, Object> parametersObjects = new LinkedHashMap<String, Object>();
+
+ public Map<String, Object> getParametersObjects() {
+ return parametersObjects;
+ }
+
+ public void addParameterObject(String key, Object parameterObject) {
+ this.parametersObjects.put(key, parameterObject);
+ }
+
+ public Map<String, String> getParameters() {
+ return parameters;
+ }
+
+ public void addParameter(String key, String value) {
+ parameters.put(key, value);
+ }
+
+ public List<Object> getTestObjectList() {
+ return testObjectList;
+ }
+
+ public void addTestObject(Object testObject) {
+ testObjectList.add(testObject);
+ }
+
+ public String getTestSuiteName() {
+ return testSuiteTitle;
+ }
+
+ public void setTestSuiteTitle(String testSuiteTitle) {
+ this.testSuiteTitle = testSuiteTitle;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/performance/PerformanceRunner.java b/src/main/java/org/apache/sling/performance/PerformanceRunner.java
new file mode 100644
index 0000000..cc971da
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/PerformanceRunner.java
@@ -0,0 +1,209 @@
+/*
+ * 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.performance;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.sling.performance.annotation.AfterSuite;
+import org.apache.sling.performance.annotation.BeforeSuite;
+import org.apache.sling.performance.annotation.PerformanceTest;
+import org.apache.sling.performance.annotation.PerformanceTestSuite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+
+
+/**
+ * The custom JUnit runner that collects the performance tests
+ *
+ */
+public class PerformanceRunner extends BlockJUnit4ClassRunner {
+ protected LinkedList<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
+ private List<PerformanceSuiteState> suitesState = new ArrayList<PerformanceSuiteState>();
+
+
+ public PerformanceRunner(Class<?> clazz) throws InitializationError {
+ super(clazz);
+ try {
+ computeTests();
+ }
+ catch (Exception e) {
+ throw new InitializationError(e);
+ }
+ }
+
+ /**
+ * Compute the tests that will be run
+ * @throws Exception
+ */
+ protected void computeTests() throws Exception {
+ tests.addAll(super.computeTestMethods());
+
+ // count the performance tests
+ tests.addAll(computePerformanceTests());
+
+ // This is called here to ensure the test class constructor is called at least
+ // once during testing.
+ createTest();
+ }
+
+ /**
+ * Compute performance tests
+ * @return the list containing the performance test methods
+ * @throws Exception
+ */
+ protected Collection<? extends FrameworkMethod> computePerformanceTests() throws Exception {
+ List<FrameworkPerformanceMethod> tests = new LinkedList<FrameworkPerformanceMethod>();
+
+ List<Object> testObjects = new ArrayList<Object>();
+ ParameterizedTestList testCenter = new ParameterizedTestList();
+
+ // Retrieve the test objects included in the Performance test suite
+ for (FrameworkMethod method: getTestClass().getAnnotatedMethods(PerformanceTestSuite.class)) {
+ Object targetObject = getTestClass().getJavaClass().newInstance();
+ if (method.getMethod().getReturnType().equals(ParameterizedTestList.class)){
+ testCenter = (ParameterizedTestList) method.getMethod().invoke(targetObject);
+ testObjects = testCenter.getTestObjectList();
+ }
+ else{
+ throw new InitializationError("Wrong signature for the @PerformanceSuite method");
+ }
+ }
+
+ // Retrieve the methods before running the methods from the test suite
+ List<FrameworkMethod> beforeSuiteMethods = getTestClass().getAnnotatedMethods(BeforeSuite.class);
+ if (beforeSuiteMethods.size() > 1){
+ throw new InitializationError("Only one @BeforeSuite method is allowed for a @PerformanceSuite");
+ }
+
+ // Retrieve the methods before running the methods from the test suite
+ List<FrameworkMethod> afterSuiteMethods = getTestClass().getAnnotatedMethods(AfterSuite.class);
+ if (afterSuiteMethods.size() > 1){
+ throw new InitializationError("Only one @AfterSuite method is allowed for a @PerformanceSuite");
+ }
+
+ PerformanceSuiteState current = null;
+ boolean suiteAlreadyRegistered = false;
+
+ for(PerformanceSuiteState suiteState : suitesState){
+ if (suiteState.testSuiteName.equals(testCenter.getTestSuiteName())){
+ suiteAlreadyRegistered = true;
+ suiteState.incrementNumberOfTestMethodsInSuite();
+ current = suiteState;
+ break;
+ }
+ }
+
+ // Create a new PerformanceSuiteState object
+ PerformanceSuiteState newSuite = new PerformanceSuiteState(testCenter.getTestSuiteName());
+
+ if (!suiteAlreadyRegistered){
+ if (beforeSuiteMethods.size() == 1){
+ newSuite.setBeforeSuiteMethod(beforeSuiteMethods.get(0).getMethod());
+ }
+ if (afterSuiteMethods.size() == 1){
+ newSuite.setAfterSuiteMethod(afterSuiteMethods.get(0).getMethod());
+ }
+
+ current = newSuite;
+ newSuite.setTargetObjectSuite(getTestClass().getJavaClass().newInstance());
+
+ }
+
+
+ // In case there are any objects retrieved from the Performance Suite
+ // we should add them to the tests that will be run and increase the number of methods
+ // contained in the PerformaceSuite
+ if (!testObjects.isEmpty()){
+ for (Object testObject : testObjects){
+ // retrieve the test methods from the test classes
+ Method[] testMethods = getSpecificMethods(testObject.getClass(), PerformanceTest.class);
+
+ if (!suiteAlreadyRegistered){
+ newSuite.incrementNumberOfTestMethodsInSuite();
+ }
+
+ for (Method method: testMethods){
+ FrameworkPerformanceMethod performaceTestMethod = new FrameworkPerformanceMethod(method, testObject, current);
+ tests.add(performaceTestMethod);
+ }
+ }
+
+ // add the new suite to the list of suites
+ suitesState.add(newSuite);
+ }
+
+ // Retrieve the performance tests in the case we don't have a performance test suite
+ for (FrameworkMethod method: getTestClass().getAnnotatedMethods(PerformanceTest.class)) {
+ Object targetObject = getTestClass().getJavaClass().newInstance();
+ FrameworkPerformanceMethod performaceTestMethod = new FrameworkPerformanceMethod(method.getMethod(), targetObject, current);
+ tests.add(performaceTestMethod);
+ }
+
+ return tests;
+ }
+
+
+ /**
+ * Retrieve specific method from test class
+ * @param testClass the test class that we need to search in
+ * @param annotation the annotation that we should look for
+ * @return the list with the methods that have the specified annotation
+ */
+ @SuppressWarnings({"rawtypes"})
+ private Method[] getSpecificMethods(Class testClass, Class<? extends Annotation> annotation){
+ Method[] allMethods = testClass.getDeclaredMethods();
+
+ List<Method> methodListResult = new ArrayList<Method>();
+
+ for(Method testMethod : allMethods){
+ if (testMethod.isAnnotationPresent(annotation)){
+ methodListResult.add(testMethod);
+ }
+ }
+ return methodListResult.toArray(new Method[]{});
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.junit.runners.BlockJUnit4ClassRunner#computeTestMethods()
+ */
+ @Override
+ protected List<FrameworkMethod> computeTestMethods() {
+ return tests;
+ }
+
+ /**
+ * Need to override method otherwise the validation will fail because of some
+ * hardcoded conditions in JUnit
+ */
+ @Override
+ protected void validateInstanceMethods(List<Throwable> errors) {
+ validatePublicVoidNoArgMethods(After.class, false, errors);
+ validatePublicVoidNoArgMethods(Before.class, false, errors);
+ validateTestMethods(errors);
+ }
+
+
+}
diff --git a/src/main/java/org/apache/sling/performance/PerformanceSuiteState.java b/src/main/java/org/apache/sling/performance/PerformanceSuiteState.java
new file mode 100644
index 0000000..337cad0
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/PerformanceSuiteState.java
@@ -0,0 +1,91 @@
+/*
+ * 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.performance;
+
+import java.lang.reflect.Method;
+
+public class PerformanceSuiteState {
+
+ public String testSuiteName = ParameterizedTestList.TEST_CASE_ONLY;
+
+ private Method beforeSuiteMethod;
+ private Method afterSuiteMethod;
+ private int numberOfMethodsInSuite = 0;
+ private int numberOfExecutedMethods = 0;
+ private Object targetObjectSuite;
+
+ public PerformanceSuiteState(String testSuiteName){
+ this.testSuiteName = testSuiteName;
+ }
+
+ public void incrementNumberOfTestMethodsInSuite(){
+ numberOfMethodsInSuite++;
+ }
+
+ public void incrementNumberOfExecutedTestMethods(){
+ numberOfExecutedMethods++;
+ }
+
+ public String getTestSuiteName() {
+ return testSuiteName;
+ }
+
+ public void setTestSuiteName(String testSuiteName) {
+ this.testSuiteName = testSuiteName;
+ }
+
+ public Method getBeforeSuiteMethod() {
+ return beforeSuiteMethod;
+ }
+
+ public void setBeforeSuiteMethod(Method beforeSuiteMethod) {
+ this.beforeSuiteMethod = beforeSuiteMethod;
+ }
+
+ public Method getAfterSuiteMethod() {
+ return afterSuiteMethod;
+ }
+
+ public void setAfterSuiteMethod(Method afterSuiteMethod) {
+ this.afterSuiteMethod = afterSuiteMethod;
+ }
+
+ public int getNumberOfMethodsInSuite() {
+ return numberOfMethodsInSuite;
+ }
+
+ public void setNumberOfMethodsInSuite(int numberOfMethodsInSuite) {
+ this.numberOfMethodsInSuite = numberOfMethodsInSuite;
+ }
+
+ public int getNumberOfExecutedMethods() {
+ return numberOfExecutedMethods;
+ }
+
+ public void setNumberOfExecutedMethods(int numberOfExecutedMethods) {
+ this.numberOfExecutedMethods = numberOfExecutedMethods;
+ }
+
+ public Object getTargetObjectSuite() {
+ return targetObjectSuite;
+ }
+
+ public void setTargetObjectSuite(Object targetObjectSuite) {
+ this.targetObjectSuite = targetObjectSuite;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/performance/ReportLogger.java b/src/main/java/org/apache/sling/performance/ReportLogger.java
new file mode 100644
index 0000000..e0f24d2
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/ReportLogger.java
@@ -0,0 +1,96 @@
+package org.apache.sling.performance;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.output.FileWriterWithEncoding;
+import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
+
+public class ReportLogger {
+
+ public enum ReportType{
+ TXT, XML
+ }
+
+
+ public static void writeReport(String test, String testSuiteName, String name, DescriptiveStatistics statistics, ReportType reportType) throws Exception{
+ switch(reportType){
+ case TXT:
+ writeReportTxt(test, testSuiteName, name, statistics);
+ break;
+ case XML:
+ throw new Exception("The XML reporting format is not yet supported");
+ default:
+ throw new Exception("The specified reporting format is not yet supported");
+ }
+ }
+
+ /**
+ * Method the writes the performance report after a test is run
+ * @param test the test name
+ * @param name the name that will be listed in the report
+ * @param statistics the statistics data to be written
+ * @throws IOException
+ */
+ public static void writeReportTxt(String test, String testSuiteName, String name, DescriptiveStatistics statistics)
+ throws IOException {
+
+ String className=test;
+ className=className.substring(className.lastIndexOf(".")+1);
+
+ File reportDir = new File("target/performance-reports");
+ if (!reportDir.exists()){
+ boolean test1 = reportDir.mkdir();
+ }
+
+ File report = new File("target/performance-reports", className + ".txt");
+
+ // need this in the case a user wants to set the suite name from the command line
+ // useful if we run the test cases from the command line for example
+ // by using maven
+ if (testSuiteName.equals(ParameterizedTestList.TEST_CASE_ONLY)){
+ if (System.getenv("testsuitename") != null){
+ testSuiteName = System.getenv("testsuitename");
+ }
+ }
+
+ boolean needsPrefix = !report.exists();
+ PrintWriter writer = new PrintWriter(
+ new FileWriterWithEncoding(report, "UTF-8", true));
+ try {
+ if (needsPrefix) {
+ writer.format(
+ "# %-34.34s min 10%% 50%% 90%% max%n",
+ className);
+ }
+
+ writer.format(
+ "%-36.36s %6.0f %6.0f %6.0f %6.0f %6.0f%n",
+ testSuiteName,
+ statistics.getMin(),
+ statistics.getPercentile(10.0),
+ statistics.getPercentile(50.0),
+ statistics.getPercentile(90.0),
+ statistics.getMax());
+ } finally {
+ writer.close();
+ }
+ }
+
+
+ /**
+ * Get the date that will be written into the result file
+ * @return
+ */
+ private static String getDate(){
+ DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+ Date date = new Date();
+
+ return dateFormat.format(date);
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/AfterMethodInvocation.java b/src/main/java/org/apache/sling/performance/annotation/AfterMethodInvocation.java
new file mode 100644
index 0000000..00da352
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/AfterMethodInvocation.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterMethodInvocation {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/AfterSpecificTest.java b/src/main/java/org/apache/sling/performance/annotation/AfterSpecificTest.java
new file mode 100644
index 0000000..2020f8f
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/AfterSpecificTest.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterSpecificTest {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/AfterSuite.java b/src/main/java/org/apache/sling/performance/annotation/AfterSuite.java
new file mode 100644
index 0000000..0acdaa3
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/AfterSuite.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AfterSuite {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/BeforeMethodInvocation.java b/src/main/java/org/apache/sling/performance/annotation/BeforeMethodInvocation.java
new file mode 100644
index 0000000..725bb51
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/BeforeMethodInvocation.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforeMethodInvocation {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/BeforeSpecificTest.java b/src/main/java/org/apache/sling/performance/annotation/BeforeSpecificTest.java
new file mode 100644
index 0000000..d89307e
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/BeforeSpecificTest.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforeSpecificTest {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/BeforeSuite.java b/src/main/java/org/apache/sling/performance/annotation/BeforeSuite.java
new file mode 100644
index 0000000..6bbb112
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/BeforeSuite.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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BeforeSuite {
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/PerformanceTest.java b/src/main/java/org/apache/sling/performance/annotation/PerformanceTest.java
new file mode 100644
index 0000000..3810234
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/PerformanceTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * Performance test annotation to use for the framework to be able to find
+ * all the tests in the test class
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PerformanceTest {
+
+
+ // set the warmup time for the test
+ int warmuptime() default 1;
+
+ // set the run time of the test
+ int runtime() default 5;
+
+ // set the number of invocations to time
+ // by default the run time is used instead
+ int runinvocations() default 0;
+
+ // set the number of invocations to run
+ // in the warm up phase
+ int warmupinvocations() default 0;
+
+
+}
diff --git a/src/main/java/org/apache/sling/performance/annotation/PerformanceTestSuite.java b/src/main/java/org/apache/sling/performance/annotation/PerformanceTestSuite.java
new file mode 100644
index 0000000..54a1837
--- /dev/null
+++ b/src/main/java/org/apache/sling/performance/annotation/PerformanceTestSuite.java
@@ -0,0 +1,10 @@
+package org.apache.sling.performance.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PerformanceTestSuite {
+
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.