Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.evosuite.runtime.PrivateAccess Maven / Gradle / Ivy
/**
* Copyright (C) 2010-2016 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see .
*/
package org.evosuite.runtime;
import org.evosuite.runtime.annotation.Constraints;
import org.evosuite.runtime.javaee.injection.InjectionList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Class used to access private fields/methods by reflection.
* If the accessed fields/methods do not exist any more, than
* the tests would gracefully stop
*
* Created by Andrea on 20/02/15.
*/
public class PrivateAccess {
private static final Logger logger = LoggerFactory.getLogger(PrivateAccess.class);
/**
* flag to specify to throw AssumptionViolatedException when fields/methods do not
* exist any more. this should bet set to false iff during experiments
*/
private static boolean shouldNotFailTest = true;
public static void setShouldNotFailTest(boolean b){
shouldNotFailTest = b;
}
/**
* Use reflection to set the given field
*
* @param klass
* @param instance null if field is static
* @param fieldName
* @param value
* @param the class type
* @throws IllegalArgumentException if klass or fieldName are null
* @throws FalsePositiveException if the the field does not exist anymore (eg due to refactoring)
*/
public static void setVariable(Class klass, T instance, String fieldName, Object value)
throws IllegalArgumentException, FalsePositiveException {
setVariable(klass,instance,fieldName,value,null);
}
/**
* Use reflection to set the given field
*
* @param klass
* @param instance null if field is static
* @param fieldName
* @param value
* @param the class type
* @param tagsToCheck if not null, then the field has to have at least one the tags in such list
* @throws IllegalArgumentException if klass or fieldName are null
* @throws FalsePositiveException if the the field does not exist anymore (eg due to refactoring)
*/
public static void setVariable(Class> klass, T instance, String fieldName, Object value,
List> tagsToCheck)
throws IllegalArgumentException, FalsePositiveException {
if(klass == null){
throw new IllegalArgumentException("No specified class");
}
if(fieldName == null){
throw new IllegalArgumentException("No specified field name");
}
if(fieldName.equals("serialVersionUID")){
throw new IllegalArgumentException("It is not allowed to set serialVersionUID by reflection");
}
// note: 'instance' can be null (ie, for static variables), and of course "value"
Field field = null;
try {
field = klass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
String message = "Field '"+fieldName+"' does not exist any more in class "+klass;
if(shouldNotFailTest) {
// force the throwing of a JUnit AssumptionViolatedException
throw new FalsePositiveException(message);
//it is equivalent to calling
//org.junit.Assume.assumeTrue(message,false);
} else {
throw new IllegalArgumentException(message);
}
}
assert field != null;
field.setAccessible(true);
if(tagsToCheck != null){
boolean match = false;
for(Annotation ann : field.getDeclaredAnnotations()){
Class extends Annotation> tag = ann.annotationType();
if(InjectionList.isValidForInjection(tag, tagsToCheck)){
match = true;
break;
}
}
if(!match){
throw new IllegalArgumentException("The field "+fieldName+" in class "+klass.getName()+
"does not have any valid annotation");
}
}
try {
Reflection.setField(field, instance, value);
} catch (IllegalAccessException e) {
//should never happen, due to setAccessible(true);
throw new FalsePositiveException("Failed to set field "+fieldName+": "+e.toString());
}
}
/**
* Call the default constructor of the class under test.
* This is useful to avoid low coverage due to private constructors in final
* classes used to prevent instantiating them (eg those classes only have
* static methods)
*
* @throws Throwable
*/
@Constraints(atMostOnce = true, notMutable = true)
public static Object callDefaultConstructorOfTheClassUnderTest() throws Throwable{
Class> cut = Thread.currentThread().getContextClassLoader().loadClass(RuntimeSettings.className);
return callDefaultConstructor(cut);
}
/**
* Call the default constructor of the given klass.
* This is useful to avoid low coverage due to private constructors in final
* classes used to prevent instantiating them (eg those classes only have
* static methods)
*
* @param klass
* @param
* @throws Throwable
*/
@Constraints(atMostOnce = true, noNullInputs = true, notMutable = true)
public static T callDefaultConstructor(Class klass) throws Throwable{
//TODO: not only should be atMostOnce in a test, but in the whole suite/archive
if(klass == null){
throw new IllegalArgumentException("No specified class");
}
//RuntimeSettings
Constructor constructor;
try {
constructor = klass.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
String message = "Default constructor does not exist anymore";
if(shouldNotFailTest){
throw new FalsePositiveException(message);
} else {
throw new IllegalArgumentException(message);
}
}
assert constructor != null;
constructor.setAccessible(true);
try {
return constructor.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new FalsePositiveException("Failed to call the default constructor of "+klass.getName()+": "+e.toString());
} catch (InvocationTargetException e) {
//we need to propagate the real cause to the test
throw e.getTargetException();
}
}
/**
* Use reflection to call the given method
*
* @param klass
* @param instance null for static methods
* @param methodName
* @param inputs arrays of inputs
* @param types types for the inputs
* @param
* @return the result of calling the method
* @throws IllegalArgumentException if either klass or methodName are null
* @throws FalsePositiveException if method does not exist any more (eg, refactoring)
* @throws Throwable the method might throw an internal exception
*/
public static Object callMethod(Class klass, T instance, String methodName, Object[] inputs, Class>[] types)
throws Throwable {
if(klass == null){
throw new IllegalArgumentException("No specified class");
}
if(methodName == null){
throw new IllegalArgumentException("No specified method name");
}
// note: 'instance' can be null (ie, for static methods), and of course "inputs"
if( (types==null && inputs!=null) || (types!=null && inputs==null) ||(types!=null && inputs!=null && types.length!=inputs.length)){
throw new IllegalArgumentException("Mismatch between input parameters and their type description");
}
Method method = null;
try {
method = klass.getDeclaredMethod(methodName,types);
} catch (NoSuchMethodException e) {
String message = "Method "+methodName+" does not exist anymore";
if(shouldNotFailTest){
throw new FalsePositiveException(message);
} else {
throw new IllegalArgumentException(message);
}
}
assert method != null;
method.setAccessible(true);
Object result = null;
try {
result = method.invoke(instance,inputs);
} catch (IllegalAccessException e) {
//shouldn't really happen
throw new FalsePositiveException("Failed to call "+methodName+": "+e.toString());
} catch (InvocationTargetException e) {
//we need to propagate the real cause to the test
throw e.getTargetException();
}
return result;
}
/*
TODO likely need one method per number of inputs
*/
public static Object callMethod(Class klass, T instance, String methodName)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[0], new Class>[0]);
}
public static Object callMethod(Class klass, T instance, String methodName, Object input, Class> type)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{input}, new Class>[]{type});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1}, new Class>[]{t0,t1});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2}, new Class>[]{t0,t1,t2});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3}, new Class>[]{t0,t1,t2,t3});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4}, new Class>[]{t0,t1,t2,t3,t4});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4
,Object i5, Class> t5)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5}, new Class>[]{t0,t1,t2,t3,t4,t5});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4
,Object i5, Class> t5,Object i6, Class> t6)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6}, new Class>[]{t0,t1,t2,t3,t4,t5,t6});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4
,Object i5, Class> t5,Object i6, Class> t6,Object i7, Class> t7)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7}, new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4
,Object i5, Class> t5,Object i6, Class> t6,Object i7, Class> t7,Object i8, Class> t8)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8}, new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2,Object i3, Class> t3,Object i4, Class> t4
,Object i5, Class> t5,Object i6, Class> t6,Object i7, Class> t7,Object i8, Class> t8,Object i9, Class> t9)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
, Object i15, Class> t15)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
, Object i15, Class> t15,Object i16, Class> t16)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
, Object i15, Class> t15,Object i16, Class> t16,Object i17, Class> t17)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
, Object i15, Class> t15,Object i16, Class> t16,Object i17, Class> t17,Object i18, Class> t18)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18});
}
public static Object callMethod(Class klass, T instance, String methodName
, Object i0, Class> t0, Object i1, Class> t1, Object i2, Class> t2, Object i3, Class> t3, Object i4, Class> t4
, Object i5, Class> t5, Object i6, Class> t6, Object i7, Class> t7, Object i8, Class> t8, Object i9, Class> t9
, Object i10, Class> t10,Object i11, Class> t11,Object i12, Class> t12,Object i13, Class> t13,Object i14, Class> t14
, Object i15, Class> t15,Object i16, Class> t16,Object i17, Class> t17,Object i18, Class> t18,Object i19, Class> t19)
throws Throwable {
return callMethod(klass,instance,methodName,new Object[]{i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19},
new Class>[]{t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19});
}
public static Method getCallMethod(int nParameters){
int max = 20; //TODO might consider have more
if(nParameters<0 || nParameters>max){
logger.error("Cannot handle reflection on methods with more than {} parameters: asked for {}", max, nParameters);
return null;
}
List> types = new ArrayList<>();
types.add(Class.class);//klass
types.add(Object.class);//T
types.add(String.class);//methodName
for(int i=0; i