kitty.model.high_level.staged_sequence module

Generate random sequences of messages for a session. Currently, perform no special operation for mutations on the nodes.

class kitty.model.high_level.staged_sequence.Stage(name, selection_strategy='1', seed=None)[source]

Bases: kitty.core.kitty_object.KittyObject

Stage supports 4 different sequence length strategy. For all of them, the order of templates will be random. The available strategies are:

  • for random length - ‘random’
  • for exact length - ‘12’
  • for length in range - ‘1-3’
  • for all - ‘all’
__init__(name, selection_strategy='1', seed=None)[source]
Parameters:
  • name – name of the Stage
  • selection_strategy – strategy for selecting amount of template in each mutation
  • seed – RNG seed (default: None)
add_template(template)[source]
Parameters:template – template to add to the stage
get_sequence_templates()[source]
Returns:templates of current sequence mutation
get_templates()[source]
Returns:list of the stage’s templates
hash()[source]
mutate()[source]
class kitty.model.high_level.staged_sequence.StagedSequenceModel(name='StagedSequenceModel', callback_generator=None, num_mutations=1000)[source]

Bases: kitty.model.high_level.base.BaseModel

The StagedSequenceModel provides sequences that are constructed from multiple stages of sequences. Each such stage provides its part of the sequence based on its strategy. The main goal of the Staged sequence mode is to find flaws in the state handling of a stateful target.

Example:

Assuming we have the templates [CreateA .. CreateZ, UseA .. UseZ and DeleteA .. DeleteZ]. A valid sequence is CreateA -> UseA -> DeleteA, so we want to test cases like CreateA -> UseB -> UseA -> DeleteC, or CreateA -> DeleteA -> UseA. And let’s say the common thing to all sequences is that we always want to start by sending one or more of the Create messages.

We can do that with StagedSequenceModel:

stage1 = Stage('create', selection_strategy='1-5')
stage1.add_Template(CreateA)
# ...
stage1.add_Template(CreateZ)
stage2 = Stage('use and delete', selection_strategy='3-20')
stage2.add_Template(UseA)
stage2.add_Template(DeleteA)
# ...
stage2.add_Template(UseZ)
stage2.add_Template(DeleteZ)

model = StagedSequenceModel('use and delete mess', num_mutations=10000)
model.add_stage(stage1)
model.add_stage(stage2)

Each time it is asked, it will provide a sequence that starts with 1-5 random “Create” templates, followed by 3-20 random Use and Delete messages. None of those templates will be mutated, as we try to fuzz the sequence itself, not the message structure.

Since we don’t know the what will be the order of templates in the sequences, we can’t just provide a callback as we do in GraphModel. The solution in our case is to provide the model with a callback generator, which receives the from_template and to_template and returns a callback function as described in GraphModel in runtime.

__init__(name='StagedSequenceModel', callback_generator=None, num_mutations=1000)[source]
Parameters:
  • name – name of the model object (default: ‘StagedSequenceModel’)
  • callback_generator (func(from_template, to_template) -> func(fuzzer, edge, response) -> None) – a function that returns callback functions
  • num_mutations – number of mutations to perform
add_stage(stage)[source]

add a stage. the order of stage is preserved

Parameters:stage (Stage) – the stage to add
get_model_info()[source]
Returns:dictionary of information about this model
get_test_info()[source]
Returns:dictionary of information about the current test
hash()[source]