org.jwalk.core
Class AlgebraWalker

java.lang.Object
  extended by org.jwalk.JWalker
      extended by org.jwalk.core.ClassInspector
          extended by org.jwalk.core.ProtocolWalker
              extended by org.jwalk.core.AlgebraWalker
All Implemented Interfaces:
java.lang.Runnable

public class AlgebraWalker
extends ProtocolWalker

AlgebraWalker exercises all the algebraic constructions of the test class. An AlgebraWalker explores all the unique constructions possible with the test class's constructors and methods. It detects empirically if a sequence returns to an existing state, or leaves the state unchanged, and prunes these redundant paths. It therefore explores many fewer paths than a ProtocolWalker.

Version:
1.0
Author:
Anthony Simons

Field Summary
protected  java.util.Map<java.lang.reflect.Member,Category> category
          The map from members to algebraic categories.
 
Fields inherited from class org.jwalk.core.ProtocolWalker
oracle, summary
 
Fields inherited from class org.jwalk.core.ClassInspector
constants, constructors, methods, testClass
 
Fields inherited from class org.jwalk.JWalker
channels, settings
 
Constructor Summary
AlgebraWalker(Settings settings, Channels channels)
          Creates an AlgebraWalker, using the settings and channels.
 
Method Summary
protected  void discoverAlgebra()
          Estimates the algebraic categories of the test class's operations.
 void execute()
          Executes this AlgebraWalker test strategy according to the settings.
protected  void executeProbeCycle(java.util.List<TestSequence> testSet, int cycle)
          Executes one probing cycle, refining the algebraic category of methods.
 Category getCategory(java.lang.Enum<?> constant)
          Returns the algebraic category of an enumerated constant.
 Category getCategory(java.lang.reflect.Member member)
          Returns the algebraic category of a Field, Constructor, or Method.
protected  boolean isPrunable(TestSequence sequence)
          Reports whether a given TestSequence may be pruned.
 
Methods inherited from class org.jwalk.core.ProtocolWalker
ensureExecutable, executeTestCycle, executeTestSeries, firstCycle, makeGenerator, nextCycle
 
Methods inherited from class org.jwalk.core.ClassInspector
classIsAbstract, classIsEnum, classIsInterface, classNotPublic, countActiveEdges, countConstants, countConstructors, countMethods, countPermutations, getConstants, getConstructors, getMethods, getTestClass, inspectProtocols
 
Methods inherited from class org.jwalk.JWalker
getChannels, getSettings, outOfMemory, run, userAborted
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

category

protected java.util.Map<java.lang.reflect.Member,Category> category
The map from members to algebraic categories. This is used to store an estimate of the algebraic category of each Constructor or Method found in the public protocols of the test class. Some Constructors or Methods are primitive, and have the algebraic Category CONSTRUCTOR. Some Constructors and Methods are derived, so have the algebraic Category TRANSFORMER. Some methods only inspect the data type, so have the algebraic Category OBSERVER.

Constructor Detail

AlgebraWalker

public AlgebraWalker(Settings settings,
                     Channels channels)
Creates an AlgebraWalker, using the settings and channels.

Parameters:
settings - the test parameter settings to use.
channels - the call-back channels to report on.
Method Detail

getCategory

public Category getCategory(java.lang.Enum<?> constant)
Returns the algebraic category of an enumerated constant. This is by definition always the algebraic category CONSTRUCTOR.

Parameters:
constant - an enumerated constant.
Returns:
the algebraic category CONSTRUCTOR.

getCategory

public Category getCategory(java.lang.reflect.Member member)
Returns the algebraic category of a Field, Constructor, or Method. This method may be used to categorise the value returned by the method getOperation() in TestCase and TestSequence, which returns a value of the type Member, generalising over Constructors, Methods and constant Fields. Only valid after this AlgebraWalker has inspected the test class and performed a dynamic probing analysis.

Looks up the algebraic Category of the supplied Member, according to its specific type. A Field is always assumed to be a constant, converted from the enumerated value, and by definition has the algebraic category CONSTRUCTOR. A Constructor or Method may be classified as a primitive CONSTRUCTOR, a derived TRANSFORMER or, in the case of Methods only, an OBSERVER, determined according to a dynamic analysis of the test class.

Parameters:
member - a constant Field, Constructor or Method to look up.
Returns:
the algebraic category CONSTRUCTOR.

isPrunable

protected boolean isPrunable(TestSequence sequence)
Reports whether a given TestSequence may be pruned. When exploring all algebraic constructions, TestSequences that cause the test object to enter a previously visited state are pruned, as well as those paths which terminated with an Exception. This removes redundant paths from the next test cycle. Shorter paths which reached the same states will already have been explored.

Overrides:
isPrunable in class ProtocolWalker
Parameters:
sequence - the TestSequence being evaluated.
Returns:
true if the TestSequence entered a previously visited state, or terminated with an Exception.

executeProbeCycle

protected void executeProbeCycle(java.util.List<TestSequence> testSet,
                                 int cycle)
                          throws PermissionException,
                                 GeneratorException,
                                 ExecutionException
Executes one probing cycle, refining the algebraic category of methods. This is a conservative algorithm, initially assuming that each Method is an OBSERVER, unless it is found to change the test object's state. In this case, the Method is either deemed a primitive CONSTRUCTOR, if it reaches a new state, or a derived TRANSFORMER, if it returns to a previously-visited state (and the prefix consists only of primitive operations).

Parameters:
testSet - the current test set.
cycle - the probe cycle number.
Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.

discoverAlgebra

protected void discoverAlgebra()
                        throws PermissionException,
                               GeneratorException,
                               ExecutionException
Estimates the algebraic categories of the test class's operations. This classifies each operation into one of a {CONSTRUCTOR, TRANSFORMER OBSERVER} in the algebraic sense. The algorithm classifies every enumerated constant as a CONSTRUCTOR; may classify an object Constructor as either a CONSTRUCTOR (if it is primitive) or a TRANSFORMER (if it is derivable from another object Constructor); and may classify a Method as any of a CONSTRUCTOR (if it drives the test object into a new, previously unreached, state), a TRANSFORMER (if it drives the test object into a previously visited state) or an OBSERVER (if it leaves the state of the test object unchanged). The algorithm makes conservative initial assumptions about Constructors and Methods, and updates these assumptions in the light of dynamic analysis of concrete states, using probing test sequences to exercise the test object.

Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.

execute

public void execute()
             throws PermissionException,
                    GeneratorException,
                    ExecutionException
Executes this AlgebraWalker test strategy according to the settings. If the Modality is INSPECT, extracts the public constructor and method interface of the test class and then dynamically detects the algebraic category of each constructor and method. If the Modality is EXPLORE, also explores all unique algebraic constructions of the test class to the requested path depth. If the Modality is VALIDATE, also validates the outcomes of every test using an Oracle.

Overrides:
execute in class ProtocolWalker
Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.