package U2.T2 ;
//import U2.T2.Obj.* ;
import java.lang.reflect.* ;
import java.util.* ;
import java.io.* ;
import U2.T2.Reflection.* ;
/**
* Abstract class representing the general structure and parameters of
* a test engine; furthermore the class contains a bunch of utility
* static methods.
*/
abstract public class Engine {
/**
* The class under the test.
*/
protected Class CUT ;
/**
* The object pool used by the engine.
*/
protected Pool pool ;
/*
* Saved execution traces. Typically it contains traces of
* violating executions.
*/
// protected LinkedList<Trace> savedTraces ;
/**
* Specify a maximum on the numbers of total execution steps
* generated by the engine. Default is 500.
*/
protected int maxNumOfSteps = 500 ;
/**
* Specify a maximum on the length of each execution. Default is
* 4.
*/
protected int maxExecLength = 4 ;
/**
* The engine should stop if the number of violations found
* reaches maxNumViolations. Default is 1.
*/
protected int maxNumViolations = 1 ;
// some variables to keep track progress:
/**
* Total number of execution steps generated.
*/
protected int numOfSteps = 0 ;
/**
* Total number of executions generated.
*/
protected int numOfExecs = 0 ;
/**
* Total number of violations found.
*/
protected int numOfViolations = 0 ;
/**
* Total number of relevant checks.
*/
protected int numOfRelevantChecks = 0 ;
/*
* Construct an engine with a default setting. The CUT is set to
* null.
*/
// public Engine() { } // :)
/**
* Run the test engine. It does nothing here, and should be
* overiden by subclass.
*/
abstract public void runMe() ;
/**
* To report violating traces found by the engine. It does nothing
* here, and should be overiden by subclass.
*/
abstract public void report(PrintStream out) ;
// Some utilities methods
private static final String CLASSINV_STR = "classinv" ;
private static final String MAIN_STR = "main" ;
private static final String SPEC_STR = "_spec" ;
/**
* Get the constructors of a class that act as interface
* points. Currently these are the declared, non-private
* constructors of the class.
*/
public static List<Constructor> getConsIPs(Class C) {
List<Constructor> result = new LinkedList<Constructor>() ;
Constructor[] cons = C.getDeclaredConstructors() ;
for (int i=0; i<cons.length; i++)
if (! Modifier.isPrivate(cons[i].getModifiers()))
result . add(cons[i]) ;
return result ;
}
/**
* Get the methods of a class that act as interface
* points. Currently this is all public methods of its
* superclasses + its own declared non-private methods.
*/
public static List<Method> getMethsIPs(Class C) {
Class CLASS_OBJECT = (new Object()) . getClass() ;
List<Method> result = new LinkedList<Method>() ;
// first get C's own declared methods:
Method[] methods = C.getDeclaredMethods() ;
for (int i=0; i<methods.length; i++)
if ((! Modifier.isPrivate(methods[i].getModifiers()))
&&
(! Modifier.isStatic(methods[i].getModifiers())
||
ReflUtil.canAcceptAsParameter(C,methods[i]))
&&
! methods[i] . getName() . equals(CLASSINV_STR)
&&
! methods[i] . getName() . endsWith(SPEC_STR)
&&
// exclude main for now ...
! methods[i] . getName() . equals(MAIN_STR)
)
result . add(methods[i]) ;
// now get public methods from C + superclasses:
methods = C.getMethods() ;
for (int i=0; i<methods.length; i++)
if ((! result.contains(methods[i]))
&&
(! Modifier.isStatic(methods[i].getModifiers())
||
ReflUtil.canAcceptAsParameter(C,methods[i]))
&&
// exclude methods of "Object" ... they should be safe:
(methods[i].getDeclaringClass() != CLASS_OBJECT)
&&
! methods[i] . getName() . equals(CLASSINV_STR)
&&
! methods[i] . getName() . endsWith(SPEC_STR)
&&
// exclude main for now ...
! methods[i] . getName() . equals(MAIN_STR)
)
result . add(methods[i]) ;
return result ;
}
/**
* Get the fields of a class that act as interface
* points. Currently this is all public fields of its
* superclasses + its own declared non-private fields.
*/
public static List<Field> getFieldsIPs(Class C) {
Class CLASS_OBJECT = (new Object()) . getClass() ;
List<Field> result = new LinkedList<Field>() ;
// first get C's own declared fields:
Field[] fields = C.getDeclaredFields() ;
for (int i=0; i<fields.length; i++)
if (! Modifier.isPrivate(fields[i].getModifiers())
&&
// Ehm... for now excluding static fields:
! Modifier.isStatic(fields[i].getModifiers())
&&
! Modifier.isFinal(fields[i].getModifiers())
)
result . add(fields[i]) ;
// now get public fields from C + superclasses:
fields = C.getFields() ;
for (int i=0; i<fields.length; i++)
if (! result.contains(fields[i])
&&
! Modifier.isStatic(fields[i].getModifiers())
&&
! Modifier.isFinal(fields[i].getModifiers())
)
result . add(fields[i]) ;
return result ;
}
/**
* Construct a mapping such that for any method m of the class C
* that has m_spec as its specification, we add the pair
* (m,m_spec) to the mapping.
*/
public static HashMap<Method,Method> mk_specMap(Class C, List<Method> methods) {
HashMap<Method,Method> map = new HashMap<Method,Method>() ;
for (Method m : methods) {
Method spec = null ;
Class[] paramTypes = m.getParameterTypes() ;
try { spec = C.getMethod(m.getName() + SPEC_STR, paramTypes) ; }
catch (Exception e) { continue ; } ;
map.put(m,spec) ;
} ;
return map ;
}
}
|