Output from proper_viz_gantt:render/2 and proper_viz_mermaid:render/2 applied to a katipo streaming body statem test. Each Upload/Get handle gets its own section (Gantt) or column (Sequence).
Each section is a handle. Time flows left-to-right. Shows concurrent uploads and gets, an await_uploading timeout on Upload-5, and the recovery (finish after timeout).
gantt
dateFormat X
axisFormat %s
section Get-1
start_get() → ok :1, 2
await_response() → ok :2, 3
section Get-2
start_get() → ok :3, 4
await_response() → ok :4, 5
section Upload-3
start_upload() → ok :5, 6
finish_upload() → ok :6, 7
await_response() → ok :7, 8
section Get-4
start_get() → ok :8, 9
send_chunk("iw") → ok :9, 10
await_response() → ok :10, 11
section Upload-5
start_upload() → ok :11, 12
await_uploading() → timeout :crit, 12, 13
finish_upload() → ok :13, 14
section Get-6
start_get() → ok :14, 15
await_response() → ok :15, 16
section Upload-7
start_upload() → ok :16, 17
finish_upload() → ok :17, 18
await_response() → ok :18, 19
Same test run. Shows the call/return flow between the test harness and each handle.
sequenceDiagram
participant Test
participant Get-1
participant Get-2
participant Upload-3
participant Get-4
participant Upload-5
participant Get-6
participant Upload-7
Test->>Get-1: start_get()
Get-1-->>Test: {ok, Handle}
Test->>Get-1: await_response({var,1})
Get-1-->>Test: {ok, #{status => 200, ...}}
Test->>Get-2: start_get()
Get-2-->>Test: {ok, Handle}
Test->>Upload-3: start_upload()
Upload-3-->>Test: {ok, Handle}
Test->>Get-2: await_response({var,3})
Get-2-->>Test: {ok, #{status => 200, ...}}
Test->>Get-4: start_get()
Get-4-->>Test: {ok, Handle}
Test->>Upload-5: start_upload()
Upload-5-->>Test: {ok, Handle}
Test->>Upload-3: finish_upload({var,4})
Upload-3-->>Test: ok
Test->>Get-4: send_chunk({var,6}, <<"iw">>)
Get-4-->>Test: ok
Test->>Upload-5: await_uploading({var,7})
Upload-5--x Test: {error, #{code => await_timeout}}
Test->>Upload-3: await_response({var,4})
Upload-3-->>Test: {ok, #{status => 200, ...}}
Test->>Get-4: await_response({var,6})
Get-4-->>Test: {ok, #{status => 200, ...}}
Test->>Upload-5: finish_upload({var,7})
Upload-5-->>Test: ok
Test->>Get-6: start_get()
Get-6-->>Test: {ok, Handle}
Test->>Get-6: await_response({var,12})
Get-6-->>Test: {ok, #{status => 200, ...}}
Test->>Upload-7: start_upload()
Upload-7-->>Test: {ok, Handle}
Test->>Upload-7: finish_upload({var,13})
Upload-7-->>Test: ok
Test->>Upload-7: await_response({var,13})
Upload-7-->>Test: {ok, #{status => 200, ...}}
-include_lib("proper_viz/src/proper_viz.hrl").
prop_streaming(BaseUrl, Opts) ->
?FORALL(Cmds, commands(?MODULE),
begin
{History, S, Res} = run_commands(?MODULE, Cmds),
cleanup(S),
Trace = proper_viz:from_run(?MODULE, Cmds, History, S),
ActorOpts = #{actors => fun actor/1},
Gantt = proper_viz_gantt:render(Trace, ActorOpts),
Mermaid = proper_viz_mermaid:render(Trace, ActorOpts),
?WHENFAIL(
ct:pal("Gantt:~n~s~nSequence:~n~s~nResult: ~p",
[Gantt, Mermaid, Res]),
aggregate(command_names(Cmds), Res =:= ok))
end).
actor(#viz_event{symbolic = {_, start_upload, _}}) -> {new, <<"Upload">>};
actor(#viz_event{symbolic = {_, start_get, _}}) -> {new, <<"Get">>};
actor(#viz_event{symbolic = {_, _, [Handle | _]}}) -> {handle, Handle};
actor(#viz_event{}) -> {static, <<"SUT">>}.