162 lines
5.4 KiB
Erlang
162 lines
5.4 KiB
Erlang
%%--------------------------------------------------------------------
|
|
%% Copyright (c) 2020 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.
|
|
%%--------------------------------------------------------------------
|
|
|
|
-module(emqx_rpc_SUITE).
|
|
|
|
-compile(export_all).
|
|
-compile(nowarn_export_all).
|
|
|
|
-include_lib("proper/include/proper.hrl").
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
|
all() -> emqx_ct:all(?MODULE).
|
|
|
|
t_prop_rpc(_) ->
|
|
ok = load(),
|
|
Opts = [{to_file, user}, {numtests, 10}],
|
|
{ok, _Apps} = application:ensure_all_started(gen_rpc),
|
|
ok = application:set_env(gen_rpc, call_receive_timeout, 1),
|
|
ok = emqx_logger:set_log_level(emergency),
|
|
?assert(proper:quickcheck(prop_node(), Opts)),
|
|
?assert(proper:quickcheck(prop_node_with_key(), Opts)),
|
|
?assert(proper:quickcheck(prop_nodes(), Opts)),
|
|
?assert(proper:quickcheck(prop_nodes_with_key(), Opts)),
|
|
ok = application:stop(gen_rpc),
|
|
ok = unload().
|
|
|
|
prop_node() ->
|
|
?FORALL(Node, nodename(),
|
|
begin
|
|
?assert(emqx_rpc:cast(Node, erlang, system_time, [])),
|
|
case emqx_rpc:call(Node, erlang, system_time, []) of
|
|
{badrpc, _Reason} -> true;
|
|
Delivery when is_integer(Delivery) -> true;
|
|
_Other -> false
|
|
end
|
|
end).
|
|
|
|
prop_node_with_key() ->
|
|
?FORALL({Node, Key}, nodename_with_key(),
|
|
begin
|
|
?assert(emqx_rpc:cast(Key, Node, erlang, system_time, [])),
|
|
case emqx_rpc:call(Key, Node, erlang, system_time, []) of
|
|
{badrpc, _Reason} -> true;
|
|
Delivery when is_integer(Delivery) -> true;
|
|
_Other -> false
|
|
end
|
|
end).
|
|
|
|
prop_nodes() ->
|
|
?FORALL(Nodes, nodesname(),
|
|
begin
|
|
case emqx_rpc:multicall(Nodes, erlang, system_time, []) of
|
|
{badrpc, _Reason} -> true;
|
|
{RealResults, RealBadNodes}
|
|
when is_list(RealResults);
|
|
is_list(RealBadNodes) ->
|
|
true;
|
|
_Other -> false
|
|
end
|
|
end).
|
|
|
|
prop_nodes_with_key() ->
|
|
?FORALL({Nodes, Key}, nodesname_with_key(),
|
|
begin
|
|
case emqx_rpc:multicall(Key, Nodes, erlang, system_time, []) of
|
|
{badrpc, _Reason} -> true;
|
|
{RealResults, RealBadNodes}
|
|
when is_list(RealResults);
|
|
is_list(RealBadNodes) ->
|
|
true;
|
|
_Other -> false
|
|
end
|
|
end).
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% helper
|
|
%%--------------------------------------------------------------------
|
|
|
|
load() ->
|
|
ok = meck:new(gen_rpc, [passthrough, no_history]),
|
|
ok = meck:expect(gen_rpc, multicall,
|
|
fun(Nodes, Mod, Fun, Args) ->
|
|
gen_rpc:multicall(Nodes, Mod, Fun, Args, 1)
|
|
end).
|
|
|
|
unload() ->
|
|
ok = meck:unload(gen_rpc).
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% Generator
|
|
%%--------------------------------------------------------------------
|
|
|
|
nodename() ->
|
|
?LET({NodePrefix, HostName},
|
|
{node_prefix(), hostname()},
|
|
begin
|
|
Node = NodePrefix ++ "@" ++ HostName,
|
|
list_to_atom(Node)
|
|
end).
|
|
|
|
nodename_with_key() ->
|
|
?LET({NodePrefix, HostName, Key},
|
|
{node_prefix(), hostname(), choose(0, 10)},
|
|
begin
|
|
Node = NodePrefix ++ "@" ++ HostName,
|
|
{list_to_atom(Node), Key}
|
|
end).
|
|
|
|
nodesname() ->
|
|
oneof([list(nodename()), ['emqxct@127.0.0.1']]).
|
|
|
|
nodesname_with_key() ->
|
|
oneof([{list(nodename()), choose(0, 10)}, {['emqxct@127.0.0.1'], 1}]).
|
|
|
|
node_prefix() ->
|
|
oneof(["emqxct", text_like()]).
|
|
|
|
text_like() ->
|
|
?SUCHTHAT(Text, list(range($a, $z)), (length(Text) =< 5 andalso length(Text) > 0)).
|
|
|
|
hostname() ->
|
|
oneof([ipv4_address(), ipv6_address(), "127.0.0.1", "localhost"]).
|
|
|
|
ipv4_address() ->
|
|
?LET({Num1, Num2, Num3, Num4},
|
|
{ choose(0, 255)
|
|
, choose(0, 255)
|
|
, choose(0, 255)
|
|
, choose(0, 255)},
|
|
make_ip([Num1, Num2, Num3, Num4], ipv4)).
|
|
|
|
ipv6_address() ->
|
|
?LET({Num1, Num2, Num3, Num4, Num5, Num6},
|
|
{ choose(0, 65535)
|
|
, choose(0, 65535)
|
|
, choose(0, 65535)
|
|
, choose(0, 65535)
|
|
, choose(0, 65535)
|
|
, choose(0, 65535)},
|
|
make_ip([Num1, Num2, Num3, Num4, Num5, Num6], ipv6)).
|
|
|
|
|
|
make_ip(NumList, ipv4) when is_list(NumList) ->
|
|
string:join([integer_to_list(Num) || Num <- NumList], ".");
|
|
make_ip(NumList, ipv6) when is_list(NumList) ->
|
|
string:join([integer_to_list(Num) || Num <- NumList], ":");
|
|
make_ip(_List, _protocol) ->
|
|
"127.0.0.1".
|