= Mutation Engine = This library allows to inject random modifications (mutations) into arbitrary programs. The mutations, their parameters and the code to be modified can be controlled or selected randomly by the library. Different mechanisms can be used to inject the mutations. The library is designed to allow to easily add new mutations via subclassing. The mutations can be used to evaluate test suites or programming tools. = How to Install = Add the following Monticello Repository in your Monticello browser. Open it, and load the package !ConfigurationOfMutationEngine. {{{ MCHttpRepository location: 'http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/MetacelloRepository' user: '' password: '' }}} After that, execute the following line in your workspace: {{{ (ConfigurationOfMutationEngine project version: '1.0') load. }}} Wait, until all dependencies have been loaded into your image. = How to Use = '''1. Create instance of !MutationFactory'''[[BR]] The main aspect when creating a !MutationFactory is to choose the mechanism, that will be used to inject mutations into the system. Choose one of the following: {{{MutationFactory onSourceCode}}} -> Mutations will be compiled directly into the system, using the same method used by browsers. Might be somewhat dangerous (if the image is saved while the mutation is applied, and the image crashes, the old state of the method cannot be restored automatically) {{{MutationFactory onMethodWrappers}}} -> Mutations will be applied wrapping the mutated methods by !MethodWrappers. After a crash, the original state of the image can always be restored using !MethodFactory cleanupMethodWrappers '''2. Optional: Configure the !MutationScope'''[[BR]] The !MutationFactory has an instance of type !MutationScope called scope. It is required, when the method to be mutated should be selected randomly.[[BR]] It is not set by default. Create an instance using {{{MutationScope new}}} and use the methods in the protocol 'scope manipulation' to populate the scope with methods, classes or packages. '''3. Create a Mutation object'''[[BR]] The methods of !MutationFactory in the protocol 'mutation creation' create Mutation objects.[[BR]] {{{#createMutation:withParameters:forMethod:}}} is the most general one, allowing to specify all parameters of Mutation creation explicitely. {{{#randomMutation}}} chooses ALL parameters randomly. All other methods allow to specify parts of the parameters explicitely, and choose the rest of the parameters randomly. Following aspects are relevant: - The Mutation class - specifies, which mutation will be created. Will be picked from all non-abstract subclasses of Mutation (assembled in !MutationFactory class >> #availableMutations) - The method - the mutated method. Will be picked from the configured !MutationScope - The Mutation parameters - depend on the created Mutation. Cannot be specified without specifiying the Mutation class. Check the 'parameters' protocols of the Mutation classes, and class-comments of these classes, for detailed information. If required, the Mutation will be asked to create random parameters. '''4. Apply the Mutation'''[[BR]] Methods of Mutation in protocol 'mutating'.[[BR]] {{{#apply}}} - Apply the mutation (without reverting it!) The whole system will be affected by the mutation. A Mutation can only be applied once and will report an error, if applied twice. {{{#revert}}} - Revert the mutation (if already applied). A Mutation object can be reused (applied again, after being reverted). {{{#doMutated:}}} - Execute a block in the context of the Mutation, ensuring, that it will be reverted after the block. '''5. Example code snippets'''[[BR]] {{{ "Create a fixed Mutation for a fixed method. Execute the mutation." (MEMutationFactory onMethodWrappers createMutation: MEStringLiteralMutation forMethod: MEMutationTestObject class -> #returnStringOne) doMutated: [ MEMutationTestObject returnStringOne ] }}} {{{ "Create a fixed Mutation for a fixed method, with fixed parameters. Execute the mutation multiple times." (MEMutationFactory onMethodWrappers createMutation: MEStringLiteralMutation withParameters: ({ #replacementMode -> 'The Mutated String!' } as: Dictionary) forMethod: MEMutationTestObject class -> #returnStringOne) doMutated: [ MEMutationTestObject returnStringOne ]; doMutated: [ MEMutationTestObject returnStringThree ]; doMutated: [ MEMutationTestObject returnStringOne ] }}} {{{ "Create a random Mutation for a random method in a package, with random parameters etc. Print the random parameters." mutation := (MEMutationFactory onMethodWrappers scope: (MEMutationScope new addPackage: 'MutationEngine-Tests'; yourself)) randomMutation. { mutation method. mutation class. mutation parameters } }}} = Acknowledgments = [[Image(media/icons/silk:user.png, title="Contributors", nolink)]] To date the following people contributed to this project: * Anton Gulenko * Michael Perscheid