test(proper): test message hooks
This commit is contained in:
parent
b7a8884d4a
commit
9f088bcb7f
|
@ -179,18 +179,44 @@ on_client_disconnected(Req, Md) ->
|
||||||
-spec on_client_authenticate(emqx_exhook_pb:client_authenticate_request(), grpc:metadata())
|
-spec on_client_authenticate(emqx_exhook_pb:client_authenticate_request(), grpc:metadata())
|
||||||
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
||||||
| {error, grpc_cowboy_h:error_response()}.
|
| {error, grpc_cowboy_h:error_response()}.
|
||||||
on_client_authenticate(Req, Md) ->
|
on_client_authenticate(#{clientinfo := #{username := Username}} = Req, Md) ->
|
||||||
?MODULE:in({?FUNCTION_NAME, Req}),
|
?MODULE:in({?FUNCTION_NAME, Req}),
|
||||||
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
||||||
{ok, #{type => 'IGNORE'}, Md}.
|
%% some cases for testing
|
||||||
|
case Username of
|
||||||
|
<<"baduser">> ->
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {bool_result, false}}, Md};
|
||||||
|
<<"gooduser">> ->
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {bool_result, true}}, Md};
|
||||||
|
<<"normaluser">> ->
|
||||||
|
{ok, #{type => 'CONTINUE',
|
||||||
|
value => {bool_result, true}}, Md};
|
||||||
|
_ ->
|
||||||
|
{ok, #{type => 'IGNORE'}, Md}
|
||||||
|
end.
|
||||||
|
|
||||||
-spec on_client_check_acl(emqx_exhook_pb:client_check_acl_request(), grpc:metadata())
|
-spec on_client_check_acl(emqx_exhook_pb:client_check_acl_request(), grpc:metadata())
|
||||||
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
||||||
| {error, grpc_cowboy_h:error_response()}.
|
| {error, grpc_cowboy_h:error_response()}.
|
||||||
on_client_check_acl(Req, Md) ->
|
on_client_check_acl(#{clientinfo := #{username := Username}} = Req, Md) ->
|
||||||
?MODULE:in({?FUNCTION_NAME, Req}),
|
?MODULE:in({?FUNCTION_NAME, Req}),
|
||||||
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
||||||
{ok, #{type => 'STOP_AND_RETURN', value => {bool_result, true}}, Md}.
|
%% some cases for testing
|
||||||
|
case Username of
|
||||||
|
<<"baduser">> ->
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {bool_result, false}}, Md};
|
||||||
|
<<"gooduser">> ->
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {bool_result, true}}, Md};
|
||||||
|
<<"normaluser">> ->
|
||||||
|
{ok, #{type => 'CONTINUE',
|
||||||
|
value => {bool_result, true}}, Md};
|
||||||
|
_ ->
|
||||||
|
{ok, #{type => 'IGNORE'}, Md}
|
||||||
|
end.
|
||||||
|
|
||||||
-spec on_client_subscribe(emqx_exhook_pb:client_subscribe_request(), grpc:metadata())
|
-spec on_client_subscribe(emqx_exhook_pb:client_subscribe_request(), grpc:metadata())
|
||||||
-> {ok, emqx_exhook_pb:empty_success(), grpc:metadata()}
|
-> {ok, emqx_exhook_pb:empty_success(), grpc:metadata()}
|
||||||
|
@ -267,10 +293,26 @@ on_session_terminated(Req, Md) ->
|
||||||
-spec on_message_publish(emqx_exhook_pb:message_publish_request(), grpc:metadata())
|
-spec on_message_publish(emqx_exhook_pb:message_publish_request(), grpc:metadata())
|
||||||
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
-> {ok, emqx_exhook_pb:valued_response(), grpc:metadata()}
|
||||||
| {error, grpc_cowboy_h:error_response()}.
|
| {error, grpc_cowboy_h:error_response()}.
|
||||||
on_message_publish(Req, Md) ->
|
on_message_publish(#{message := #{from := From} = Msg} = Req, Md) ->
|
||||||
?MODULE:in({?FUNCTION_NAME, Req}),
|
?MODULE:in({?FUNCTION_NAME, Req}),
|
||||||
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
%io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
|
||||||
{ok, #{}, Md}.
|
%% some cases for testing
|
||||||
|
case From of
|
||||||
|
<<"baduser">> ->
|
||||||
|
NMsg = Msg#{qos => 0,
|
||||||
|
topic => <<"">>,
|
||||||
|
payload => <<"">>
|
||||||
|
},
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {message, NMsg}}, Md};
|
||||||
|
<<"gooduser">> ->
|
||||||
|
NMsg = Msg#{topic => From,
|
||||||
|
payload => From},
|
||||||
|
{ok, #{type => 'STOP_AND_RETURN',
|
||||||
|
value => {message, NMsg}}, Md};
|
||||||
|
_ ->
|
||||||
|
{ok, #{type => 'IGNORE'}, Md}
|
||||||
|
end.
|
||||||
|
|
||||||
-spec on_message_delivered(emqx_exhook_pb:message_delivered_request(), grpc:metadata())
|
-spec on_message_delivered(emqx_exhook_pb:message_delivered_request(), grpc:metadata())
|
||||||
-> {ok, emqx_exhook_pb:empty_success(), grpc:metadata()}
|
-> {ok, emqx_exhook_pb:empty_success(), grpc:metadata()}
|
||||||
|
|
|
@ -44,20 +44,11 @@ prop_client_connect() ->
|
||||||
?ALL({ConnInfo, ConnProps},
|
?ALL({ConnInfo, ConnProps},
|
||||||
{conninfo(), conn_properties()},
|
{conninfo(), conn_properties()},
|
||||||
begin
|
begin
|
||||||
_OutConnProps = emqx_hooks:run_fold('client.connect', [ConnInfo], ConnProps),
|
ok = emqx_hooks:run('client.connect', [ConnInfo, ConnProps]),
|
||||||
{'on_client_connect', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_connect', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{props => properties(ConnProps),
|
#{props => properties(ConnProps),
|
||||||
conninfo =>
|
conninfo => from_conninfo(ConnInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ConnInfo),
|
|
||||||
username => maybe(maps:get(username, ConnInfo, <<>>)),
|
|
||||||
peerhost => peerhost(ConnInfo),
|
|
||||||
sockport => sockport(ConnInfo),
|
|
||||||
proto_name => maps:get(proto_name, ConnInfo),
|
|
||||||
proto_ver => stringfy(maps:get(proto_ver, ConnInfo)),
|
|
||||||
keepalive => maps:get(keepalive, ConnInfo)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -67,78 +58,86 @@ prop_client_connack() ->
|
||||||
?ALL({ConnInfo, Rc, AckProps},
|
?ALL({ConnInfo, Rc, AckProps},
|
||||||
{conninfo(), connack_return_code(), ack_properties()},
|
{conninfo(), connack_return_code(), ack_properties()},
|
||||||
begin
|
begin
|
||||||
_OutAckProps = emqx_hooks:run_fold('client.connack', [ConnInfo, Rc], AckProps),
|
ok = emqx_hooks:run('client.connack', [ConnInfo, Rc, AckProps]),
|
||||||
{'on_client_connack', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_connack', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{props => properties(AckProps),
|
#{props => properties(AckProps),
|
||||||
result_code => atom_to_binary(Rc, utf8),
|
result_code => atom_to_binary(Rc, utf8),
|
||||||
conninfo =>
|
conninfo => from_conninfo(ConnInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ConnInfo),
|
|
||||||
username => maybe(maps:get(username, ConnInfo, <<>>)),
|
|
||||||
peerhost => peerhost(ConnInfo),
|
|
||||||
sockport => sockport(ConnInfo),
|
|
||||||
proto_name => maps:get(proto_name, ConnInfo),
|
|
||||||
proto_ver => stringfy(maps:get(proto_ver, ConnInfo)),
|
|
||||||
keepalive => maps:get(keepalive, ConnInfo)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
end).
|
end).
|
||||||
|
|
||||||
prop_client_authenticate() ->
|
prop_client_authenticate() ->
|
||||||
?ALL({ClientInfo, AuthResult}, {clientinfo(), authresult()},
|
?ALL({ClientInfo0, AuthResult},
|
||||||
|
{clientinfo(), authresult()},
|
||||||
begin
|
begin
|
||||||
_OutAuthResult = emqx_hooks:run_fold('client.authenticate', [ClientInfo], AuthResult),
|
ClientInfo = inject_magic_into(username, ClientInfo0),
|
||||||
|
OutAuthResult = emqx_hooks:run_fold('client.authenticate', [ClientInfo], AuthResult),
|
||||||
|
ExpectedAuthResult = case maps:get(username, ClientInfo) of
|
||||||
|
<<"baduser">> ->
|
||||||
|
AuthResult#{
|
||||||
|
auth_result => not_authorized,
|
||||||
|
anonymous => false};
|
||||||
|
<<"gooduser">> ->
|
||||||
|
AuthResult#{
|
||||||
|
auth_result => success,
|
||||||
|
anonymous => false};
|
||||||
|
<<"normaluser">> ->
|
||||||
|
AuthResult#{
|
||||||
|
auth_result => success,
|
||||||
|
anonymous => false};
|
||||||
|
_ ->
|
||||||
|
case maps:get(auth_result, AuthResult) of
|
||||||
|
success ->
|
||||||
|
#{auth_result => success,
|
||||||
|
anonymous => false};
|
||||||
|
_ ->
|
||||||
|
#{auth_result => not_authorized,
|
||||||
|
anonymous => false}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
?assertEqual(ExpectedAuthResult, OutAuthResult),
|
||||||
|
|
||||||
{'on_client_authenticate', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_authenticate', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{result => authresult_to_bool(AuthResult),
|
#{result => authresult_to_bool(AuthResult),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
end).
|
end).
|
||||||
|
|
||||||
prop_client_check_acl() ->
|
prop_client_check_acl() ->
|
||||||
?ALL({ClientInfo, PubSub, Topic, Result},
|
?ALL({ClientInfo0, PubSub, Topic, Result},
|
||||||
{clientinfo(), oneof([publish, subscribe]), topic(), oneof([allow, deny])},
|
{clientinfo(), oneof([publish, subscribe]),
|
||||||
|
topic(), oneof([allow, deny])},
|
||||||
begin
|
begin
|
||||||
_OutResult = emqx_hooks:run_fold('client.check_acl', [ClientInfo, PubSub, Topic], Result),
|
ClientInfo = inject_magic_into(username, ClientInfo0),
|
||||||
|
OutResult = emqx_hooks:run_fold(
|
||||||
|
'client.check_acl',
|
||||||
|
[ClientInfo, PubSub, Topic],
|
||||||
|
Result),
|
||||||
|
ExpectedOutResult = case maps:get(username, ClientInfo) of
|
||||||
|
<<"baduser">> -> deny;
|
||||||
|
<<"gooduser">> -> allow;
|
||||||
|
<<"normaluser">> -> allow;
|
||||||
|
_ -> Result
|
||||||
|
end,
|
||||||
|
?assertEqual(ExpectedOutResult, OutResult),
|
||||||
|
|
||||||
{'on_client_check_acl', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_check_acl', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{result => aclresult_to_bool(Result),
|
#{result => aclresult_to_bool(Result),
|
||||||
type => pubsub_to_enum(PubSub),
|
type => pubsub_to_enum(PubSub),
|
||||||
topic => Topic,
|
topic => Topic,
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
|
||||||
prop_client_connected() ->
|
prop_client_connected() ->
|
||||||
?ALL({ClientInfo, ConnInfo},
|
?ALL({ClientInfo, ConnInfo},
|
||||||
{clientinfo(), conninfo()},
|
{clientinfo(), conninfo()},
|
||||||
|
@ -146,18 +145,7 @@ prop_client_connected() ->
|
||||||
ok = emqx_hooks:run('client.connected', [ClientInfo, ConnInfo]),
|
ok = emqx_hooks:run('client.connected', [ClientInfo, ConnInfo]),
|
||||||
{'on_client_connected', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_connected', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{clientinfo =>
|
#{clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -171,18 +159,7 @@ prop_client_disconnected() ->
|
||||||
{'on_client_disconnected', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_disconnected', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{reason => stringfy(Reason),
|
#{reason => stringfy(Reason),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -192,23 +169,12 @@ prop_client_subscribe() ->
|
||||||
?ALL({ClientInfo, SubProps, TopicTab},
|
?ALL({ClientInfo, SubProps, TopicTab},
|
||||||
{clientinfo(), sub_properties(), topictab()},
|
{clientinfo(), sub_properties(), topictab()},
|
||||||
begin
|
begin
|
||||||
_OutTopicTab = emqx_hooks:run_fold('client.subscribe', [ClientInfo, SubProps], TopicTab),
|
ok = emqx_hooks:run('client.subscribe', [ClientInfo, SubProps, TopicTab]),
|
||||||
{'on_client_subscribe', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_subscribe', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{props => properties(SubProps),
|
#{props => properties(SubProps),
|
||||||
topic_filters => topicfilters(TopicTab),
|
topic_filters => topicfilters(TopicTab),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -218,23 +184,12 @@ prop_client_unsubscribe() ->
|
||||||
?ALL({ClientInfo, UnSubProps, TopicTab},
|
?ALL({ClientInfo, UnSubProps, TopicTab},
|
||||||
{clientinfo(), unsub_properties(), topictab()},
|
{clientinfo(), unsub_properties(), topictab()},
|
||||||
begin
|
begin
|
||||||
_OutTopicTab = emqx_hooks:run_fold('client.unsubscribe', [ClientInfo, UnSubProps], TopicTab),
|
ok = emqx_hooks:run('client.unsubscribe', [ClientInfo, UnSubProps, TopicTab]),
|
||||||
{'on_client_unsubscribe', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_client_unsubscribe', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{props => properties(UnSubProps),
|
#{props => properties(UnSubProps),
|
||||||
topic_filters => topicfilters(TopicTab),
|
topic_filters => topicfilters(TopicTab),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -246,18 +201,7 @@ prop_session_created() ->
|
||||||
ok = emqx_hooks:run('session.created', [ClientInfo, SessInfo]),
|
ok = emqx_hooks:run('session.created', [ClientInfo, SessInfo]),
|
||||||
{'on_session_created', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_created', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{clientinfo =>
|
#{clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -272,18 +216,7 @@ prop_session_subscribed() ->
|
||||||
Expected =
|
Expected =
|
||||||
#{topic => Topic,
|
#{topic => Topic,
|
||||||
subopts => subopts(SubOpts),
|
subopts => subopts(SubOpts),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -297,18 +230,7 @@ prop_session_unsubscribed() ->
|
||||||
{'on_session_unsubscribed', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_unsubscribed', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{topic => Topic,
|
#{topic => Topic,
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -320,18 +242,7 @@ prop_session_resumed() ->
|
||||||
ok = emqx_hooks:run('session.resumed', [ClientInfo, SessInfo]),
|
ok = emqx_hooks:run('session.resumed', [ClientInfo, SessInfo]),
|
||||||
{'on_session_resumed', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_resumed', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{clientinfo =>
|
#{clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -343,18 +254,7 @@ prop_session_discared() ->
|
||||||
ok = emqx_hooks:run('session.discarded', [ClientInfo, SessInfo]),
|
ok = emqx_hooks:run('session.discarded', [ClientInfo, SessInfo]),
|
||||||
{'on_session_discarded', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_discarded', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{clientinfo =>
|
#{clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -366,18 +266,7 @@ prop_session_takeovered() ->
|
||||||
ok = emqx_hooks:run('session.takeovered', [ClientInfo, SessInfo]),
|
ok = emqx_hooks:run('session.takeovered', [ClientInfo, SessInfo]),
|
||||||
{'on_session_takeovered', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_takeovered', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{clientinfo =>
|
#{clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
true
|
true
|
||||||
|
@ -391,21 +280,98 @@ prop_session_terminated() ->
|
||||||
{'on_session_terminated', Resp} = emqx_exhook_demo_svr:take(),
|
{'on_session_terminated', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
Expected =
|
Expected =
|
||||||
#{reason => stringfy(Reason),
|
#{reason => stringfy(Reason),
|
||||||
clientinfo =>
|
clientinfo => from_clientinfo(ClientInfo)
|
||||||
#{node => nodestr(),
|
|
||||||
clientid => maps:get(clientid, ClientInfo),
|
|
||||||
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
|
||||||
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
|
||||||
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
|
||||||
sockport => maps:get(sockport, ClientInfo),
|
|
||||||
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
|
||||||
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
|
||||||
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
|
||||||
anonymous => maps:get(anonymous, ClientInfo, true)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
?assertEqual(Expected, Resp),
|
?assertEqual(Expected, Resp),
|
||||||
|
true
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_message_publish() ->
|
||||||
|
?ALL(Msg0, message(),
|
||||||
|
begin
|
||||||
|
Msg = emqx_message:from_map(
|
||||||
|
inject_magic_into(from, emqx_message:to_map(Msg0))),
|
||||||
|
OutMsg= emqx_hooks:run_fold('message.publish', [], Msg),
|
||||||
|
case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
|
||||||
|
true ->
|
||||||
|
?assertEqual(Msg, OutMsg),
|
||||||
|
skip;
|
||||||
|
_ ->
|
||||||
|
ExpectedOutMsg = case emqx_message:from(Msg) of
|
||||||
|
<<"baduser">> ->
|
||||||
|
MsgMap = emqx_message:to_map(Msg),
|
||||||
|
emqx_message:from_map(
|
||||||
|
MsgMap#{qos => 0,
|
||||||
|
topic => <<"">>,
|
||||||
|
payload => <<"">>
|
||||||
|
});
|
||||||
|
<<"gooduser">> = From ->
|
||||||
|
MsgMap = emqx_message:to_map(Msg),
|
||||||
|
emqx_message:from_map(
|
||||||
|
MsgMap#{topic => From,
|
||||||
|
payload => From
|
||||||
|
});
|
||||||
|
_ -> Msg
|
||||||
|
end,
|
||||||
|
?assertEqual(ExpectedOutMsg, OutMsg),
|
||||||
|
|
||||||
|
{'on_message_publish', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
|
Expected =
|
||||||
|
#{message => from_message(Msg)
|
||||||
|
},
|
||||||
|
?assertEqual(Expected, Resp)
|
||||||
|
end,
|
||||||
|
true
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_message_dropped() ->
|
||||||
|
?ALL({Msg, By, Reason}, {message(), hardcoded, shutdown_reason()},
|
||||||
|
begin
|
||||||
|
ok = emqx_hooks:run('message.dropped', [Msg, By, Reason]),
|
||||||
|
case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
|
||||||
|
true -> skip;
|
||||||
|
_ ->
|
||||||
|
{'on_message_dropped', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
|
Expected =
|
||||||
|
#{reason => stringfy(Reason),
|
||||||
|
message => from_message(Msg)
|
||||||
|
},
|
||||||
|
?assertEqual(Expected, Resp)
|
||||||
|
end,
|
||||||
|
true
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_message_delivered() ->
|
||||||
|
?ALL({ClientInfo, Msg}, {clientinfo(), message()},
|
||||||
|
begin
|
||||||
|
ok = emqx_hooks:run('message.delivered', [ClientInfo, Msg]),
|
||||||
|
case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
|
||||||
|
true -> skip;
|
||||||
|
_ ->
|
||||||
|
{'on_message_delivered', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
|
Expected =
|
||||||
|
#{clientinfo => from_clientinfo(ClientInfo),
|
||||||
|
message => from_message(Msg)
|
||||||
|
},
|
||||||
|
?assertEqual(Expected, Resp)
|
||||||
|
end,
|
||||||
|
true
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_message_acked() ->
|
||||||
|
?ALL({ClientInfo, Msg}, {clientinfo(), message()},
|
||||||
|
begin
|
||||||
|
ok = emqx_hooks:run('message.acked', [ClientInfo, Msg]),
|
||||||
|
case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
|
||||||
|
true -> skip;
|
||||||
|
_ ->
|
||||||
|
{'on_message_acked', Resp} = emqx_exhook_demo_svr:take(),
|
||||||
|
Expected =
|
||||||
|
#{clientinfo => from_clientinfo(ClientInfo),
|
||||||
|
message => from_message(Msg)
|
||||||
|
},
|
||||||
|
?assertEqual(Expected, Resp)
|
||||||
|
end,
|
||||||
true
|
true
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
@ -465,23 +431,39 @@ aclresult_to_bool(Result) ->
|
||||||
pubsub_to_enum(publish) -> 'PUBLISH';
|
pubsub_to_enum(publish) -> 'PUBLISH';
|
||||||
pubsub_to_enum(subscribe) -> 'SUBSCRIBE'.
|
pubsub_to_enum(subscribe) -> 'SUBSCRIBE'.
|
||||||
|
|
||||||
%prop_message_publish() ->
|
from_conninfo(ConnInfo) ->
|
||||||
% ?ALL({Msg, Env, Encode}, {message(), topic_filter_env()},
|
#{node => nodestr(),
|
||||||
% begin
|
clientid => maps:get(clientid, ConnInfo),
|
||||||
% true
|
username => maybe(maps:get(username, ConnInfo, <<>>)),
|
||||||
% end).
|
peerhost => peerhost(ConnInfo),
|
||||||
%
|
sockport => sockport(ConnInfo),
|
||||||
%prop_message_delivered() ->
|
proto_name => maps:get(proto_name, ConnInfo),
|
||||||
% ?ALL({ClientInfo, Msg, Env, Encode}, {clientinfo(), message(), topic_filter_env()},
|
proto_ver => stringfy(maps:get(proto_ver, ConnInfo)),
|
||||||
% begin
|
keepalive => maps:get(keepalive, ConnInfo)
|
||||||
% true
|
}.
|
||||||
% end).
|
|
||||||
%
|
from_clientinfo(ClientInfo) ->
|
||||||
%prop_message_acked() ->
|
#{node => nodestr(),
|
||||||
% ?ALL({ClientInfo, Msg, Env, Encode}, {clientinfo(), message()},
|
clientid => maps:get(clientid, ClientInfo),
|
||||||
% begin
|
username => maybe(maps:get(username, ClientInfo, <<>>)),
|
||||||
% true
|
password => maybe(maps:get(password, ClientInfo, <<>>)),
|
||||||
% end).
|
peerhost => ntoa(maps:get(peerhost, ClientInfo)),
|
||||||
|
sockport => maps:get(sockport, ClientInfo),
|
||||||
|
protocol => stringfy(maps:get(protocol, ClientInfo)),
|
||||||
|
mountpoint => maybe(maps:get(mountpoint, ClientInfo, <<>>)),
|
||||||
|
is_superuser => maps:get(is_superuser, ClientInfo, false),
|
||||||
|
anonymous => maps:get(anonymous, ClientInfo, true)
|
||||||
|
}.
|
||||||
|
|
||||||
|
from_message(Msg) ->
|
||||||
|
#{node => nodestr(),
|
||||||
|
id => emqx_guid:to_hexstr(emqx_message:id(Msg)),
|
||||||
|
qos => emqx_message:qos(Msg),
|
||||||
|
from => stringfy(emqx_message:from(Msg)),
|
||||||
|
topic => emqx_message:topic(Msg),
|
||||||
|
payload => emqx_message:payload(Msg),
|
||||||
|
timestamp => emqx_message:timestamp(Msg)
|
||||||
|
}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Helper
|
%% Helper
|
||||||
|
@ -533,7 +515,15 @@ shutdown_reason() ->
|
||||||
oneof([utf8(), {shutdown, emqx_ct_proper_types:limited_atom()}]).
|
oneof([utf8(), {shutdown, emqx_ct_proper_types:limited_atom()}]).
|
||||||
|
|
||||||
authresult() ->
|
authresult() ->
|
||||||
#{auth_result => connack_return_code()}.
|
?LET(RC, connack_return_code(), #{auth_result => RC}).
|
||||||
|
|
||||||
%topic_filter_env() ->
|
inject_magic_into(Key, Object) ->
|
||||||
% oneof([{<<"#">>}, {undefined}, {topic()}]).
|
case castspell() of
|
||||||
|
muggles -> Object;
|
||||||
|
Spell ->
|
||||||
|
Object#{Key => Spell}
|
||||||
|
end.
|
||||||
|
|
||||||
|
castspell() ->
|
||||||
|
L = [<<"baduser">>, <<"gooduser">>, <<"normaluser">>, muggles],
|
||||||
|
lists:nth(rand:uniform(length(L)), L).
|
||||||
|
|
Loading…
Reference in New Issue