Mutation
Hierarchical field/message/sequence mutator with energy feedback.
The hierarchical mutator produces child TestCase instances from parents and the active ProtocolModel. It prioritises structure-aware edits (field / message / sequence) over pure random streams, with optional dictionary and template synthesis and energy feedback on interesting outcomes.
src/input/mutator.rs — Mutator::mutate. Defaults from MutatorConfig in src/common/config.rs.
Configuration
| Key / param | Default | Role |
|---|---|---|
max_mutations | 8 | Upper bound on mutation ops per child |
hierarchical_prob | 0.15 | Probability of sequence-level ops when multiple messages exist |
field_prob | 0.70 | Bias toward field-level vs message-level branch |
dict_prob | 0.25 | Dictionary / spec-value injection probability |
template_prob | 0.12 | Splice synthesised MessageSpec / SequenceSpec |
| repair (internal) | on when integrity enabled | Call integrity::prepare_for_send after mutations |
rng_seed | — | Deterministic XorShift64 seed via -r |
# config excerpt
hierarchical_prob=0.15
field_prob=0.70
dict_prob=0.25
template_prob=0.12
max_mutations=8
rng_seed=42
Mutation levels
- Template splice (optional) — synthesise from
MessageSpec/SequenceSpecand replace/insert into the test case. - Sequence-level — duplicate, remove, swap, or truncate messages in multi-message cases.
- Message-level — insert/remove non-protected fields; overwrite from dictionary or spec values.
- Field-level — bit/byte flip, arithmetic, interesting bytes, insert/delete/overwrite, random fill (respecting fixed
size).
Length and Checksum fields are avoided as mutation targets at message level; size constraints from FieldSpec are enforced before send. Protected fields are skipped.
Field-type weights
Selection prefers high-signal types (energy multiplies weight after interesting hits):
| Type | Weight |
|---|---|
| Command | 10 |
| String | 9 |
| Payload | 8 |
| Binary | 6 |
| Numeric | 5 |
| Custom | 4 |
| Length | 1 |
| Checksum | 0 (skipped) |
on_interesting() boosts energy for fields touched in the last mutation (cap 64).
Field operators
- Bit flip / byte XOR
0xff - Arithmetic ± delta on a byte
- Interesting constants:
0x00 0x01 0x7f 0x80 0xff 0x20 0x0a 0x0d 0x09 - Delete / insert / overwrite spans (when size not fixed)
- Dictionary replace, splice, or append
Design trade-offs
- Structure-aware over blind havoc — deeper state-machine reach.
- Integrity repair after mutation keeps length/checksum coherent (disable via
-i nullfor framing-break tests). - Mutator holds RNG state — not inherently thread-safe; workers own separate instances in the engine.