Package org.easetech.easytest.interceptor

Source Code of org.easetech.easytest.interceptor.CommonProxyInterceptor

package org.easetech.easytest.interceptor;

import java.lang.reflect.Method;
import java.util.Observable;
import junit.framework.Assert;
import org.easetech.easytest.annotation.Duration;
import org.easetech.easytest.reports.data.MethodUnderTestDuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A common class for both {@link InternalInterceptor} as well as {@link InternalInvocationhandler}
*
* @author Anuj Kumar
*
*/
public class CommonProxyInterceptor  extends Observable {
   
    /** Logger implementation*/
    protected static final Logger LOG = LoggerFactory.getLogger(CommonProxyInterceptor.class);
   
    /**
     * User provided {@link MethodIntercepter}
     */
    private MethodIntercepter userIntercepter;
   
    /**
     * The instance on which to call the Method
     */
    private Object targetInstance;
   
    /**
     * The expected Run time of the method as specified in the {@link Duration} annotation
     */
    private Long expectedRunTime;
   
    /**
     * Get the User supplied {@link MethodIntercepter} implementation.
     * Defaults to {@link DefaultMethodIntercepter}
     * @return the userIntercepter user supplied method interceptor
     */
    public MethodIntercepter getUserIntercepter() {
        return userIntercepter;
    }

    /**
     * the User supplied {@link MethodIntercepter} implementation.
     * Defaults to {@link DefaultMethodIntercepter}
     * @param userIntercepter the userIntercepter to set
     */
    public void setUserIntercepter(MethodIntercepter userIntercepter) {
        this.userIntercepter = userIntercepter;
    }

    /**
     * The actual instance of the class that is being proxied
     * @return the targetInstance instance of the class that is being proxied
     */
    public Object getTargetInstance() {
        return targetInstance;
    }

    /**
     * Set instance of the class that is being proxied
     * @param targetInstance the targetInstance to set
     */
    public void setTargetInstance(Object targetInstance) {
        this.targetInstance = targetInstance;
    }

    /**
     * Get the maximum time in milliseconds that a method under test should take to run.
     *
     * @return the expectedRunTime
     */
    public Long getExpectedRunTime() {
        return expectedRunTime;
    }

    /**
     * Set the maximum time in milliseconds that a method under test should take to run.
     * @param expectedRunTime the expectedRunTime to set
     */
    public void setExpectedRunTime(Long expectedRunTime) {
        this.expectedRunTime = expectedRunTime;
    }
   
    /**
     * Get the expected time in Nano seconds
     * @param timeInMillis the given time in millis
     * @return the time in Nanos
     */
    public Long getExpectedTimeInNano(Long timeInMillis) {
        Long result = null;
        Long nanoBase = (long)(1000 * 1000) ;
        if(timeInMillis != null && timeInMillis != 0 && timeInMillis != Long.MAX_VALUE) {
            if (nanoBase > Long.MAX_VALUE / timeInMillis) {
                Assert.fail("EasyTest tries to convert the time (specified in Millisecond using Duration annotation) into nano seconds for precise comparisons." +
                    "But in this particular case, you specified a value that would ultimately overflow and will not fit in the long datatype. " +
                    "The value is : " + timeInMillis + "(ms). Please specify a smaller time unit.");
            } else {
               result = timeInMillis * nanoBase;
            }
        }
        return result;
       
    }
   
    /**
     * Compare the time taken by the method to the expected runtime.
     * Fail if the time taken is more, else log the time taken.
     * @param timeTakenInNanos time taken by the method under test
     * @param method Name of the method
     * @param durationBean the instance of {@link MethodUnderTestDuration}
     */
    public void compareTime(Long timeTakenInNanos , Method method , MethodUnderTestDuration durationBean) {
        Long expectedTimeInNano = getExpectedTimeInNano(getExpectedRunTime());
        Long expectedTimeInMillis = Long.valueOf(0), timeTakenInMillis, expectedTimeinMicros, timeTakenInMicros;
        timeTakenInMicros = timeTakenInNanos / 1000 ;
        timeTakenInMillis = (timeTakenInNanos / 1000)/1000;
        if(expectedTimeInNano!= null && timeTakenInNanos > expectedTimeInNano) {
           
            expectedTimeInMillis = (expectedTimeInNano / 1000)/1000;
            expectedTimeinMicros = expectedTimeInNano / 1000 ;
           
            Assert.fail("Total time taken by method " + method.getName() +" ("+ timeTakenInNanos + " nanosec/"+ timeTakenInMicros +" microsec/"+ timeTakenInMillis+" millisec) is greater than the " +
                "expected time("+expectedTimeInNano+" nenosec/" +expectedTimeinMicros+" microsec/"+expectedTimeInMillis+" millisec)");
        } else {
            System.out.println("Method " + method.getName() + " on " + getTargetInstance().getClass()+ " took " + timeTakenInNanos + " nanosec/"+ timeTakenInMicros +" microsec/"+ timeTakenInMillis+" millisec" );
            LOG.debug("Method " + method.getName() + " on " + getTargetInstance().getClass()+ " took " + timeTakenInNanos + " nanosec/"+ timeTakenInMicros +" microsec/"+ timeTakenInMillis+" millisec" );
        }
        durationBean.setActualDurationinMillis(timeTakenInMillis);
        durationBean.setExpectedDurationinMillis(expectedTimeInMillis);
        notifyObservers(durationBean);
    }
   
    /**
     * A common Interceptor method for both {@link InternalInvocationhandler} and
     * {@link InternalInterceptor} that handles delegation to a user defined interceptor
     * and also compares the time taken by the method to the time a user expects a method
     * to be completed
     * @param method the method to invoke
     * @param args the arguments to the method
     * @return result of method execution
     * @throws Throwable if any exception occurs
     */
    public Object intercept(Method method , Object[] args) throws Throwable {
        Long startTime = System.nanoTime();
        Object result = getUserIntercepter().intercept(method, getTargetInstance(), args);
        Long timeTaken = System.nanoTime() - startTime;
        MethodUnderTestDuration durationBean = getMethodDurationBean(method, args, result);
        compareTime(timeTaken , method , durationBean);
        return result;
    }
   
    /**
     * Method to get hte {@link MethodUnderTestDuration} instance filled with requisite information
     * @param method the method under test
     * @param args the arguments to the method under test
     * @param result the result returned by the method under test
     * @return an instance of {@link MethodUnderTestDuration}
     */
    private MethodUnderTestDuration getMethodDurationBean(Method method, Object[] args , Object result) {
        MethodUnderTestDuration durationBean = new MethodUnderTestDuration();
        durationBean.setClassUnderTest(getTargetInstance().getClass());
        durationBean.setMethodUnderTest(method);
        durationBean.setMethodArguments(args);
        durationBean.setMethodResult(result);
        return durationBean;
       
    }

}
TOP

Related Classes of org.easetech.easytest.interceptor.CommonProxyInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.