Debugging, improved logging, etc.
This commit is contained in:
@@ -16,13 +16,16 @@ for the duration of such a sequence, and this tends to lead to hacking
|
||||
a plain process with a custom protocol.
|
||||
|
||||
This application attempts to make that a bit more structured.
|
||||
In its initial version, there are two APIs:
|
||||
In its initial version, there are a few different APIs:
|
||||
|
||||
* `gm_ctflow_fun`, where one can instantiate a stateful handler fun,
|
||||
which can be called by test cases as needed.
|
||||
* `gm_ctflow_worker`, a gen_server where the server logic is given
|
||||
by a user-provided fun. The server is spawned under a
|
||||
`simple_one_for_one` supervisor.
|
||||
* `gm_ctflow_reg`, used to register and find `gm_ctflow_worker` processes.
|
||||
Complies with the `via` addressing scheme for OTP behaviors.
|
||||
* `gm_ctflow`, providing a shared dictionary, logging and status support.
|
||||
|
||||
The application `gm_ctflow` is intended to be started in
|
||||
`init_per_suite/1` and stopped in `end_per_suite/1`, or in
|
||||
@@ -70,6 +73,60 @@ end_per_group(_Grp, _Config) ->
|
||||
|
||||
This resets the state and removes all helper processes for each group.
|
||||
|
||||
A simple way to keep track of the flow state:
|
||||
|
||||
```erlang
|
||||
init_per_testcase(_Case, Config) ->
|
||||
gm_ctflow:status(),
|
||||
Config.
|
||||
|
||||
end_per_testcase(_Case, _Config) ->
|
||||
gm_ctflow:status(),
|
||||
ok.
|
||||
```
|
||||
|
||||
This gives output like this, from the `gm_ctflow_SUITE:incr/1` testcase:
|
||||
```
|
||||
*** User 2026-05-30 13:06:02.679 ***🔗
|
||||
== Summary for flow my_counter
|
||||
= Worker State: - none -
|
||||
= Fun State: 0
|
||||
= State: - none -
|
||||
= Log History:
|
||||
|
||||
2026-05-30 13:06:02.654:
|
||||
New flow: my_counter
|
||||
|
||||
|
||||
|
||||
*** User 2026-05-30 13:06:02.679 ***🔗
|
||||
my_counter[<0.332.0>]: F(incr, 0) -> {ok,1,1}
|
||||
|
||||
*** User 2026-05-30 13:06:02.679 ***🔗
|
||||
== Summary for flow my_counter
|
||||
= Worker State: - none -
|
||||
= Fun State: 1
|
||||
= State: - none -
|
||||
= Log History:
|
||||
|
||||
2026-05-30 13:06:02.654:
|
||||
New flow: my_counter
|
||||
|
||||
2026-05-30 13:06:02.679:
|
||||
F(incr, 0) -> {ok,1,1}
|
||||
```
|
||||
|
||||
Normally, of course, there would be more going on in the test, making the
|
||||
bookends a bit less dominant, but here we see the initial state of the flow
|
||||
`my_counter`: The "Fun state" is `0`, while there's no worker, and no shared state.
|
||||
The log history shows one previous message, from instantiating the fun.
|
||||
|
||||
The next log output shows the effect of calling the fun. Log messages produced
|
||||
with `gm_ctflow:ct_log/[2,3]` go both to `ct:log/2` and the log history. The
|
||||
flow is derived automatically, if possible, if not provided.
|
||||
|
||||
In the ending `status` output, we see the accumulated history, with timestamps
|
||||
to make it easier to find the context in CT or SUT logs.
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
Reference in New Issue
Block a user