|
Hegel 0.13.1
Property-based testing for C++
|
Stateful (model-based) property testing. More...
Classes | |
| class | VariablesGenerator |
| class | Invariant |
| An invariant is a predicate that must hold at any point in the stateful test. They are evaluated in full on the initial and final state and sampled at intermediate join points. The invariant function should throw when the invariant is violated. More... | |
| class | ConcurrentRule |
| An action that a worker can apply to a concurrent state machine. More... | |
| class | ConcurrentStateMachine |
| Base class for a concurrent state machine. More... | |
| class | Pool |
| A pool of previously generated values. A pool lets data flow from one rule to another, so a rule can act on a handle or identifier that an earlier rule produced rather than on a freshly drawn value. More... | |
| class | ConcurrentPool |
| A pool of values that concurrent workers can share. More... | |
| class | Rule |
| A rule is one possible action in a stateful test. More... | |
| struct | StateMachineParams |
| Arguments for the StateMachine constructor. More... | |
| class | StateMachine |
| Base class for a state machine. Holds the state and declares the rules and the invariants that act on it. More... | |
| struct | RunParams |
| Options for run. More... | |
| class | Generator |
| The base class of all generators. More... | |
| struct | IGenerator |
| Base interface for generators. More... | |
Functions | |
Variable pools | |
| template<typename T> | |
| Generator< T > | values_consumed (Pool< T > &p) |
| Returns a value from the pool and removes it. | |
| template<typename T> | |
| Generator< T > | values_reusable (Pool< T > &p) |
| Returns a value from the pool without removing it. | |
| template<typename T> | |
| Generator< T > | values_consumed (ConcurrentPool< T > &pool) |
| Returns a value from a concurrent pool and removes it. | |
| template<typename T> | |
| Generator< T > | values_reusable (ConcurrentPool< T > &pool) |
| Returns a copy of a value from a concurrent pool. | |
| template<typename M> | |
| void | run_concurrent (M &machine, TestCase &tc, int64_t min_concurrency, int64_t max_concurrency) |
Executes a concurrent stateful test with rules from machine. | |
| template<typename M> | |
| void | run (M &machine, TestCase &tc, const RunParams ¶ms={}) |
Executes a stateful test by repeatedly applying randomly chosen rules from machine to it. Invariants run in full before the first step and after the final step. Between steps, each invariant is sampled independently. Rules mutate machine in place. Raises std::invalid_argument if the machine declares no rules. | |
Variables | |
| constexpr const char * | anonymous_group = "<anonymous>" |
| The group name for rules that do not specify a group. | |
Stateful (model-based) property testing.
A stateful test exercises a system through a sequence of randomly chosen actions ("rules") applied to a state machine. Derive a machine from StateMachine and define its rules(). Each Rule is a name and a step function that performs one application of the rule, drawing any arguments it needs from the test case and mutating the machine. Invariants are predicates on the machine evaluated in full before any step and after the final step, and sampled at intermediate join points. An invariant must throw when violated.
To run a state machine, pass an instance to run inside a hegel::test. Examples in this documentation assume the alias namespace gs = hegel::generators;.
Example: an integer stack.
| void hegel::stateful::run | ( | M & | machine, |
| TestCase & | tc, | ||
| const RunParams & | params = {} ) |
Executes a stateful test by repeatedly applying randomly chosen rules from machine to it. Invariants run in full before the first step and after the final step. Between steps, each invariant is sampled independently. Rules mutate machine in place. Raises std::invalid_argument if the machine declares no rules.
On a failing replay, each applied rule prints as "Step N: <name>". A violated invariant identifies whether it was observed after a step or in the initial or final state.
| M | The state-machine type, deriving from StateMachine |
| machine | The state machine, initialized by the caller and mutated by its rules |
| tc | The test case object |
| params | Options for the run. See RunParams. |
| void hegel::stateful::run_concurrent | ( | M & | machine, |
| TestCase & | tc, | ||
| int64_t | min_concurrency, | ||
| int64_t | max_concurrency ) |
Executes a concurrent stateful test with rules from machine.
The runner selects a concurrency level from min_concurrency through max_concurrency. Execution proceeds in rounds. For each round, libhegel picks a random concurrency group. Every worker thread then runs a short (possibly empty) random sequence of rules from only that group concurrently with the other workers. The runner waits for all workers to finish before it starts the next round.
All invariants run before the first round and after the final round. Between rounds, the runner samples each invariant independently.
Raises std::invalid_argument if the machine declares no rules or if the concurrency bounds are invalid.
On a failing replay, the output shows the concurrency level, each round, the active group, and the rules that each worker applies, but the falsifying test case is not shrunk since the failure may be dependent on thread scheduling.
| M | The state-machine type, deriving from ConcurrentStateMachine |
| machine | The state machine that the workers share |
| tc | The test case object |
| min_concurrency | The minimum number of workers |
| max_concurrency | The maximum number of workers |
| Generator< T > hegel::stateful::values_consumed | ( | ConcurrentPool< T > & | pool | ) |
Returns a value from a concurrent pool and removes it.
The draw rejects the test case if the pool is empty.
| T | The type of the values in the pool |
| pool | The pool to draw from |
Returns a value from the pool and removes it.
| T | Element type |
| p | The pool to draw from |
| Generator< T > hegel::stateful::values_reusable | ( | ConcurrentPool< T > & | pool | ) |
Returns a copy of a value from a concurrent pool.
The draw does not remove the value. It rejects the test case if the pool is empty.
| T | The type of the values in the pool |
| pool | The pool to draw from |
Returns a value from the pool without removing it.
| T | Element type |
| p | The pool to draw from |