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-org-apache-sling-performance.git

commit eb67a440c990e294c858ea91f2f84b36b7aa347d
Author: Antonio Sanso <[email protected]>
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
"[email protected]" <[email protected]>.

Reply via email to