File 0742-kernel-Make-net_kernel-allowed-0-documented-with-spe.patch of Package erlang
From 12a722ce85d571dd8a6adeb2cf79ac619f9e0563 Mon Sep 17 00:00:00 2001
From: Marko Mindek <marko.mindek@gmail.com>
Date: Thu, 29 Feb 2024 21:33:08 +0100
Subject: [PATCH 2/2] kernel: Make net_kernel:allowed/0 documented with spec
and tests
Co-authored-by: Kiko Fernandez-Reyes <kiko@erlang.org>
Co-authored-by: Sverker Eriksson <sverker@erlang.org>
---
lib/kernel/src/net_kernel.erl | 22 +++-
lib/kernel/test/erl_distribution_SUITE.erl | 142 ++++++++++++++++++++-
2 files changed, 154 insertions(+), 10 deletions(-)
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index d65ce22c2f..54e9b8f879 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -156,13 +156,13 @@ in the Erlang Reference Manual.
-record(tick,
{ticker :: pid(), %% ticker
time :: pos_integer(), %% net tick time (ms)
- intensity :: 4..1000 %% ticks until timout
+ intensity :: 4..1000 %% ticks until timeout
}).
-record(tick_change,
{ticker :: pid(), %% ticker
time :: pos_integer(), %% net tick time (ms)
- intensity :: 4..1000, %% ticks until timout
+ intensity :: 4..1000, %% ticks until timeout
how :: 'longer' | 'shorter' %% What type of change
}).
@@ -186,10 +186,12 @@ dflag_unicode_io(_) ->
kernel_apply(M,F,A) -> request({apply,M,F,A}).
--spec allow(Nodes) -> ok | error when
+-spec allow(Nodes) -> ok | error | ignored when
Nodes :: [node()].
allow(Nodes) -> request({allow, Nodes}).
+-spec allowed() -> {ok, Nodes} | ignored when
+ Nodes :: [node()].
allowed() -> request(allowed).
longnames() -> request(longnames).
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index dc6f9072a2..5e72b9a212 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -54,7 +54,8 @@
erl_1424/1, net_kernel_start/1, differing_cookies/1,
cmdline_setcookie_2/1, connection_cookie/1,
dyn_differing_cookies/1,
- xdg_cookie/1]).
+ xdg_cookie/1,
+ allowed/1]).
%% Performs the test at another node.
-export([get_socket_priorities/0,
@@ -77,7 +78,8 @@
-export([pinger/1]).
--export([start_uds_rpc_server/1]).
+-export([start_uds_rpc_server/1,
+ wait_node_down/1]).
-define(DUMMY_NODE,dummy@test01).
-define(ALT_EPMD_PORT, "12321").
@@ -107,7 +109,9 @@ all() ->
{group, monitor_nodes},
erl_uds_dist_smoke_test,
erl_1424, net_kernel_start,
- {group, differing_cookies}].
+ {group, differing_cookies},
+ allowed
+ ].
groups() ->
[{monitor_nodes, [],
@@ -137,6 +141,11 @@ end_per_suite(_Config) ->
init_per_group(_GroupName, Config) ->
Config.
+end_per_group(monitor_nodes, Config) ->
+ %% we disconnect existing nodes because they interfere
+ %% with other tests where `nodes() == []` but it wasn't.
+ ok = kill_existing_nodes(),
+ Config;
end_per_group(_GroupName, Config) ->
Config.
@@ -1582,13 +1591,23 @@ monitor_nodes_otp_6481(Config) when is_list(Config) ->
monitor_nodes_otp_6481(DCfg, Config) ->
io:format("Testing nodedown...~n"),
- monitor_nodes_otp_6481_test(DCfg, Config, nodedown),
+ ok = monitor_nodes_otp_6481_test(DCfg, Config, nodedown),
io:format("ok~n"),
io:format("Testing nodeup...~n"),
- monitor_nodes_otp_6481_test(DCfg, Config, nodeup),
+ ok = monitor_nodes_otp_6481_test(DCfg, Config, nodeup),
io:format("ok~n"),
ok.
+kill_existing_nodes() ->
+ kill_existing_nodes(nodes()),
+ ok.
+
+kill_existing_nodes([]) -> ok;
+kill_existing_nodes([Node | Nodes]) ->
+ catch erpc:call(Node, erlang, halt, []),
+ kill_existing_nodes(Nodes).
+
+
monitor_nodes_otp_6481_test(DCfg, Config, TestType) when is_list(Config) ->
MonNodeState = monitor_node_state(),
NodeMsg = make_ref(),
@@ -2719,7 +2738,120 @@ xdg_cookie(Config) when is_list(Config) ->
ok.
+allowed(_Config) ->
+ %% inspired by differing_cookies/1
+ test_server:timetrap({minutes, 1}),
+ NodeT = node(),
+ true = NodeT =/= nonode@nohost,
+ [] = nodes(),
+ BaseName = atom_to_list(?FUNCTION_NAME),
+
+ %% Use -hidden nodes to avoid global connecting all nodes
+
+ %% Start node A
+ NodeAName = BaseName++"_nodeA",
+ NodeA = full_node_name(NodeAName),
+ { ok, NodeA } =
+ start_node( "-hidden", NodeAName),
+
+ %% allow NodeT on NodeA so that other connections are dismissed
+ {ok,[]} = rpc:call(NodeA, net_kernel, allowed, []),
+ ok = rpc:call(NodeA, net_kernel, allow, [[NodeT]]),
+ {ok,[NodeT]} = rpc:call(NodeA, net_kernel, allowed, []),
+ try
+
+ %% Verify the cluster
+ [ NodeA ] = nodes(hidden),
+ [ NodeT ] = rpc:call( NodeA, erlang, nodes, [hidden] ),
+
+ %% Start node B
+ NodeBName = BaseName++"_nodeB",
+ NodeB = full_node_name(NodeBName),
+ { ok, NodeB } =
+ start_node( "-hidden", NodeBName),
+
+ try
+
+ %% Verify the cluster
+ equal_sets( [NodeA, NodeB], nodes(hidden) ),
+ [ NodeT ] = rpc:call( NodeA, erlang, nodes, [hidden] ),
+ [ NodeT ] = rpc:call( NodeB, erlang, nodes, [hidden] ),
+
+ %% Verify that the nodes can not connect as A does not allow B.
+ pang = rpc:call( NodeA, net_adm, ping, [NodeB] ),
+ pang = rpc:call( NodeB, net_adm, ping, [NodeA] ),
+
+ %% Allow node B on node A
+ ok = rpc:call(NodeA, net_kernel, allow, [[NodeB]]),
+ {ok,N_B} = rpc:call(NodeA, net_kernel, allowed, []),
+ equal_sets([NodeT,NodeB], N_B),
+ pong = rpc:call(NodeA, net_adm, ping, [NodeB]),
+ %% Verify the cluster
+ equal_sets( [NodeA, NodeB], nodes(hidden) ),
+ equal_sets( [NodeT, NodeB],
+ rpc:call( NodeA, erlang, nodes, [hidden] )),
+ equal_sets( [NodeT, NodeA],
+ rpc:call( NodeB, erlang, nodes, [hidden] )),
+
+ %% Disconnect and connect the other way (B -> A)
+ true = rpc:call( NodeB, net_kernel, disconnect, [NodeA] ),
+ [NodeT] = rpc:call( NodeA, ?MODULE, wait_node_down, [NodeB] ),
+ [NodeT] = rpc:call( NodeB, ?MODULE, wait_node_down, [NodeA] ),
+ pong = rpc:call(NodeB, net_adm, ping, [NodeA]),
+
+ %% Verify the cluster
+ equal_sets( [NodeA, NodeB], nodes(hidden) ),
+ equal_sets( [NodeT, NodeB],
+ rpc:call( NodeA, erlang, nodes, [hidden] )),
+ equal_sets( [NodeT, NodeA],
+ rpc:call( NodeB, erlang, nodes, [hidden] )),
+
+ %% Disallow node A on node B (by allowing node T)
+ %% and verify it does not affect the existing connection
+ ok = rpc:call(NodeB, net_kernel, allow, [[NodeT]]),
+ {ok,[NodeT]} = rpc:call(NodeB, net_kernel, allowed, []),
+ equal_sets([NodeT, NodeA],
+ rpc:call( NodeB, erlang, nodes, [hidden] )),
+
+ %% Disconnect and fail to reconnect
+ true = rpc:call( NodeB, net_kernel, disconnect, [NodeA] ),
+ [NodeT] = rpc:call( NodeA, ?MODULE, wait_node_down, [NodeB] ),
+ pang = rpc:call( NodeA, net_adm, ping, [NodeB] ),
+ pang = rpc:call( NodeB, net_adm, ping, [NodeA] ),
+
+ %% Allow node T again and verify its only returned once.
+ ok = rpc:call(NodeB, net_kernel, allow, [[NodeT]]),
+ {ok,[NodeT]} = rpc:call(NodeB, net_kernel, allowed, []),
+
+ %% Test non-registered process
+ %% 'net_kernel' is registered to a process
+ %% so we unregister it to test the output 'ignored'
+ ok = rpc:call(NodeA, erts_internal, dynamic_node_name, [false]),
+ true = rpc:call(NodeA, erlang, unregister, [net_kernel]),
+ ignored = rpc:call(NodeA, net_kernel, allow, [[NodeB]])
+ after
+ _ = stop_node(NodeB)
+ end
+ after
+ _ = stop_node(NodeA)
+ end,
+ [] = nodes(hidden),
+ ok.
+
+wait_node_down(Node) ->
+ net_kernel:monitor_nodes(true, [all]),
+ Timeout = case lists:member(Node, nodes(connected)) of
+ true -> 10_000;
+ false -> 0
+ end,
+ receive
+ {nodedown, Node} -> ok
+ after
+ Timeout -> ok
+ end,
+ net_kernel:monitor_nodes(false, [all]),
+ nodes(connected).
%% Misc. functions
--
2.43.0