The mutation toolkit is used to generate mutation faults for Java classes.
Mutations are generated from the bytecode of Java classes and applied using
bytecode transformations. The mutation operators used to generate and apply
possible mutants are implemented in a dynamic framework that allows easy addition
of new operators. The two main classes of interest are the
MutationGenerator, which generates tables of possible mutations,
and the Mutator, which applies mutations.
The mutation generator processes a set of Java classfiles using a set of enabled mutation operators and generates for each class a table of all the possible mutations that can be applied to that class. This table lists each mutation with the operator that generated it and the information necessary to apply the bytecode transformation. The command to run the mutation generator is the following:
java sofya.mutator.MutationGenerator [-tag tag]
<-c config_file> <classfile|jarfile|listfile>
[classfile|jarfile|listfile ...]
-tag tag
Specifies the database tag associated with the provided program list file, if applicable. Ignored otherwise.
-c config_file
Specifies the configuration file to be used.
If you include the '.class' extension when specifying a single class, it is interpreted as an absolute path name. If the extension is excluded, the class must be specified using its fully qualified name, and Σοφία will attempt to load it from the classpath. The mutation generator also accepts jar files and program list files to specify the classes for which to generate mutations. Program list files are automatically found in the database, using the tag if one is specified. Any necessary path information should be provided when passing a jar file as an argument. When a jar file is passed as an argument on the command line, mutations are generated for every class in that jar. The preferred way to include classes in a jar file is to include the jar file in a program list file and supply the program list file as an argument instead, as a program list file permits you to exclude classes in the jar from processing. Any number of specific classes, jar files, and program list files can be passed to the mutation generator, though supplying a single program list file is the expected typical use.
For each class, a file containing the mutation table for that class will be generated in the working directory from which the mutation generator was run.
The configuration file specifies the enabled mutation operators, and certain global properties used for loading mutation operators. This file should begin with the keyword 'global' followed by zero or more property/value entries enclosed in braces; this section declares the global properties. Currently the following global properties are supported:
operatorListFile=<list_file>
Specifies the path to the file containing the list of
operators to be enabled by default if defaultEnabled is set
to true.
defaultEnabled=<true|false>
Specifies whether all operators in the operators list
file should be enabled by default. If false, no operator will be
enabled unless it is explicitly listed in the configuration file. Defaults
to true.
If defaultEnabled is false, the remainder of the file
should list the fully qualified name of the class implementing each operator to
be enabled, followed by a brace-enclosed block. (The braces are present to
support future extensions to the configuration file format).
The following is a simple example of a configuration file for the mutation generator. It specifies that no mutation operators should be enabled by default, and then enables the argument order change (AOC) and logical connector change (LCC) operators explicitly.
global {
defaultEnabled=false
}
sofya.mutator.operators.AOC {
}
sofya.mutator.operators.LCC {
}
The mutator is the tool responsible for actually applying one or more mutations to the bytecode of a Java classfile to create the mutated class. It uses the mutation tables produced by the mutation generator in combination with a user specified selection criteria to apply mutations to a class. To use the mutator, run the following command:
java sofya.mutator.Mutator [-tag tag] [selection_type]
<classfile> [in directory|jarfile]
where optional selection_type may be one of the following:
-all
Selects all mutations. This is the default.
-ids id_1[:varid],id_2[:varid],...,id_n[:varid]
Selects mutations by ID and optional variant ID.
-methods method_list_file
Selects mutations that occur in methods specified by method
name and signature. The methods to be selected are listed in method_list_file,
one per line, where each method entry is in source code declaration format with
underscores substituted for spaces, and the fully qualified implementing class name is
prepended (e.g. java.util.Map_public_boolean_containsKey(Object_key)).
-ops op_1,op_2,...,op_n
Selects mutations by operator.
-random number
Selects number mutations randomly.
-randOp number op_1,op_2,...,op_n
Selects number mutation operators from the given set of operators, and then selects all mutations generated by the selected operators.
-randMethod number method_list_file
Selects number methods from the list of methods in method_list_file, and then selects all mutations that occur in those methods.
When specifying a class for mutation, the rules regarding inclusion of the .class extension are the same as for the Mutation Generator. However, the mutator exhibits additional behaviors with respect to the format of the class name. If an absolute path is given, the mutation(s) will be directly applied to the given classfile, at the classfile's current location. If the class is loaded from the classpath, the resulting mutated classfile will be placed in the working directory from which the mutator is run.
The class to be mutated can also be qualified with the
"in directory|jarfile" clause. If this
extension is present, the class name should be the fully qualified name of the
class using dot notation (no path or extension). The mutator will then attempt
to load and mutate the class in the given location. This is primarily intended
to facilitate the mutation of classes in jar files.
Regardless of how classes are specified to the mutator, the mutation tables for each class are loaded automatically from the current working directory. Generally it is expected that the mutator will be run from the same working directory as the mutation generator.
Certain mutation operators can generate multiple 'variants' at a particular
mutation point. These variants represent a set of mutually exclusive modifications
that can be made to produce a mutation at that location. An example of such
a mutation operator is arithmetic operator substitution, where a single operator
can be mutated into several alternate operators. When such cases arise,
the mutation generator identifies and records all the possible alternatives in
the mutation table as variants of a single mutation, one of which can be chosen
at the time of mutation generation. A default variant is selected, usually
at random. Variants are assigned numeric identifiers, which can be determined
by using the MutationTableViewer. The two display modes of the
viewer can provide either human-friendly or parser-friendly representations of
the possible variants for selection. To select a variant, the appropriate
numeric identifier can be appended to the mutation ID with a colon, using the
"-ids" selector. For example:
java sofya.mutator.Mutator -ids 3:2 Target.class
The above will select the second variant of the third mutation to be
applied to Target.class. In the absence of a specified variant,
the default variant will be used; the default variant can also be determined
using the viewer.