Skip to content

Commit

Permalink
Reuse nodes in cets_test_peer
Browse files Browse the repository at this point in the history
cover logic is broken in Erlang 26. So, peer:stop/1 should not be called
  • Loading branch information
arcusfelis committed May 14, 2024
1 parent 0d98f74 commit b9908fc
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Compile
run: rebar3 as test compile
- name: Run tests
run: DEBUG=1 rebar3 cover_tests
run: rebar3 cover_tests
- name: Send test coverage report
run: rebar3 as test codecov analyze
- name: Upload coverage reports to Codecov
Expand Down
1 change: 0 additions & 1 deletion test/app.config

This file was deleted.

47 changes: 19 additions & 28 deletions test/cets_test_peer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,35 @@
-include_lib("common_test/include/ct.hrl").

start(Names, Config) ->
{Nodes, Peers} = lists:unzip([start_node(N) || N <- Names]),
{Nodes, Peers} = lists:unzip([find_or_start_node(N) || N <- Names]),
[
{nodes, maps:from_list(lists:zip(Names, Nodes))},
{peers, maps:from_list(lists:zip(Names, Peers))}
| Config
].

stop(Config) ->
Peers = proplists:get_value(peers, Config),
%% peer:stop/1 freezes in the code cover logic.
%% So, we reuse nodes between different suites.
%% Ensure that the nodes are connected again.
Nodes = proplists:get_value(nodes, Config),
[
slow_task(
"peer:stop:self",
self(),
fun() -> slow_task("peer:stop", Peer, fun() -> peer:stop(Peer) end) end
)
|| Peer <- maps:values(Peers)
reconnect_node(Node, node_to_peer(Node))
|| Node <- maps:values(Nodes)
],
ok.

name(Node) ->
list_to_atom(peer:random_name(atom_to_list(Node))).

find_or_start_node(Id) ->
case persistent_term:get({id_to_node_peer, Id}, undefined) of
undefined ->
start_node(Id);
NodePeer ->
NodePeer
end.

start_node(Id) ->
{ok, Peer, Node} = ?CT_PEER(#{
name => name(Id),
Expand All @@ -47,7 +54,8 @@ start_node(Id) ->
shutdown => 3000
}),
%% Register so we can find Peer process later in code
register(node_to_peer_name(Node), Peer),
persistent_term:put({node_to_peer, Node}, Peer),
persistent_term:put({id_to_node_peer, Id}, {Node, Peer}),
%% Keep nodes running after init_per_suite is finished
unlink(Peer),
%% Do RPC using alternative connection method
Expand All @@ -60,16 +68,13 @@ node_to_peer(Node) when Node =:= node() ->
%% There is no peer for the local CT node
Node;
node_to_peer(Node) when is_atom(Node) ->
case whereis(node_to_peer_name(Node)) of
case persistent_term:get({node_to_peer, Node}) of
Pid when is_pid(Pid) ->
Pid;
undefined ->
ct:fail({node_to_peer_failed, Node})
end.

node_to_peer_name(Node) ->
list_to_atom(atom_to_list(Node) ++ "_peer").

%% Set epmd_port for better coverage
extra_args(ct2) ->
["-epmd_port", "4369"];
Expand All @@ -88,6 +93,7 @@ block_node(Node, Peer) when is_atom(Node), is_pid(Peer) ->

reconnect_node(Node, Peer) when is_atom(Node), is_pid(Peer) ->
rpc(Peer, erlang, set_cookie, [node(), erlang:get_cookie()]),
erlang:set_cookie(Node, erlang:get_cookie()),
%% Very rarely it could return pang
cets_test_wait:wait_until(fun() -> rpc(Peer, net_adm, ping, [node()]) end, pong),
cets_test_wait:wait_until(fun() -> rpc(node(), net_adm, ping, [Node]) end, pong).
Expand All @@ -105,18 +111,3 @@ disconnect_node_by_name(Config, Id) ->
lists:member(Node, nodes())
end,
cets_test_wait:wait_until(F, false).

slow_task(What, Self, F) ->
Pid = spawn_link(fun() -> monitor_loop(What, Self) end),
Res = F(),
Pid ! stop,
Res.

monitor_loop(What, Pid) ->
receive
stop ->
ok
after 1000 ->
ct:pal("monitor_loop ~p ~p", [What, erlang:process_info(Pid, current_stacktrace)]),
monitor_loop(What, Pid)
end.

0 comments on commit b9908fc

Please sign in to comment.