diff --git a/.tool-versions b/.tool-versions index a988325fa..824207a4a 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -erlang 25.3.2-2 -elixir 1.14.5-otp-25 +erlang 26.1.2-1 +elixir 1.15.7-otp-26 diff --git a/apps/emqx/integration_test/emqx_persistent_session_ds_SUITE.erl b/apps/emqx/integration_test/emqx_persistent_session_ds_SUITE.erl index 05c1eb8f2..6f064940e 100644 --- a/apps/emqx/integration_test/emqx_persistent_session_ds_SUITE.erl +++ b/apps/emqx/integration_test/emqx_persistent_session_ds_SUITE.erl @@ -40,7 +40,7 @@ init_per_testcase(TestCase, Config) when Cluster = cluster(#{n => 1}), ClusterOpts = #{work_dir => emqx_cth_suite:work_dir(TestCase, Config)}, NodeSpecs = emqx_cth_cluster:mk_nodespecs(Cluster, ClusterOpts), - Nodes = emqx_cth_cluster:start(Cluster, ClusterOpts), + Nodes = emqx_cth_cluster:start(NodeSpecs), [ {cluster, Cluster}, {node_specs, NodeSpecs}, @@ -116,27 +116,8 @@ start_client(Opts0 = #{}) -> restart_node(Node, NodeSpec) -> ?tp(will_restart_node, #{}), - ?tp(notice, "restarting node", #{node => Node}), - true = monitor_node(Node, true), - ok = erpc:call(Node, init, restart, []), - receive - {nodedown, Node} -> - ok - after 10_000 -> - ct:fail("node ~p didn't stop", [Node]) - end, - ?tp(notice, "waiting for nodeup", #{node => Node}), + emqx_cth_cluster:restart(Node, NodeSpec), wait_nodeup(Node), - wait_gen_rpc_down(NodeSpec), - ?tp(notice, "restarting apps", #{node => Node}), - Apps = maps:get(apps, NodeSpec), - ok = erpc:call(Node, emqx_cth_suite, load_apps, [Apps]), - _ = erpc:call(Node, emqx_cth_suite, start_apps, [Apps, NodeSpec]), - %% have to re-inject this so that we may stop the node succesfully at the - %% end.... - ok = emqx_cth_cluster:set_node_opts(Node, NodeSpec), - ok = snabbkaffe:forward_trace(Node), - ?tp(notice, "node restarted", #{node => Node}), ?tp(restarted_node, #{}), ok. diff --git a/apps/emqx/rebar.config b/apps/emqx/rebar.config index 296d567ee..d4d3332f7 100644 --- a/apps/emqx/rebar.config +++ b/apps/emqx/rebar.config @@ -27,9 +27,9 @@ {lc, {git, "https://github.com/emqx/lc.git", {tag, "0.3.2"}}}, {gproc, {git, "https://github.com/emqx/gproc", {tag, "0.9.0.1"}}}, {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.2"}}}, - {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.7"}}}, + {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.8"}}}, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.15.16"}}}, - {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.2.1"}}}, + {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.2.2"}}}, {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.40.0"}}}, {emqx_http_lib, {git, "https://github.com/emqx/emqx_http_lib.git", {tag, "0.5.3"}}}, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}, diff --git a/apps/emqx/src/emqx_vm.erl b/apps/emqx/src/emqx_vm.erl index 79ad9905c..894595f72 100644 --- a/apps/emqx/src/emqx_vm.erl +++ b/apps/emqx/src/emqx_vm.erl @@ -418,6 +418,9 @@ get_otp_version() -> end. read_otp_version() -> + string:trim(do_read_otp_version()). + +do_read_otp_version() -> ReleasesDir = filename:join([code:root_dir(), "releases"]), Filename = filename:join([ReleasesDir, emqx_app:get_release(), "BUILD_INFO"]), case file:read_file(Filename) of diff --git a/apps/emqx/test/emqx_common_test_helpers.erl b/apps/emqx/test/emqx_common_test_helpers.erl index 4671851f8..18919103c 100644 --- a/apps/emqx/test/emqx_common_test_helpers.erl +++ b/apps/emqx/test/emqx_common_test_helpers.erl @@ -753,24 +753,15 @@ start_slave(Name, Opts) when is_map(Opts) -> case SlaveMod of ct_slave -> ct:pal("~p: node data dir: ~s", [Node, NodeDataDir]), - ct_slave:start( - Node, - [ - {kill_if_fail, true}, - {monitor_master, true}, - {init_timeout, 20_000}, - {startup_timeout, 20_000}, - {erl_flags, erl_flags()}, - {env, [ - {"HOCON_ENV_OVERRIDE_PREFIX", "EMQX_"}, - {"EMQX_NODE__COOKIE", Cookie}, - {"EMQX_NODE__DATA_DIR", NodeDataDir} - ]} - ] - ); + Envs = [ + {"HOCON_ENV_OVERRIDE_PREFIX", "EMQX_"}, + {"EMQX_NODE__COOKIE", Cookie}, + {"EMQX_NODE__DATA_DIR", NodeDataDir} + ], + emqx_cth_peer:start(Node, erl_flags(), Envs); slave -> - Env = " -env HOCON_ENV_OVERRIDE_PREFIX EMQX_", - slave:start_link(host(), Name, ebin_path() ++ Env) + Envs = [{"HOCON_ENV_OVERRIDE_PREFIX", "EMQX_"}], + emqx_cth_peer:start(Node, ebin_path(), Envs) end end, case DoStart() of @@ -789,13 +780,7 @@ start_slave(Name, Opts) when is_map(Opts) -> %% Node stopping stop_slave(Node0) -> Node = node_name(Node0), - SlaveMod = get_peer_mod(Node), - erase_peer_mod(Node), - case SlaveMod:stop(Node) of - ok -> ok; - {ok, _} -> ok; - {error, not_started, _} -> ok - end. + emqx_cth_peer:stop(Node). %% EPMD starting start_epmd() -> @@ -1022,11 +1007,11 @@ set_envs(Node, Env) -> ). erl_flags() -> - %% One core and redirecting logs to master - "+S 1:1 -master " ++ atom_to_list(node()) ++ " " ++ ebin_path(). + %% One core + ["+S", "1:1"] ++ ebin_path(). ebin_path() -> - string:join(["-pa" | lists:filter(fun is_lib/1, code:get_path())], " "). + ["-pa" | lists:filter(fun is_lib/1, code:get_path())]. is_lib(Path) -> string:prefix(Path, code:lib_dir()) =:= nomatch andalso diff --git a/apps/emqx/test/emqx_cth_cluster.erl b/apps/emqx/test/emqx_cth_cluster.erl index b41586518..029907f57 100644 --- a/apps/emqx/test/emqx_cth_cluster.erl +++ b/apps/emqx/test/emqx_cth_cluster.erl @@ -38,14 +38,14 @@ %% in `end_per_suite/1` or `end_per_group/2`) with the result from step 2. -module(emqx_cth_cluster). --export([start/2]). +-export([start/1, start/2, restart/2]). -export([stop/1, stop_node/1]). --export([start_bare_node/2]). +-export([start_bare_nodes/1, start_bare_nodes/2]). -export([share_load_module/2]). -export([node_name/1, mk_nodespecs/2]). --export([start_apps/2, set_node_opts/2]). +-export([start_apps/2]). -define(APPS_CLUSTERING, [gen_rpc, mria, ekka]). @@ -109,9 +109,12 @@ when }. start(Nodes, ClusterOpts) -> NodeSpecs = mk_nodespecs(Nodes, ClusterOpts), - ct:pal("Starting cluster:\n ~p", [NodeSpecs]), + start(NodeSpecs). + +start(NodeSpecs) -> + ct:pal("(Re)starting nodes:\n ~p", [NodeSpecs]), % 1. Start bare nodes with only basic applications running - _ = emqx_utils:pmap(fun start_node_init/1, NodeSpecs, ?TIMEOUT_NODE_START_MS), + ok = start_nodes_init(NodeSpecs, ?TIMEOUT_NODE_START_MS), % 2. Start applications needed to enable clustering % Generally, this causes some applications to restart, but we deliberately don't % start them yet. @@ -121,6 +124,11 @@ start(Nodes, ClusterOpts) -> _ = emqx_utils:pmap(fun run_node_phase_apps/1, NodeSpecs, ?TIMEOUT_APPS_START_MS), [Node || #{name := Node} <- NodeSpecs]. +restart(Node, Spec) -> + ct:pal("Stopping peer node ~p", [Node]), + ok = emqx_cth_peer:stop(Node), + start([Spec#{boot_type => restart}]). + mk_nodespecs(Nodes, ClusterOpts) -> NodeSpecs = lists:zipwith( fun(N, {Name, Opts}) -> mk_init_nodespec(N, Name, Opts, ClusterOpts) end, @@ -282,8 +290,50 @@ allocate_listener_port(Type, #{base_port := BasePort}) -> allocate_listener_ports(Types, Spec) -> lists:foldl(fun maps:merge/2, #{}, [allocate_listener_port(Type, Spec) || Type <- Types]). -start_node_init(Spec = #{name := Node}) -> - Node = start_bare_node(Node, Spec), +start_nodes_init(Specs, Timeout) -> + Names = lists:map(fun(#{name := Name}) -> Name end, Specs), + Nodes = start_bare_nodes(Names, Timeout), + lists:foreach(fun node_init/1, Nodes). + +start_bare_nodes(Names) -> + start_bare_nodes(Names, ?TIMEOUT_NODE_START_MS). +start_bare_nodes(Names, Timeout) -> + Args = erl_flags(), + Envs = [], + Waits = lists:map( + fun(Name) -> + WaitTag = {boot_complete, Name}, + WaitBoot = {self(), WaitTag}, + {ok, _} = emqx_cth_peer:start(Name, Args, Envs, WaitBoot), + WaitTag + end, + Names + ), + Deadline = erlang:monotonic_time() + erlang:convert_time_unit(Timeout, millisecond, nanosecond), + Nodes = wait_boot_complete(Waits, Deadline), + lists:foreach(fun(Node) -> pong = net_adm:ping(Node) end, Nodes), + Nodes. + +wait_boot_complete([], _) -> + []; +wait_boot_complete(Waits, Deadline) -> + case erlang:monotonic_time() > Deadline of + true -> + error({timeout, Waits}); + false -> + ok + end, + receive + {{boot_complete, _Name} = Wait, {started, Node, _Pid}} -> + ct:pal("~p", [Wait]), + [Node | wait_boot_complete(Waits -- [Wait], Deadline)]; + {{boot_complete, _Name}, Otherwise} -> + error({unexpected, Otherwise}) + after 100 -> + wait_boot_complete(Waits, Deadline) + end. + +node_init(Node) -> % Make it possible to call `ct:pal` and friends (if running under rebar3) _ = share_load_module(Node, cthr), % Enable snabbkaffe trace forwarding @@ -300,12 +350,6 @@ run_node_phase_apps(Spec = #{name := Node}) -> ok = start_apps(Node, Spec), ok. -set_node_opts(Node, Spec) -> - erpc:call(Node, persistent_term, put, [{?MODULE, opts}, Spec]). - -get_node_opts(Node) -> - erpc:call(Node, persistent_term, get, [{?MODULE, opts}]). - load_apps(Node, #{apps := Apps}) -> erpc:call(Node, emqx_cth_suite, load_apps, [Apps]). @@ -322,8 +366,12 @@ start_apps(Node, #{apps := Apps} = Spec) -> ok. suite_opts(Spec) -> - maps:with([work_dir], Spec). + maps:with([work_dir, boot_type], Spec). +maybe_join_cluster(_Node, #{boot_type := restart}) -> + %% when restart, the node should already be in the cluster + %% hence no need to (re)join + ok; maybe_join_cluster(_Node, #{role := replicant}) -> ok; maybe_join_cluster(Node, Spec) -> @@ -352,23 +400,7 @@ stop(Nodes) -> stop_node(Name) -> Node = node_name(Name), - try get_node_opts(Node) of - Opts -> - stop_node(Name, Opts) - catch - error:{erpc, _} -> - ok - end. - -stop_node(Node, #{driver := ct_slave}) -> - case ct_slave:stop(Node, [{stop_timeout, ?TIMEOUT_NODE_STOP_S}]) of - {ok, _} -> - ok; - {error, Reason, _} when Reason == not_connected; Reason == not_started -> - ok - end; -stop_node(Node, #{driver := slave}) -> - slave:stop(Node). + ok = emqx_cth_peer:stop(Node). %% Ports @@ -391,36 +423,12 @@ listener_port(BasePort, wss) -> %% --spec start_bare_node(atom(), map()) -> node(). -start_bare_node(Name, Spec = #{driver := ct_slave}) -> - {ok, Node} = ct_slave:start( - node_name(Name), - [ - {kill_if_fail, true}, - {monitor_master, true}, - {init_timeout, 20_000}, - {startup_timeout, 20_000}, - {erl_flags, erl_flags()}, - {env, []} - ] - ), - init_bare_node(Node, Spec); -start_bare_node(Name, Spec = #{driver := slave}) -> - {ok, Node} = slave:start_link(host(), Name, ebin_path()), - init_bare_node(Node, Spec). - -init_bare_node(Node, Spec) -> - pong = net_adm:ping(Node), - % Preserve node spec right on the remote node - ok = set_node_opts(Node, Spec), - Node. - erl_flags() -> - %% One core and redirecting logs to master - "+S 1:1 -master " ++ atom_to_list(node()) ++ " " ++ ebin_path(). + %% One core + ["+S", "1:1"] ++ ebin_path(). ebin_path() -> - string:join(["-pa" | lists:filter(fun is_lib/1, code:get_path())], " "). + ["-pa" | lists:filter(fun is_lib/1, code:get_path())]. is_lib(Path) -> string:prefix(Path, code:lib_dir()) =:= nomatch andalso diff --git a/apps/emqx/test/emqx_cth_peer.erl b/apps/emqx/test/emqx_cth_peer.erl new file mode 100644 index 000000000..8b1996cbd --- /dev/null +++ b/apps/emqx/test/emqx_cth_peer.erl @@ -0,0 +1,79 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2023 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +%% @doc Common Test Helper proxy module for slave -> peer migration. +%% OTP 26 has slave module deprecated, use peer instead. + +-module(emqx_cth_peer). + +-export([start/2, start/3, start/4]). +-export([start_link/2, start_link/3, start_link/4]). +-export([stop/1]). + +start(Name, Args) -> + start(Name, Args, []). + +start(Name, Args, Envs) -> + start(Name, Args, Envs, timer:seconds(20)). + +start(Name, Args, Envs, Timeout) when is_atom(Name) -> + do_start(Name, Args, Envs, Timeout, start). + +start_link(Name, Args) -> + start_link(Name, Args, []). + +start_link(Name, Args, Envs) -> + start_link(Name, Args, Envs, timer:seconds(20)). + +start_link(Name, Args, Envs, Timeout) when is_atom(Name) -> + do_start(Name, Args, Envs, Timeout, start_link). + +do_start(Name0, Args, Envs, Timeout, Func) when is_atom(Name0) -> + {Name, Host} = parse_node_name(Name0), + {ok, Pid, Node} = peer:Func(#{ + name => Name, + host => Host, + args => Args, + env => Envs, + wait_boot => Timeout, + longnames => true, + shutdown => {halt, 1000} + }), + true = register(Node, Pid), + {ok, Node}. + +stop(Node) when is_atom(Node) -> + Pid = whereis(Node), + case is_pid(Pid) of + true -> + unlink(Pid), + ok = peer:stop(Pid); + false -> + ct:pal("The control process for node ~p is unexpetedly down", [Node]), + ok + end. + +parse_node_name(NodeName) -> + case string:tokens(atom_to_list(NodeName), "@") of + [Name, Host] -> + {list_to_atom(Name), Host}; + [_] -> + {NodeName, host()} + end. + +host() -> + [_Name, Host] = string:tokens(atom_to_list(node()), "@"), + Host. diff --git a/apps/emqx/test/emqx_cth_suite.erl b/apps/emqx/test/emqx_cth_suite.erl index 401d4f59d..5e91b92c9 100644 --- a/apps/emqx/test/emqx_cth_suite.erl +++ b/apps/emqx/test/emqx_cth_suite.erl @@ -453,6 +453,9 @@ stop_apps(Apps) -> %% +verify_clean_suite_state(#{boot_type := restart}) -> + %% when testing node restart, we do not need to verify clean state + ok; verify_clean_suite_state(#{work_dir := WorkDir}) -> {ok, []} = file:list_dir(WorkDir), false = emqx_schema_hooks:any_injections(), diff --git a/apps/emqx/test/emqx_metrics_worker_SUITE.erl b/apps/emqx/test/emqx_metrics_worker_SUITE.erl index 194c9cc99..784eac18e 100644 --- a/apps/emqx/test/emqx_metrics_worker_SUITE.erl +++ b/apps/emqx/test/emqx_metrics_worker_SUITE.erl @@ -53,9 +53,9 @@ t_get_metrics(_) -> ?assertMatch( #{ rate := #{ - a := #{current := 0.0, max := 0.0, last5m := 0.0}, - b := #{current := 0.0, max := 0.0, last5m := 0.0}, - c := #{current := 0.0, max := 0.0, last5m := 0.0} + a := #{current := +0.0, max := +0.0, last5m := +0.0}, + b := #{current := +0.0, max := +0.0, last5m := +0.0}, + c := #{current := +0.0, max := +0.0, last5m := +0.0} }, gauges := #{}, counters := #{ @@ -118,9 +118,9 @@ t_clear_metrics(_Config) -> ?assertMatch( #{ rate := #{ - a := #{current := 0.0, max := 0.0, last5m := 0.0}, - b := #{current := 0.0, max := 0.0, last5m := 0.0}, - c := #{current := 0.0, max := 0.0, last5m := 0.0} + a := #{current := +0.0, max := +0.0, last5m := +0.0}, + b := #{current := +0.0, max := +0.0, last5m := +0.0}, + c := #{current := +0.0, max := +0.0, last5m := +0.0} }, gauges := #{}, slides := #{}, @@ -145,7 +145,7 @@ t_clear_metrics(_Config) -> #{ counters => #{}, gauges => #{}, - rate => #{current => 0.0, last5m => 0.0, max => 0.0}, + rate => #{current => +0.0, last5m => +0.0, max => +0.0}, slides => #{} }, emqx_metrics_worker:get_metrics(?NAME, Id) @@ -160,9 +160,9 @@ t_reset_metrics(_) -> ?assertMatch( #{ rate := #{ - a := #{current := 0.0, max := 0.0, last5m := 0.0}, - b := #{current := 0.0, max := 0.0, last5m := 0.0}, - c := #{current := 0.0, max := 0.0, last5m := 0.0} + a := #{current := +0.0, max := +0.0, last5m := +0.0}, + b := #{current := +0.0, max := +0.0, last5m := +0.0}, + c := #{current := +0.0, max := +0.0, last5m := +0.0} }, gauges := #{}, counters := #{ diff --git a/apps/emqx/test/emqx_mountpoint_SUITE.erl b/apps/emqx/test/emqx_mountpoint_SUITE.erl index 0bfde981c..1d9539409 100644 --- a/apps/emqx/test/emqx_mountpoint_SUITE.erl +++ b/apps/emqx/test/emqx_mountpoint_SUITE.erl @@ -58,9 +58,6 @@ t_mount_share(_) -> TopicFilters = [T], ?assertEqual(TopicFilter, #share{group = <<"group">>, topic = <<"topic">>}), - %% should not mount share topic when make message. - Msg = emqx_message:make(<<"clientid">>, TopicFilter, <<"payload">>), - ?assertEqual( TopicFilter, mount(undefined, TopicFilter) @@ -89,8 +86,6 @@ t_unmount_share(_) -> ?assertEqual(TopicFilter, #share{group = <<"group">>, topic = <<"topic">>}), - %% should not unmount share topic when make message. - Msg = emqx_message:make(<<"clientid">>, TopicFilter, <<"payload">>), ?assertEqual( TopicFilter, unmount(undefined, TopicFilter) diff --git a/apps/emqx/test/emqx_router_helper_SUITE.erl b/apps/emqx/test/emqx_router_helper_SUITE.erl index 8fe052af8..c16277884 100644 --- a/apps/emqx/test/emqx_router_helper_SUITE.erl +++ b/apps/emqx/test/emqx_router_helper_SUITE.erl @@ -80,7 +80,7 @@ t_mnesia(_) -> ct:sleep(200). t_cleanup_membership_mnesia_down(_Config) -> - Slave = emqx_cth_cluster:node_name(?FUNCTION_NAME), + Slave = emqx_cth_cluster:node_name(node2), emqx_router:add_route(<<"a/b/c">>, Slave), emqx_router:add_route(<<"d/e/f">>, node()), ?assertMatch([_, _], emqx_router:topics()), @@ -92,7 +92,7 @@ t_cleanup_membership_mnesia_down(_Config) -> ?assertEqual([<<"d/e/f">>], emqx_router:topics()). t_cleanup_membership_node_down(_Config) -> - Slave = emqx_cth_cluster:node_name(?FUNCTION_NAME), + Slave = emqx_cth_cluster:node_name(node3), emqx_router:add_route(<<"a/b/c">>, Slave), emqx_router:add_route(<<"d/e/f">>, node()), ?assertMatch([_, _], emqx_router:topics()), @@ -104,7 +104,7 @@ t_cleanup_membership_node_down(_Config) -> ?assertEqual([<<"d/e/f">>], emqx_router:topics()). t_cleanup_monitor_node_down(_Config) -> - Slave = emqx_cth_cluster:start_bare_node(?FUNCTION_NAME, #{driver => ct_slave}), + [Slave] = emqx_cth_cluster:start_bare_nodes([node4]), emqx_router:add_route(<<"a/b/c">>, Slave), emqx_router:add_route(<<"d/e/f">>, node()), ?assertMatch([_, _], emqx_router:topics()), diff --git a/apps/emqx/test/emqx_routing_SUITE.erl b/apps/emqx/test/emqx_routing_SUITE.erl index a54e1b4dd..c9ad63cf1 100644 --- a/apps/emqx/test/emqx_routing_SUITE.erl +++ b/apps/emqx/test/emqx_routing_SUITE.erl @@ -218,38 +218,41 @@ t_routing_schema_switch(VFrom, VTo, Config) -> ], #{work_dir => WorkDir} ), - % Verify that new nodes switched to schema v1/v2 in presence of v1/v2 routes respectively Nodes = [Node1, Node2, Node3], - ?assertEqual( - [{ok, VTo}, {ok, VTo}, {ok, VTo}], - erpc:multicall(Nodes, emqx_router, get_schema_vsn, []) - ), - % Wait for all nodes to agree on cluster state - ?retry( - 500, - 10, - ?assertMatch( - [{ok, [Node1, Node2, Node3]}], - lists:usort(erpc:multicall(Nodes, emqx, running_nodes, [])) - ) - ), - % Verify that routing works as expected - C2 = start_client(Node2), - ok = subscribe(C2, <<"a/+/d">>), - C3 = start_client(Node3), - ok = subscribe(C3, <<"d/e/f/#">>), - {ok, _} = publish(C1, <<"a/b/d">>, <<"hey-newbies">>), - {ok, _} = publish(C2, <<"a/b/c">>, <<"hi">>), - {ok, _} = publish(C3, <<"d/e/f/42">>, <<"hello">>), - ?assertReceive({pub, C2, #{topic := <<"a/b/d">>, payload := <<"hey-newbies">>}}), - ?assertReceive({pub, C1, #{topic := <<"a/b/c">>, payload := <<"hi">>}}), - ?assertReceive({pub, C1, #{topic := <<"d/e/f/42">>, payload := <<"hello">>}}), - ?assertReceive({pub, C3, #{topic := <<"d/e/f/42">>, payload := <<"hello">>}}), - ?assertNotReceive(_), - ok = emqtt:stop(C1), - ok = emqtt:stop(C2), - ok = emqtt:stop(C3), - ok = emqx_cth_cluster:stop(Nodes). + try + % Verify that new nodes switched to schema v1/v2 in presence of v1/v2 routes respectively + ?assertEqual( + [{ok, VTo}, {ok, VTo}, {ok, VTo}], + erpc:multicall(Nodes, emqx_router, get_schema_vsn, []) + ), + % Wait for all nodes to agree on cluster state + ?retry( + 500, + 10, + ?assertMatch( + [{ok, [Node1, Node2, Node3]}], + lists:usort(erpc:multicall(Nodes, emqx, running_nodes, [])) + ) + ), + % Verify that routing works as expected + C2 = start_client(Node2), + ok = subscribe(C2, <<"a/+/d">>), + C3 = start_client(Node3), + ok = subscribe(C3, <<"d/e/f/#">>), + {ok, _} = publish(C1, <<"a/b/d">>, <<"hey-newbies">>), + {ok, _} = publish(C2, <<"a/b/c">>, <<"hi">>), + {ok, _} = publish(C3, <<"d/e/f/42">>, <<"hello">>), + ?assertReceive({pub, C2, #{topic := <<"a/b/d">>, payload := <<"hey-newbies">>}}), + ?assertReceive({pub, C1, #{topic := <<"a/b/c">>, payload := <<"hi">>}}), + ?assertReceive({pub, C1, #{topic := <<"d/e/f/42">>, payload := <<"hello">>}}), + ?assertReceive({pub, C3, #{topic := <<"d/e/f/42">>, payload := <<"hello">>}}), + ?assertNotReceive(_), + ok = emqtt:stop(C1), + ok = emqtt:stop(C2), + ok = emqtt:stop(C3) + after + ok = emqx_cth_cluster:stop(Nodes) + end. %% diff --git a/apps/emqx/test/emqx_shared_sub_SUITE.erl b/apps/emqx/test/emqx_shared_sub_SUITE.erl index 86887eff0..cc6908fb6 100644 --- a/apps/emqx/test/emqx_shared_sub_SUITE.erl +++ b/apps/emqx/test/emqx_shared_sub_SUITE.erl @@ -63,6 +63,7 @@ init_per_suite(Config) -> end, emqx_common_test_helpers:boot_modules(all), emqx_common_test_helpers:start_apps([]), + emqx_logger:set_log_level(debug), [{dist_pid, DistPid} | Config]. end_per_suite(Config) -> @@ -574,7 +575,7 @@ t_local(Config) when is_list(Config) -> <<"sticky_group">> => sticky }, - Node = start_slave('local_shared_sub_testtesttest', 21999), + Node = start_slave('local_shared_sub_local_1', 21999), ok = ensure_group_config(GroupConfig), ok = ensure_group_config(Node, GroupConfig), @@ -627,7 +628,7 @@ t_remote(Config) when is_list(Config) -> <<"sticky_group">> => sticky }, - Node = start_slave('remote_shared_sub_testtesttest', 21999), + Node = start_slave('remote_shared_sub_remote_1', 21999), ok = ensure_group_config(GroupConfig), ok = ensure_group_config(Node, GroupConfig), @@ -676,7 +677,7 @@ t_local_fallback(Config) when is_list(Config) -> Topic = <<"local_foo/bar">>, ClientId1 = <<"ClientId1">>, ClientId2 = <<"ClientId2">>, - Node = start_slave('local_fallback_shared_sub_test', 11888), + Node = start_slave('local_fallback_shared_sub_1', 11888), {ok, ConnPid1} = emqtt:start_link([{clientid, ClientId1}]), {ok, _} = emqtt:connect(ConnPid1), @@ -1253,34 +1254,24 @@ recv_msgs(Count, Msgs) -> end. start_slave(Name, Port) -> - {ok, Node} = ct_slave:start( - list_to_atom(atom_to_list(Name) ++ "@" ++ host()), - [ - {kill_if_fail, true}, - {monitor_master, true}, - {init_timeout, 10000}, - {startup_timeout, 10000}, - {erl_flags, ebin_path()} - ] + {ok, Node} = emqx_cth_peer:start_link( + Name, + ebin_path() ), - pong = net_adm:ping(Node), setup_node(Node, Port), Node. stop_slave(Node) -> rpc:call(Node, mria, leave, []), - ct_slave:stop(Node). + emqx_cth_peer:stop(Node). host() -> [_, Host] = string:tokens(atom_to_list(node()), "@"), Host. ebin_path() -> - string:join(["-pa" | lists:filter(fun is_lib/1, code:get_path())], " "). - -is_lib(Path) -> - string:prefix(Path, code:lib_dir()) =:= nomatch. + ["-pa" | code:get_path()]. setup_node(Node, Port) -> EnvHandler = diff --git a/apps/emqx_bridge/test/emqx_bridge_compatible_config_tests.erl b/apps/emqx_bridge/test/emqx_bridge_compatible_config_tests.erl index 540c18878..86cc1f5c6 100644 --- a/apps/emqx_bridge/test/emqx_bridge_compatible_config_tests.erl +++ b/apps/emqx_bridge/test/emqx_bridge_compatible_config_tests.erl @@ -126,7 +126,7 @@ check(Conf) when is_map(Conf) -> %% erlfmt-ignore %% this is config generated from v5.0.11 webhook_v5011_hocon() -> -""" +" bridges{ webhook { the_name{ @@ -143,7 +143,7 @@ bridges{ } } } -""". +". full_webhook_v5011_hocon() -> "" @@ -215,7 +215,7 @@ full_webhook_v5019_hocon() -> %% erlfmt-ignore %% this is a generated from v5.0.11 mqtt_v5011_hocon() -> -""" +" bridges { mqtt { bridge_one { @@ -257,12 +257,12 @@ bridges { } } } -""". +". %% erlfmt-ignore %% a more complete version mqtt_v5011_full_hocon() -> -""" +" bridges { mqtt { bridge_one { @@ -330,4 +330,4 @@ bridges { } } } -""". +". diff --git a/apps/emqx_bridge_azure_event_hub/rebar.config b/apps/emqx_bridge_azure_event_hub/rebar.config index efe337029..90be538b3 100644 --- a/apps/emqx_bridge_azure_event_hub/rebar.config +++ b/apps/emqx_bridge_azure_event_hub/rebar.config @@ -2,7 +2,7 @@ {erl_opts, [debug_info]}. {deps, [ {wolff, {git, "https://github.com/kafka4beam/wolff.git", {tag, "1.8.0"}}} , {kafka_protocol, {git, "https://github.com/kafka4beam/kafka_protocol.git", {tag, "4.1.3"}}} - , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.0"}}} + , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.1"}}} , {brod, {git, "https://github.com/kafka4beam/brod.git", {tag, "3.16.8"}}} , {snappyer, "1.2.9"} , {emqx_connector, {path, "../../apps/emqx_connector"}} diff --git a/apps/emqx_bridge_azure_event_hub/test/emqx_bridge_azure_event_hub_tests.erl b/apps/emqx_bridge_azure_event_hub/test/emqx_bridge_azure_event_hub_tests.erl index 92d268d20..1b135d0f7 100644 --- a/apps/emqx_bridge_azure_event_hub/test/emqx_bridge_azure_event_hub_tests.erl +++ b/apps/emqx_bridge_azure_event_hub/test/emqx_bridge_azure_event_hub_tests.erl @@ -12,7 +12,7 @@ %% erlfmt-ignore aeh_producer_hocon() -> -""" +" bridges.azure_event_hub_producer.my_producer { enable = true authentication { @@ -62,7 +62,7 @@ bridges.azure_event_hub_producer.my_producer { server_name_indication = auto } } -""". +". %%=========================================================================== %% Helper functions diff --git a/apps/emqx_bridge_confluent/rebar.config b/apps/emqx_bridge_confluent/rebar.config index 38173e74c..0c0c2eece 100644 --- a/apps/emqx_bridge_confluent/rebar.config +++ b/apps/emqx_bridge_confluent/rebar.config @@ -2,7 +2,7 @@ {erl_opts, [debug_info]}. {deps, [ {wolff, {git, "https://github.com/kafka4beam/wolff.git", {tag, "1.8.0"}}} , {kafka_protocol, {git, "https://github.com/kafka4beam/kafka_protocol.git", {tag, "4.1.3"}}} - , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.0"}}} + , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.1"}}} , {brod, {git, "https://github.com/kafka4beam/brod.git", {tag, "3.16.8"}}} , {snappyer, "1.2.9"} , {emqx_connector, {path, "../../apps/emqx_connector"}} diff --git a/apps/emqx_bridge_confluent/test/emqx_bridge_confluent_tests.erl b/apps/emqx_bridge_confluent/test/emqx_bridge_confluent_tests.erl index 16e6e11fe..a7efebf89 100644 --- a/apps/emqx_bridge_confluent/test/emqx_bridge_confluent_tests.erl +++ b/apps/emqx_bridge_confluent/test/emqx_bridge_confluent_tests.erl @@ -12,7 +12,7 @@ %% erlfmt-ignore confluent_producer_action_hocon() -> -""" +" actions.confluent_producer.my_producer { enable = true connector = my_connector @@ -40,7 +40,7 @@ actions.confluent_producer.my_producer { } local_topic = \"t/confluent\" } -""". +". confluent_producer_connector_hocon() -> "" diff --git a/apps/emqx_bridge_gcp_pubsub/test/emqx_bridge_gcp_pubsub_tests.erl b/apps/emqx_bridge_gcp_pubsub/test/emqx_bridge_gcp_pubsub_tests.erl index 885754470..de7467f62 100644 --- a/apps/emqx_bridge_gcp_pubsub/test/emqx_bridge_gcp_pubsub_tests.erl +++ b/apps/emqx_bridge_gcp_pubsub/test/emqx_bridge_gcp_pubsub_tests.erl @@ -12,7 +12,7 @@ %% erlfmt-ignore gcp_pubsub_producer_hocon() -> -""" +" bridges.gcp_pubsub.my_producer { attributes_template = [ {key = \"${payload.key}\", value = fixed_value} @@ -54,7 +54,7 @@ bridges.gcp_pubsub.my_producer { type = service_account } } -""". +". %%=========================================================================== %% Helper functions diff --git a/apps/emqx_bridge_http/test/emqx_bridge_http_connector_tests.erl b/apps/emqx_bridge_http/test/emqx_bridge_http_connector_tests.erl index 4f5e2929c..f2de91123 100644 --- a/apps/emqx_bridge_http/test/emqx_bridge_http_connector_tests.erl +++ b/apps/emqx_bridge_http/test/emqx_bridge_http_connector_tests.erl @@ -175,7 +175,7 @@ check_atom_key(Conf) when is_map(Conf) -> %% erlfmt-ignore webhook_config_hocon() -> -""" +" bridges.webhook.a { body = \"${.}\" connect_timeout = 15s @@ -209,4 +209,4 @@ bridges.webhook.a { } url = \"http://some.host:4000/api/echo\" } -""". +". diff --git a/apps/emqx_bridge_kafka/rebar.config b/apps/emqx_bridge_kafka/rebar.config index 92e83fa04..b69ec1262 100644 --- a/apps/emqx_bridge_kafka/rebar.config +++ b/apps/emqx_bridge_kafka/rebar.config @@ -2,7 +2,7 @@ {erl_opts, [debug_info]}. {deps, [ {wolff, {git, "https://github.com/kafka4beam/wolff.git", {tag, "1.8.0"}}} , {kafka_protocol, {git, "https://github.com/kafka4beam/kafka_protocol.git", {tag, "4.1.3"}}} - , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.0"}}} + , {brod_gssapi, {git, "https://github.com/kafka4beam/brod_gssapi.git", {tag, "v0.1.1"}}} , {brod, {git, "https://github.com/kafka4beam/brod.git", {tag, "3.16.8"}}} , {snappyer, "1.2.9"} , {emqx_connector, {path, "../../apps/emqx_connector"}} diff --git a/apps/emqx_bridge_pulsar/test/emqx_bridge_pulsar_tests.erl b/apps/emqx_bridge_pulsar/test/emqx_bridge_pulsar_tests.erl index 5492bb2a8..5b9c33fbb 100644 --- a/apps/emqx_bridge_pulsar/test/emqx_bridge_pulsar_tests.erl +++ b/apps/emqx_bridge_pulsar/test/emqx_bridge_pulsar_tests.erl @@ -73,7 +73,7 @@ check_atom_key(Conf) when is_map(Conf) -> %% erlfmt-ignore pulsar_producer_hocon() -> -""" +" bridges.pulsar_producer.my_producer { enable = true servers = \"localhost:6650\" @@ -90,4 +90,4 @@ bridges.pulsar_producer.my_producer { server_name_indication = \"auto\" } } -""". +". diff --git a/apps/emqx_conf/test/emqx_conf_logger_SUITE.erl b/apps/emqx_conf/test/emqx_conf_logger_SUITE.erl index 096136651..2cb699036 100644 --- a/apps/emqx_conf/test/emqx_conf_logger_SUITE.erl +++ b/apps/emqx_conf/test/emqx_conf_logger_SUITE.erl @@ -24,7 +24,7 @@ %% erlfmt-ignore -define(BASE_CONF, - """ + " log { console { enable = true @@ -36,7 +36,7 @@ path = \"log/emqx.log\" } } - """). + "). all() -> emqx_common_test_helpers:all(?MODULE). diff --git a/apps/emqx_conf/test/emqx_conf_schema_tests.erl b/apps/emqx_conf/test/emqx_conf_schema_tests.erl index 4fca88a00..22f8c5575 100644 --- a/apps/emqx_conf/test/emqx_conf_schema_tests.erl +++ b/apps/emqx_conf/test/emqx_conf_schema_tests.erl @@ -20,7 +20,7 @@ %% erlfmt-ignore -define(BASE_CONF, - """ + " node { name = \"emqx1@127.0.0.1\" cookie = \"emqxsecretcookie\" @@ -34,7 +34,7 @@ static.seeds = ~p core_nodes = ~p } - """). + "). array_nodes_test() -> ensure_acl_conf(), @@ -70,7 +70,7 @@ array_nodes_test() -> %% erlfmt-ignore -define(OUTDATED_LOG_CONF, - """ + " log.console_handler { burst_limit { enable = true @@ -124,7 +124,7 @@ log.file_handlers { time_offset = \"+01:00\" } } - """ + " ). -define(FORMATTER(TimeOffset), {emqx_logger_textfmt, #{ @@ -196,7 +196,7 @@ validate_log(Conf) -> %% erlfmt-ignore -define(FILE_LOG_BASE_CONF, - """ + " log.file.default { enable = true file = \"log/xx-emqx.log\" @@ -206,7 +206,7 @@ validate_log(Conf) -> rotation_size = ~s time_offset = \"+01:00\" } - """ + " ). file_log_infinity_rotation_size_test_() -> @@ -249,7 +249,7 @@ file_log_infinity_rotation_size_test_() -> %% erlfmt-ignore -define(KERNEL_LOG_CONF, - """ + " log.console { enable = true formatter = text @@ -269,7 +269,7 @@ file_log_infinity_rotation_size_test_() -> enable = true file = \"log/my-emqx.log\" } - """ + " ). log_test() -> @@ -279,7 +279,7 @@ log_test() -> log_rotation_count_limit_test() -> ensure_acl_conf(), Format = - """ + " log.file { enable = true path = \"log/emqx.log\" @@ -288,7 +288,7 @@ log_rotation_count_limit_test() -> rotation = {count = ~w} rotation_size = \"1024MB\" } - """, + ", BaseConf = to_bin(?BASE_CONF, ["emqx1@127.0.0.1", "emqx1@127.0.0.1"]), lists:foreach(fun({Conf, Count}) -> Conf0 = <>, @@ -320,7 +320,7 @@ log_rotation_count_limit_test() -> %% erlfmt-ignore -define(BASE_AUTHN_ARRAY, - """ + " authentication = [ {backend = \"http\" body {password = \"${password}\", username = \"${username}\"} @@ -335,7 +335,7 @@ log_rotation_count_limit_test() -> url = \"~ts\" } ] - """ + " ). -define(ERROR(Error), @@ -396,13 +396,13 @@ authn_validations_test() -> %% erlfmt-ignore -define(LISTENERS, - """ + " listeners.ssl.default.bind = 9999 listeners.wss.default.bind = 9998 listeners.wss.default.ssl_options.cacertfile = \"mytest/certs/cacert.pem\" listeners.wss.new.bind = 9997 listeners.wss.new.websocket.mqtt_path = \"/my-mqtt\" - """ + " ). listeners_test() -> diff --git a/apps/emqx_management/src/emqx_mgmt_api_configs.erl b/apps/emqx_management/src/emqx_mgmt_api_configs.erl index d5879be36..d08bb9882 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_configs.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_configs.erl @@ -57,7 +57,7 @@ %% erlfmt-ignore -define(SYSMON_EXAMPLE, - <<""" + <<" sysmon { os { cpu_check_interval = 60s @@ -78,7 +78,7 @@ process_low_watermark = 60% } } - """>> + ">> ). api_spec() -> diff --git a/apps/emqx_management/src/emqx_mgmt_api_plugins.erl b/apps/emqx_management/src/emqx_mgmt_api_plugins.erl index c89ee202e..81a1103d2 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_plugins.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_plugins.erl @@ -399,7 +399,7 @@ do_install_package(FileName, Bin) -> end, {400, #{ code => 'BAD_PLUGIN_INFO', - message => iolist_to_binary([Reason, ":", FileName]) + message => iolist_to_binary([Reason, ": ", FileName]) }} end. @@ -445,7 +445,8 @@ install_package(FileName, Bin) -> case emqx_plugins:ensure_installed(PackageName) of {error, #{return := not_found}} = NotFound -> NotFound; - {error, _Reason} = Error -> + {error, Reason} = Error -> + ?SLOG(error, Reason#{msg => "failed_to_install_plugin"}), _ = file:delete(File), Error; Result -> diff --git a/apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl index f428009cb..32fbfdee5 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl @@ -214,7 +214,22 @@ t_kickout_clients(_) -> {ok, C3} = emqtt:start_link(#{clientid => ClientId3}), {ok, _} = emqtt:connect(C3), - timer:sleep(300), + emqx_common_test_helpers:wait_for( + ?FUNCTION_NAME, + ?LINE, + fun() -> + try + [_] = emqx_cm:lookup_channels(ClientId1), + [_] = emqx_cm:lookup_channels(ClientId2), + [_] = emqx_cm:lookup_channels(ClientId3), + true + catch + error:badmatch -> + false + end + end, + 2000 + ), %% get /clients ClientsPath = emqx_mgmt_api_test_util:api_path(["clients"]), @@ -233,6 +248,15 @@ t_kickout_clients(_) -> KickoutBody = [ClientId1, ClientId2, ClientId3], {ok, 204, _} = emqx_mgmt_api_test_util:request_api_with_body(post, KickoutPath, KickoutBody), + ReceiveExit = fun({ClientPid, ClientId}) -> + receive + {'EXIT', Pid, _} when Pid =:= ClientPid -> + ok + after 1000 -> + error({timeout, ClientId}) + end + end, + lists:foreach(ReceiveExit, [{C1, ClientId1}, {C2, ClientId2}, {C3, ClientId3}]), {ok, Clients2} = emqx_mgmt_api_test_util:request_api(get, ClientsPath), ClientsResponse2 = emqx_utils_json:decode(Clients2, [return_maps]), ?assertMatch(#{<<"meta">> := #{<<"count">> := 0}}, ClientsResponse2). diff --git a/apps/emqx_plugins/src/emqx_plugins.erl b/apps/emqx_plugins/src/emqx_plugins.erl index 41538daf6..f14a1022a 100644 --- a/apps/emqx_plugins/src/emqx_plugins.erl +++ b/apps/emqx_plugins/src/emqx_plugins.erl @@ -83,7 +83,7 @@ describe(NameVsn) -> read_plugin(NameVsn, #{fill_readme => true}). %% @doc Install a .tar.gz package placed in install_dir. --spec ensure_installed(name_vsn()) -> ok | {error, any()}. +-spec ensure_installed(name_vsn()) -> ok | {error, map()}. ensure_installed(NameVsn) -> case read_plugin(NameVsn, #{}) of {ok, _} -> diff --git a/apps/emqx_plugins/test/emqx_plugins_SUITE.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl index 3e9850129..b0a47a6a0 100644 --- a/apps/emqx_plugins/test/emqx_plugins_SUITE.erl +++ b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl @@ -750,7 +750,7 @@ group_t_copy_plugin_to_a_new_node_single_node({init, Config}) -> | Config ]; group_t_copy_plugin_to_a_new_node_single_node({'end', Config}) -> - CopyToNode = proplists:get_value(copy_to_node, Config), + CopyToNode = proplists:get_value(copy_to_node_name, Config), ok = emqx_common_test_helpers:stop_slave(CopyToNode), ok = file:del_dir_r(proplists:get_value(to_install_dir, Config)), ok; diff --git a/apps/emqx_resource/test/emqx_resource_schema_tests.erl b/apps/emqx_resource/test/emqx_resource_schema_tests.erl index 78a761bd2..51575cfe7 100644 --- a/apps/emqx_resource/test/emqx_resource_schema_tests.erl +++ b/apps/emqx_resource/test/emqx_resource_schema_tests.erl @@ -134,7 +134,7 @@ check(Conf) when is_map(Conf) -> %% erlfmt-ignore webhook_bridge_health_check_hocon(HealthCheckInterval) -> io_lib:format( -""" +" bridges.webhook.simple { url = \"http://localhost:4000\" body = \"body\" @@ -142,5 +142,5 @@ bridges.webhook.simple { health_check_interval = \"~s\" } } -""", +", [HealthCheckInterval]). diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_schema_tests.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_schema_tests.erl index e3cff53e9..e361e2ad2 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_schema_tests.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_schema_tests.erl @@ -24,7 +24,7 @@ %% erlfmt-ignore republish_hocon0() -> -""" +" rule_engine.rules.my_rule { description = \"some desc\" metadata = {created_at = 1693918992079} @@ -55,7 +55,7 @@ rule_engine.rules.my_rule { } ] } -""". +". %%=========================================================================== %% Helper functions diff --git a/apps/emqx_telemetry/test/emqx_telemetry_SUITE.erl b/apps/emqx_telemetry/test/emqx_telemetry_SUITE.erl index 07cb18e60..f1da349eb 100644 --- a/apps/emqx_telemetry/test/emqx_telemetry_SUITE.erl +++ b/apps/emqx_telemetry/test/emqx_telemetry_SUITE.erl @@ -869,7 +869,7 @@ stop_slave(Node) -> % This line don't work!! %emqx_cluster_rpc:fast_forward_to_commit(Node, 100), rpc:call(Node, ?MODULE, leave_cluster, []), - ok = slave:stop(Node), + ok = emqx_cth_peer:stop(Node), ?assertEqual([node()], mria:running_nodes()), ?assertEqual([], nodes()), _ = application:stop(mria), diff --git a/mix.exs b/mix.exs index 3fbd4318f..e0aba14cc 100644 --- a/mix.exs +++ b/mix.exs @@ -46,17 +46,17 @@ defmodule EMQXUmbrella.MixProject do # other exact versions, and not ranges. [ {:lc, github: "emqx/lc", tag: "0.3.2", override: true}, - {:redbug, "2.0.8"}, + {:redbug, github: "emqx/redbug", tag: "2.0.10"}, {:covertool, github: "zmstone/covertool", tag: "2.0.4.1", override: true}, {:typerefl, github: "ieQu1/typerefl", tag: "0.9.1", override: true}, {:ehttpc, github: "emqx/ehttpc", tag: "0.4.11", override: true}, {:gproc, github: "emqx/gproc", tag: "0.9.0.1", override: true}, {:jiffy, github: "emqx/jiffy", tag: "1.0.5", override: true}, {:cowboy, github: "emqx/cowboy", tag: "2.9.2", override: true}, - {:esockd, github: "emqx/esockd", tag: "5.9.7", override: true}, + {:esockd, github: "emqx/esockd", tag: "5.9.8", override: true}, {:rocksdb, github: "emqx/erlang-rocksdb", tag: "1.8.0-emqx-1", override: true}, {:ekka, github: "emqx/ekka", tag: "0.15.16", override: true}, - {:gen_rpc, github: "emqx/gen_rpc", tag: "3.2.1", override: true}, + {:gen_rpc, github: "emqx/gen_rpc", tag: "3.2.2", override: true}, {:grpc, github: "emqx/grpc-erl", tag: "0.6.8", override: true}, {:minirest, github: "emqx/minirest", tag: "1.3.14", override: true}, {:ecpool, github: "emqx/ecpool", tag: "0.5.4", override: true}, @@ -230,7 +230,7 @@ defmodule EMQXUmbrella.MixProject do {:influxdb, github: "emqx/influxdb-client-erl", tag: "1.1.11", override: true}, {:wolff, github: "kafka4beam/wolff", tag: "1.8.0"}, {:kafka_protocol, github: "kafka4beam/kafka_protocol", tag: "4.1.3", override: true}, - {:brod_gssapi, github: "kafka4beam/brod_gssapi", tag: "v0.1.0"}, + {:brod_gssapi, github: "kafka4beam/brod_gssapi", tag: "v0.1.1"}, {:brod, github: "kafka4beam/brod", tag: "3.16.8"}, {:snappyer, "1.2.9", override: true}, {:crc32cer, "0.1.8", override: true}, @@ -823,7 +823,7 @@ defmodule EMQXUmbrella.MixProject do defp jq_dep() do if enable_jq?(), - do: [{:jq, github: "emqx/jq", tag: "v0.3.11", override: true}], + do: [{:jq, github: "emqx/jq", tag: "v0.3.12", override: true}], else: [] end diff --git a/rebar.config b/rebar.config index aa11697d4..fb93825f7 100644 --- a/rebar.config +++ b/rebar.config @@ -51,7 +51,7 @@ {deps, [ {lc, {git, "https://github.com/emqx/lc.git", {tag, "0.3.2"}}} - , {redbug, "2.0.8"} + , {redbug, {git, "https://github.com/emqx/redbug", {tag, "2.0.10"}}} , {covertool, {git, "https://github.com/zmstone/covertool", {tag, "2.0.4.1"}}} , {gpb, "4.19.9"} , {typerefl, {git, "https://github.com/ieQu1/typerefl", {tag, "0.9.1"}}} @@ -60,10 +60,10 @@ , {gproc, {git, "https://github.com/emqx/gproc", {tag, "0.9.0.1"}}} , {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}} , {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.2"}}} - , {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.7"}}} + , {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.8"}}} , {rocksdb, {git, "https://github.com/emqx/erlang-rocksdb", {tag, "1.8.0-emqx-1"}}} , {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.15.16"}}} - , {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.2.1"}}} + , {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.2.2"}}} , {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.8"}}} , {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.3.14"}}} , {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.4"}}} diff --git a/rebar.config.erl b/rebar.config.erl index 98e29f32a..e054f2661 100644 --- a/rebar.config.erl +++ b/rebar.config.erl @@ -16,7 +16,7 @@ do(Dir, CONFIG) -> assert_otp() -> Oldest = 24, - Latest = 25, + Latest = 26, OtpRelease = list_to_integer(erlang:system_info(otp_release)), case OtpRelease < Oldest orelse OtpRelease > Latest of true -> @@ -42,7 +42,7 @@ quicer() -> {quicer, {git, "https://github.com/emqx/quic.git", {tag, "0.0.202"}}}. jq() -> - {jq, {git, "https://github.com/emqx/jq", {tag, "v0.3.11"}}}. + {jq, {git, "https://github.com/emqx/jq", {tag, "v0.3.12"}}}. deps(Config) -> {deps, OldDeps} = lists:keyfind(deps, 1, Config), @@ -53,7 +53,10 @@ deps(Config) -> lists:keystore(deps, 1, Config, {deps, OldDeps ++ MoreDeps}). overrides() -> - [{add, [{extra_src_dirs, [{"etc", [{recursive, true}]}]}]}] ++ snabbkaffe_overrides(). + [ + {add, [{extra_src_dirs, [{"etc", [{recursive, true}]}]}]}, + {add, jesse, [{erl_opts, [nowarn_match_float_zero]}]} + ] ++ snabbkaffe_overrides(). %% Temporary workaround for a rebar3 erl_opts duplication %% bug. Ideally, we want to set this define globally diff --git a/scripts/ensure-rebar3.sh b/scripts/ensure-rebar3.sh index 12c492132..054deabd4 100755 --- a/scripts/ensure-rebar3.sh +++ b/scripts/ensure-rebar3.sh @@ -18,6 +18,9 @@ case ${OTP_VSN} in 25*) VERSION="3.19.0-emqx-9" ;; + 26*) + VERSION="3.20.0-emqx-1" + ;; *) echo "Unsupporetd Erlang/OTP version $OTP_VSN" exit 1