[erlang-questions] How to mimic Erlang nodes in PropEr statem test
Fred Hebert
mononcqc@REDACTED
Fri Jan 25 14:03:06 CET 2019
On 01/23, Nyirő Gergő wrote:
>
>Right now I have only one gen_server (crdt_server) per node, but I would
>like to add an event handler (crdt_event) which could persist the content
>of the crdt set or log the executed commands.
>
Okay, so that's essentially duplicating the messages: send them to the
server, but you want to asynchronously log with another process. Do I
understand this right?
>crdt_event could be registered with a fix name then all the
>crdt_server processes
>in the proper statem test will send the events to the same event handler, so
>the event has to be extended with a reference to the sender (e.g: the name
>or pid of the crdt_server). It seems too complicated for my situation.
Is the event handler only required for the tests? If so, that can make
sense. If you're working with the same design for your production
system, it would generally be a better idea to have one process that
handles the logging per CRDT server, assuming what you end up with is
one file per server, in order.
Using the same handler for multiple servers is a possibility, but you
have a lot more risk and complexity—as you noted, you'd need to start
identifying each message, rather than just giving the event manager a
destination where to output traffic—while coupling the runtime of
unrelated files.
>
>Other solution would be to pass the NameOrPid of the crdt_event processes to
>crdt_server processes, but a process registry could be a more elegant solution.
>
This is a possibility. There are other options such as:
- Each crdt_server is spawned under a crdt_sup. The crdt_sup works by
booting two processes: crdt_log (first) and crdt_server (second). Each
is passed a name that identifies the server ("crdt_1", `node_a`, or
whatever)
- By using a dynamic process registry like gproc (see
https://hex.pm/packages/gproc) and replacing the name registration
from {local, Name} to {via, gproc, {n, l, {crdt_log, Name}}} and {via,
gproc, {n, l, {crdt_server, Name}}} you can give them unique names
that they can "know"
- On every call the crdt_server wants to log, it can call a function
from the crdt_log module, such as crdt_log:do_log(Name, Contents)
If you implement the latter function as:
-module(crdt_log).
...
start_link(Name) ->
%% {n, l, Name} stands for "{name, local, ActualName}" but gproc
%% uses shorthand
gen_server:start_link({via, gproc, {n, l, {crdt_log, Name}}},
?MODULE, [], []).
...
do_log(Name, Event) ->
gen_server:cast({via, gproc, {n, l, {crdt_log, Name}}}, Event).
...
Then you'll be able to call the log process from within the other one
and send asynchronous events this way. You can then consider both
processes as one unit that fits under one supervisor. For your test, you
now want to boot 3 of these supervisors instead of only 3 servers, and
you should get a rather transparent layer added otherwise.
>Should I use ct_property_test [1] instead?
>
This is an experimental call or module to integrate the results of your
properties to the common test flow. You're free to use it if you want to
integrate everything into CT.
I personally maintain the rebar3 plugin for PropEr and I tend to prefer
it for some of the additional features it adds:
- meta functions
https://github.com/ferd/rebar3_proper#per-properties-meta-functions
(which I might need to contribute upstream to PropEr instead)
- The ability to run a `rebar3 proper --retry` to get the last failing
case run again
- The `rebar3 proper --store` call, which can be called after a failure
to store the failing cases in a file that can be used to test
regressions
- The `rebar3 proper --regressions` switch, which replays the previously
stored couterexamples.
You can, of course, get all of this by doing more manual work in CT or
by transcribing counterexamples by hand into regression tests. I
personally just use the proper and CT commands distinctly, and instead
add a rebar3 alias for both:
{alias, [{check, [ct, proper]}]}.
Which then lets me call 'rebar3 check' and runs both the CT and the
PropEr test suites.
Regards,
Fred.
More information about the erlang-questions
mailing list