Module molly.gen
Module with functions for generators.
One of the key pieces of a Molly test is a generators for client and
nemesis operations. These generators will create a finite or infinite
sequence of operations. It is often test have its own nemesis generator, but
most likely shares a common client generator with other tests. A nemesis
generator, for instance, might be a sequence of partition, sleep, and
restore, repeated infinitely. A client generator will specify a random,
infinite sequence of client operation, as well as the associated parameters
such as durability level, the document key, the new value to write or CAS
(Compare-And-Set), etc. When a test starts, the client generator feeds
client operations to the client and the nemesis generator feeds operations
to the nemesis. The test will continue until either the nemesis generator
has completed a specified number of operations, a time limit is reached, or
an error is thrown.
Example of generator that generates two operations w
and r
:
local w = function() return { f = 'w', v = math.random(1, 10) } end
local r = function() return { f = 'r', v = nil } end
gen.rands(0, 2):map(function(x)
return (x == 0 and r()) or
(x == 1 and w()))
end):take(100)
local w = function(x) return { f = 'w', v = x } end
gen.map(w, gen.rands(1, 10):take(50))
References:
filter () |
Return a new iterator of those elements that satisfy the predicate . |
remove_if () |
An alias for filter(). |
grep () |
If regexporpredicate is string then the parameter is used as a regular
expression to build filtering predicate. |
partition () |
The function returns two iterators where elements do and do not satisfy the
predicate. |
foldl () |
The function reduces the iterator from left to right using the binary
operator accfun and the initial value initval . |
reduce () |
An alias to foldl(). |
length () |
Return a number of elements in gen, param, state iterator. |
totable () |
Return a new table (array) from iterated values. |
tomap () |
Return a new table (map) from iterated values. |
zip (...) |
Return a new iterator where i-th return value contains the i-th element
from each of the iterators. |
cycle (iterator) |
A cycled version of an iterator. |
chain (...) |
Make an iterator that returns elements from the first iterator until it is
exhausted, then proceeds to the next iterator, until all of the iterators are
exhausted. |
cycle_times (...) |
(TODO) Cycles between several generators on a rotating schedule. |
mix (...) |
(TODO) A random mixture of several generators. |
flip_flop (a, b) |
(TODO) Emits an operation from generator A, then B, then A again, then B again,
etc. |
log () |
(TODO) A generator which, when asked for an operation, logs a message and yields
nil. |
stagger (dt) |
(TODO) Operations from that generator are scheduled at uniformly random intervals
between 0 to 2 * (dt seconds) . |
time_limit (duration) |
Stops generating items when time limit is exceeded. |
Basic Functions
-
iter (object)
-
Make an iterator from the iterable object.
See fun.iter.
Parameters:
- object
- an iterable object (map, array, string).
Returns:
an iterator
Usage:
> for _it, v in gen.iter({1, 2, 3}) do print(v) end
1
2
3
...
> for _it, v in gen.iter({a = 1, b = 2, c = 3}) do print(v) end
b
a
c
...
> for _it, v in gen.iter("abc") do print(v) end
a
b
c
...
-
each (function, iterator)
-
Execute the function
fun
for each iteration value.
See fun.each.
Parameters:
- function
- iterator
- an iterator or iterable object
Returns:
none
Usage:
> gen.each(print, { a = 1, b = 2, c = 3})
b 2
a 1
c 3
...
-
for_each ()
-
An alias for each().
See gen.each .
-
foreach ()
-
An alias for each().
See gen.each .
Generators: Finite Generators
-
range ([start], stop[, step])
-
The iterator to create arithmetic progressions.
Iteration values are generated within closed interval
[start, stop]
(i.e.
stop
is included). If the start
argument is omitted, it defaults to 1 (stop
> 0
) or to -1 (stop < 0
). If the step
argument is omitted, it defaults to 1
(start <= stop
) or to -1 (start > stop
). If step
is positive, the last
element is the largest start + i * step
less than or equal to stop
; if step
is negative, the last element is the smallest start + i * step
greater than
or equal to stop
. step
must not be zero (or else an error is raised).
range(0)
returns empty iterator.
See fun.range.
Parameters:
- start
number
– an endpoint of the interval.
- stop
number
– an endpoint of the interval.
- step
number
– a step.
Returns:
an iterator
Usage:
> for _it, v in gen.range(1, 6) do print(v) end
1
2
3
4
5
6
...
> for _it, v in gen.range(1, 6, 2) do print(v) end
1
3
5
...
Generators: Infinity Generators
-
duplicate ()
-
The iterator returns values over and over again indefinitely. All values
that passed to the iterator are returned as-is during the iteration.
See fun.duplicate.
Usage:
> gen.each(print, gen.take(3, gen.duplicate('a', 'b', 'c')))
a b c
a b c
a b c
...
-
xrepeat ()
-
An alias for duplicate().
See gen.duplicate .
-
replicate ()
-
An alias for duplicate().
See gen.duplicate .
-
tabulate ()
-
Return
fun(0)
, fun(1)
, fun(2)
, ... values indefinitely.
See fun.tabulate.
Generators: Random sampling
-
rands ()
-
See fun.rands.
Slicing: Subsequences
-
take_n ()
-
See fun.take_n.
-
take_while ()
-
See fun.take_while.
-
take ()
-
See fun.take.
-
drop_n ()
-
See fun.drop_n.
-
drop_while ()
-
See fun.drop_while.
-
drop ()
-
See fun.drop.
-
span ()
-
See fun.span.
-
split ()
-
An alias for span().
See
fun.span
.
-
split_at ()
-
An alias for span().
See
fun.span
.
Indexing
-
index ()
-
See fun.index.
-
index_of ()
-
An alias for index().
See
fun.index
.
-
elem_index ()
-
An alias for index().
See
fun.index
.
-
indexes ()
-
See fun.indexes.
-
indices ()
-
An alias for indexes().
See
fun.indexes
.
-
elem_indexes ()
-
An alias for indexes().
See
fun.indexes
.
-
elem_indices ()
-
An alias for indexes().
See
fun.indexes
.
Filtering
-
filter ()
-
Return a new iterator of those elements that satisfy the
predicate
.
See fun.filter.
-
remove_if ()
-
An alias for filter().
See gen.filter .
-
grep ()
-
If
regexporpredicate
is string then the parameter is used as a regular
expression to build filtering predicate. Otherwise the function is just an
alias for gen.filter().
See fun.grep.
-
partition ()
-
The function returns two iterators where elements do and do not satisfy the
predicate.
See fun.partition.
Reducing: Folds
-
foldl ()
-
The function reduces the iterator from left to right using the binary
operator
accfun
and the initial value initval
.
See fun.foldl.
-
reduce ()
-
An alias to foldl().
See gen.foldl .
-
length ()
-
Return a number of elements in
gen, param, state
iterator.
See fun.length.
-
totable ()
-
Return a new table (array) from iterated values.
See fun.totable.
-
tomap ()
-
Return a new table (map) from iterated values.
See fun.tomap.
Reducing: Predicates
-
is_prefix_of ()
-
See fun.isprefixof.
-
is_null ()
-
See fun.is_null.
-
all ()
-
See fun.all.
-
every ()
-
An alias for all().
See
fun.all
.
-
any ()
-
See fun.any.
-
some ()
-
An alias for any().
See
fun.any
.
Transformations
-
map ()
-
See fun.map.
-
enumerate ()
-
See fun.enumerate.
-
intersperse ()
-
See fun.intersperse.
Compositions
-
zip (...)
-
Return a new iterator where i-th return value contains the i-th element
from each of the iterators. The returned iterator is truncated in length to
the length of the shortest iterator. For multi-return iterators only the
first variable is used.
See fun.zip.
Parameters:
Returns:
an iterator
-
cycle (iterator)
-
A cycled version of an iterator.
Make a new iterator that returns elements from
{gen, param, state}
iterator
until the end and then "restart" iteration using a saved clone of {gen,
param, state}
. The returned iterator is constant space and no return values
are buffered. Instead of that the function make a clone of the source {gen,
param, state}
iterator. Therefore, the source iterator must be pure
functional to make an indentical clone. Infinity iterators are supported,
but are not recommended.
See fun.cycle.
Parameters:
Returns:
an iterator
-
chain (...)
-
Make an iterator that returns elements from the first iterator until it is
exhausted, then proceeds to the next iterator, until all of the iterators are
exhausted. Used for treating consecutive iterators as a single iterator.
Infinity iterators are supported, but are not recommended.
See fun.chain.
Parameters:
Returns:
an iterator, a consecutive iterator from sources (left from right).
Usage:
> fun.each(print, fun.chain(fun.range(5, 1, -1), fun.range(1, 5)))
5
4
3
2
1
1
2
3
4
5
...
-
cycle_times (...)
-
(TODO) Cycles between several generators on a rotating schedule.
Takes a flat series of [time, generator] pairs.
Parameters:
Returns:
an iterator
-
mix (...)
-
(TODO) A random mixture of several generators. Takes a collection of generators
and chooses between them uniformly.
To be precise, a mix behaves like a sequence of one-time, randomly selected
generators from the given collection. This is efficient and prevents
multiple generators from competing for the next slot, making it hard to
control the mixture of operations.
Parameters:
Returns:
an iterator
-
flip_flop (a, b)
-
(TODO) Emits an operation from generator A, then B, then A again, then B again,
etc. Stops as soon as any gen is exhausted.
Parameters:
- a
number
generator A.
- b
number
generator B.
Returns:
an iterator
Special generators
-
log ()
-
(TODO) A generator which, when asked for an operation, logs a message and yields
nil. Occurs only once; use
repeat
to repeat.
Returns:
an iterator
-
stagger (dt)
-
(TODO) Operations from that generator are scheduled at uniformly random intervals
between
0
to 2 * (dt seconds)
.
Parameters:
- dt
number
Number of seconds.
Returns:
an iterator
-
time_limit (duration)
-
Stops generating items when time limit is exceeded.
Parameters:
- duration
number
Number of seconds.
Returns:
an iterator
Usage:
> for _it, v in gen.time_limit(gen.range(1, 100), 0.0001) do print(v) end
1
2
3
4
5
6
7
8
9
10
11
12
...