fix(test): avoid port collision
Use OS selected free port to avoid port collision among the test runs.
This commit is contained in:
parent
c78004001c
commit
abf150518c
|
@ -59,7 +59,8 @@
|
||||||
read_schema_configs/2,
|
read_schema_configs/2,
|
||||||
render_config_file/2,
|
render_config_file/2,
|
||||||
wait_for/4,
|
wait_for/4,
|
||||||
wait_mqtt_payload/1
|
wait_mqtt_payload/1,
|
||||||
|
select_free_port/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -1242,3 +1243,34 @@ get_or_spawn_janitor() ->
|
||||||
on_exit(Fun) ->
|
on_exit(Fun) ->
|
||||||
Janitor = get_or_spawn_janitor(),
|
Janitor = get_or_spawn_janitor(),
|
||||||
ok = emqx_test_janitor:push_on_exit_callback(Janitor, Fun).
|
ok = emqx_test_janitor:push_on_exit_callback(Janitor, Fun).
|
||||||
|
|
||||||
|
%%-------------------------------------------------------------------------------
|
||||||
|
%% Select a free transport port from the OS
|
||||||
|
%%-------------------------------------------------------------------------------
|
||||||
|
%% @doc get unused port from OS
|
||||||
|
-spec select_free_port(tcp | udp | ssl | quic) -> inets:port_number().
|
||||||
|
select_free_port(tcp) ->
|
||||||
|
select_free_port(gen_tcp, listen);
|
||||||
|
select_free_port(udp) ->
|
||||||
|
select_free_port(gen_udp, open);
|
||||||
|
select_free_port(ssl) ->
|
||||||
|
select_free_port(tcp);
|
||||||
|
select_free_port(quic) ->
|
||||||
|
select_free_port(udp).
|
||||||
|
|
||||||
|
select_free_port(GenModule, Fun) when
|
||||||
|
GenModule == gen_tcp orelse
|
||||||
|
GenModule == gen_udp
|
||||||
|
->
|
||||||
|
{ok, S} = GenModule:Fun(0, [{reuseaddr, true}]),
|
||||||
|
{ok, Port} = inet:port(S),
|
||||||
|
ok = GenModule:close(S),
|
||||||
|
case os:type() of
|
||||||
|
{unix, darwin} ->
|
||||||
|
%% in MacOS, still get address_in_use after close port
|
||||||
|
timer:sleep(500);
|
||||||
|
_ ->
|
||||||
|
skip
|
||||||
|
end,
|
||||||
|
ct:pal("Select free OS port: ~p", [Port]),
|
||||||
|
Port.
|
||||||
|
|
|
@ -47,13 +47,14 @@ init_per_testcase(Case, Config) when
|
||||||
Case =:= t_max_conns_tcp; Case =:= t_current_conns_tcp
|
Case =:= t_max_conns_tcp; Case =:= t_current_conns_tcp
|
||||||
->
|
->
|
||||||
catch emqx_config_handler:stop(),
|
catch emqx_config_handler:stop(),
|
||||||
|
Port = emqx_common_test_helpers:select_free_port(tcp),
|
||||||
{ok, _} = emqx_config_handler:start_link(),
|
{ok, _} = emqx_config_handler:start_link(),
|
||||||
PrevListeners = emqx_config:get([listeners], #{}),
|
PrevListeners = emqx_config:get([listeners], #{}),
|
||||||
PureListeners = remove_default_limiter(PrevListeners),
|
PureListeners = remove_default_limiter(PrevListeners),
|
||||||
PureListeners2 = PureListeners#{
|
PureListeners2 = PureListeners#{
|
||||||
tcp => #{
|
tcp => #{
|
||||||
listener_test => #{
|
listener_test => #{
|
||||||
bind => {"127.0.0.1", 9999},
|
bind => {"127.0.0.1", Port},
|
||||||
max_connections => 4321,
|
max_connections => 4321,
|
||||||
limiter => #{}
|
limiter => #{}
|
||||||
}
|
}
|
||||||
|
@ -63,19 +64,20 @@ init_per_testcase(Case, Config) when
|
||||||
|
|
||||||
ok = emqx_listeners:start(),
|
ok = emqx_listeners:start(),
|
||||||
[
|
[
|
||||||
{prev_listener_conf, PrevListeners}
|
{prev_listener_conf, PrevListeners},
|
||||||
|
{tcp_port, Port}
|
||||||
| Config
|
| Config
|
||||||
];
|
];
|
||||||
init_per_testcase(t_wss_conn, Config) ->
|
init_per_testcase(t_wss_conn, Config) ->
|
||||||
catch emqx_config_handler:stop(),
|
catch emqx_config_handler:stop(),
|
||||||
|
Port = emqx_common_test_helpers:select_free_port(ssl),
|
||||||
{ok, _} = emqx_config_handler:start_link(),
|
{ok, _} = emqx_config_handler:start_link(),
|
||||||
|
|
||||||
PrevListeners = emqx_config:get([listeners], #{}),
|
PrevListeners = emqx_config:get([listeners], #{}),
|
||||||
PureListeners = remove_default_limiter(PrevListeners),
|
PureListeners = remove_default_limiter(PrevListeners),
|
||||||
PureListeners2 = PureListeners#{
|
PureListeners2 = PureListeners#{
|
||||||
wss => #{
|
wss => #{
|
||||||
listener_test => #{
|
listener_test => #{
|
||||||
bind => {{127, 0, 0, 1}, 9998},
|
bind => {{127, 0, 0, 1}, Port},
|
||||||
limiter => #{},
|
limiter => #{},
|
||||||
ssl_options => #{
|
ssl_options => #{
|
||||||
cacertfile => ?CERTS_PATH("cacert.pem"),
|
cacertfile => ?CERTS_PATH("cacert.pem"),
|
||||||
|
@ -89,7 +91,8 @@ init_per_testcase(t_wss_conn, Config) ->
|
||||||
|
|
||||||
ok = emqx_listeners:start(),
|
ok = emqx_listeners:start(),
|
||||||
[
|
[
|
||||||
{prev_listener_conf, PrevListeners}
|
{prev_listener_conf, PrevListeners},
|
||||||
|
{wss_port, Port}
|
||||||
| Config
|
| Config
|
||||||
];
|
];
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(_, Config) ->
|
||||||
|
@ -171,20 +174,30 @@ t_restart_listeners_with_hibernate_after_disabled(_Config) ->
|
||||||
ok = emqx_listeners:stop(),
|
ok = emqx_listeners:stop(),
|
||||||
emqx_config:put([listeners], OldLConf).
|
emqx_config:put([listeners], OldLConf).
|
||||||
|
|
||||||
t_max_conns_tcp(_) ->
|
t_max_conns_tcp(Config) ->
|
||||||
%% Note: Using a string representation for the bind address like
|
%% Note: Using a string representation for the bind address like
|
||||||
%% "127.0.0.1" does not work
|
%% "127.0.0.1" does not work
|
||||||
?assertEqual(4321, emqx_listeners:max_conns('tcp:listener_test', {{127, 0, 0, 1}, 9999})).
|
?assertEqual(
|
||||||
|
4321,
|
||||||
|
emqx_listeners:max_conns('tcp:listener_test', {{127, 0, 0, 1}, ?config(tcp_port, Config)})
|
||||||
|
).
|
||||||
|
|
||||||
t_current_conns_tcp(_) ->
|
t_current_conns_tcp(Config) ->
|
||||||
?assertEqual(0, emqx_listeners:current_conns('tcp:listener_test', {{127, 0, 0, 1}, 9999})).
|
?assertEqual(
|
||||||
|
0,
|
||||||
|
emqx_listeners:current_conns('tcp:listener_test', {
|
||||||
|
{127, 0, 0, 1}, ?config(tcp_port, Config)
|
||||||
|
})
|
||||||
|
).
|
||||||
|
|
||||||
t_wss_conn(_) ->
|
t_wss_conn(Config) ->
|
||||||
{ok, Socket} = ssl:connect({127, 0, 0, 1}, 9998, [{verify, verify_none}], 1000),
|
{ok, Socket} = ssl:connect(
|
||||||
|
{127, 0, 0, 1}, ?config(wss_port, Config), [{verify, verify_none}], 1000
|
||||||
|
),
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_quic_conn(Config) ->
|
t_quic_conn(Config) ->
|
||||||
Port = 24568,
|
Port = emqx_common_test_helpers:select_free_port(quic),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
SSLOpts = #{
|
SSLOpts = #{
|
||||||
password => ?SERVER_KEY_PASSWORD,
|
password => ?SERVER_KEY_PASSWORD,
|
||||||
|
@ -207,7 +220,7 @@ t_quic_conn(Config) ->
|
||||||
emqx_listeners:stop_listener(quic, ?FUNCTION_NAME, #{bind => Port}).
|
emqx_listeners:stop_listener(quic, ?FUNCTION_NAME, #{bind => Port}).
|
||||||
|
|
||||||
t_ssl_password_cert(Config) ->
|
t_ssl_password_cert(Config) ->
|
||||||
Port = 24568,
|
Port = emqx_common_test_helpers:select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
SSLOptsPWD = #{
|
SSLOptsPWD = #{
|
||||||
password => ?SERVER_KEY_PASSWORD,
|
password => ?SERVER_KEY_PASSWORD,
|
||||||
|
|
|
@ -2026,18 +2026,7 @@ stop_emqx() ->
|
||||||
%% select a random port picked by OS
|
%% select a random port picked by OS
|
||||||
-spec select_port() -> inet:port_number().
|
-spec select_port() -> inet:port_number().
|
||||||
select_port() ->
|
select_port() ->
|
||||||
{ok, S} = gen_udp:open(0, [{reuseaddr, true}]),
|
emqx_common_test_helpers:select_free_port(quic).
|
||||||
{ok, {_, Port}} = inet:sockname(S),
|
|
||||||
gen_udp:close(S),
|
|
||||||
case os:type() of
|
|
||||||
{unix, darwin} ->
|
|
||||||
%% in MacOS, still get address_in_use after close port
|
|
||||||
timer:sleep(500);
|
|
||||||
_ ->
|
|
||||||
skip
|
|
||||||
end,
|
|
||||||
ct:pal("select port: ~p", [Port]),
|
|
||||||
Port.
|
|
||||||
|
|
||||||
-spec via_stream({quic, quicer:connection_handle(), quicer:stream_handle()}) ->
|
-spec via_stream({quic, quicer:connection_handle(), quicer:stream_handle()}) ->
|
||||||
quicer:stream_handle().
|
quicer:stream_handle().
|
||||||
|
|
Loading…
Reference in New Issue