Просмотр исходного кода

test(exhook): exhook request_meta SUITE and prop tests

JimMoen 3 лет назад
Родитель
Сommit
a7542e1673

+ 42 - 3
apps/emqx_exhook/test/emqx_exhook_SUITE.erl

@@ -19,8 +19,15 @@
 -compile(export_all).
 -compile(nowarn_export_all).
 
+-include("emqx_exhook.hrl").
+
 -include_lib("eunit/include/eunit.hrl").
 -include_lib("common_test/include/ct.hrl").
+
+-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
+
+-define(OTHER_CLUSTER_NAME_ATOM, test_emqx_cluster).
+-define(OTHER_CLUSTER_NAME_STRING, "test_emqx_cluster").
 -define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
 
 -define(CONF_DEFAULT, <<
@@ -54,6 +61,7 @@ all() -> emqx_common_test_helpers:all(?MODULE).
 init_per_suite(Cfg) ->
     application:load(emqx_conf),
     ok = ekka:start(),
+    application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
     ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
     meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
     meck:expect(emqx_alarm, activate, 3, ok),
@@ -65,6 +73,7 @@ init_per_suite(Cfg) ->
     Cfg.
 
 end_per_suite(_Cfg) ->
+    application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
     ekka:stop(),
     mria:stop(),
     mria_mnesia:delete_schema(),
@@ -95,7 +104,7 @@ load_cfg(Cfg) ->
 %% Test cases
 %%--------------------------------------------------------------------
 
-t_access_failed_if_no_server_running(_) ->
+t_access_failed_if_no_server_running(Config) ->
     emqx_exhook_mgr:disable(<<"default">>),
     ClientInfo = #{
         clientid => <<"user-id-1">>,
@@ -120,7 +129,8 @@ t_access_failed_if_no_server_running(_) ->
         {stop, Message},
         emqx_exhook_handler:on_message_publish(Message)
     ),
-    emqx_exhook_mgr:enable(<<"default">>).
+    emqx_exhook_mgr:enable(<<"default">>),
+    assert_get_basic_usage_info(Config).
 
 t_lookup(_) ->
     Result = emqx_exhook_mgr:lookup(<<"default">>),
@@ -250,7 +260,36 @@ t_misc_test(_) ->
     _ = emqx_exhook_server:format(#{name => <<"test">>, hookspec => #{}}),
     ok.
 
-t_get_basic_usage_info(_Config) ->
+t_cluster_name(_) ->
+    SetEnvFun =
+        fun
+            (emqx) ->
+                application:set_env(ekka, cluster_name, ?OTHER_CLUSTER_NAME_ATOM);
+            (emqx_exhook) ->
+                ok
+        end,
+
+    emqx_common_test_helpers:stop_apps([emqx, emqx_exhook]),
+    emqx_common_test_helpers:start_apps([emqx, emqx_exhook], SetEnvFun),
+
+    ?assertEqual(?OTHER_CLUSTER_NAME_STRING, emqx_sys:cluster_name()),
+
+    emqx_exhook_mgr:disable(<<"default">>),
+    emqx_exhook_mgr:enable(<<"default">>),
+    %% See emqx_exhook_demo_svr:on_provider_loaded/2
+    ?assertEqual([], emqx_hooks:lookup('session.created')),
+    ?assertEqual([], emqx_hooks:lookup('message_publish')),
+    ?assertEqual(
+        true,
+        erlang:length(emqx_hooks:lookup('client.connected')) > 1
+    ),
+    emqx_exhook_mgr:disable(<<"default">>).
+
+%%--------------------------------------------------------------------
+%% Cases Helpers
+%%--------------------------------------------------------------------
+
+assert_get_basic_usage_info(_Config) ->
     #{
         num_servers := NumServers,
         servers := Servers

+ 12 - 1
apps/emqx_exhook/test/emqx_exhook_api_SUITE.erl

@@ -26,6 +26,8 @@
 -define(BASE_PATH, "api").
 -define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
 
+-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
+
 -define(CONF_DEFAULT, <<
     "\n"
     "exhook {\n"
@@ -54,18 +56,20 @@ all() ->
 init_per_suite(Config) ->
     application:load(emqx_conf),
     ok = ekka:start(),
+    application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
     ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
     meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
     meck:expect(emqx_alarm, activate, 3, ok),
     meck:expect(emqx_alarm, deactivate, 3, ok),
 
     _ = emqx_exhook_demo_svr:start(),
-    ok = emqx_common_test_helpers:load_config(emqx_exhook_schema, ?CONF_DEFAULT),
+    load_cfg(?CONF_DEFAULT),
     emqx_mgmt_api_test_util:init_suite([emqx_exhook]),
     [Conf] = emqx:get_config([exhook, servers]),
     [{template, Conf} | Config].
 
 end_per_suite(Config) ->
+    application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
     ekka:stop(),
     mria:stop(),
     mria_mnesia:delete_schema(),
@@ -96,6 +100,13 @@ end_per_testcase(_, Config) ->
     end,
     Config.
 
+load_cfg(Cfg) ->
+    ok = emqx_common_test_helpers:load_config(emqx_exhook_schema, Cfg).
+
+%%--------------------------------------------------------------------
+%% Test cases
+%%--------------------------------------------------------------------
+
 t_list(_) ->
     {ok, Data} = request_api(
         get,

+ 40 - 29
apps/emqx_exhook/test/emqx_exhook_demo_svr.erl

@@ -16,7 +16,7 @@
 
 -module(emqx_exhook_demo_svr).
 
--behaviour(emqx_exhook_v_1_hook_provider_bhvr).
+-behaviour(emqx_exhook_v_2_hook_provider_bhvr).
 
 %%
 -export([
@@ -55,6 +55,8 @@
 
 -define(PORT, 9000).
 -define(NAME, ?MODULE).
+-define(DEFAULT_CLUSTER_NAME, <<"emqxcl">>).
+-define(OTHER_CLUSTER_NAME_BIN, <<"test_emqx_cluster">>).
 
 %%--------------------------------------------------------------------
 %% Server APIs
@@ -89,7 +91,7 @@ mgr_main(Name, Port) ->
     application:ensure_all_started(grpc),
     Services = #{
         protos => [emqx_exhook_pb],
-        services => #{'emqx.exhook.v1.HookProvider' => emqx_exhook_demo_svr}
+        services => #{'emqx.exhook.v2.HookProvider' => emqx_exhook_demo_svr}
     },
     Options = [],
     Svr = grpc:start_server(Name, Port, Services, Options),
@@ -134,34 +136,43 @@ to_atom_name(Name) ->
     {ok, emqx_exhook_pb:loaded_response(), grpc:metadata()}
     | {error, grpc_cowboy_h:error_response()}.
 
-on_provider_loaded(Req, Md) ->
+on_provider_loaded(#{meta := #{cluster_name := Name}} = Req, Md) ->
     ?MODULE:in({?FUNCTION_NAME, Req}),
-    %io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
-    {ok,
-        #{
-            hooks => [
-                #{name => <<"client.connect">>},
-                #{name => <<"client.connack">>},
-                #{name => <<"client.connected">>},
-                #{name => <<"client.disconnected">>},
-                #{name => <<"client.authenticate">>},
-                #{name => <<"client.authorize">>},
-                #{name => <<"client.subscribe">>},
-                #{name => <<"client.unsubscribe">>},
-                #{name => <<"session.created">>},
-                #{name => <<"session.subscribed">>},
-                #{name => <<"session.unsubscribed">>},
-                #{name => <<"session.resumed">>},
-                #{name => <<"session.discarded">>},
-                #{name => <<"session.takenover">>},
-                #{name => <<"session.terminated">>},
-                #{name => <<"message.publish">>},
-                #{name => <<"message.delivered">>},
-                #{name => <<"message.acked">>},
-                #{name => <<"message.dropped">>}
-            ]
-        },
-        Md}.
+    %% io:format("fun: ~p, req: ~0p~n", [?FUNCTION_NAME, Req]),
+    HooksClient =
+        [
+            #{name => <<"client.connect">>},
+            #{name => <<"client.connack">>},
+            #{name => <<"client.connected">>},
+            #{name => <<"client.disconnected">>},
+            #{name => <<"client.authenticate">>},
+            #{name => <<"client.authorize">>},
+            #{name => <<"client.subscribe">>},
+            #{name => <<"client.unsubscribe">>}
+        ],
+    HooksSession =
+        [
+            #{name => <<"session.created">>},
+            #{name => <<"session.subscribed">>},
+            #{name => <<"session.unsubscribed">>},
+            #{name => <<"session.resumed">>},
+            #{name => <<"session.discarded">>},
+            #{name => <<"session.takenover">>},
+            #{name => <<"session.terminated">>}
+        ],
+    HooksMessage =
+        [
+            #{name => <<"message.publish">>},
+            #{name => <<"message.delivered">>},
+            #{name => <<"message.acked">>},
+            #{name => <<"message.dropped">>}
+        ],
+    case Name of
+        ?DEFAULT_CLUSTER_NAME ->
+            {ok, #{hooks => HooksClient ++ HooksSession ++ HooksMessage}, Md};
+        ?OTHER_CLUSTER_NAME_BIN ->
+            {ok, #{hooks => HooksClient}, Md}
+    end.
 -spec on_provider_unloaded(emqx_exhook_pb:provider_unloaded_request(), grpc:metadata()) ->
     {ok, emqx_exhook_pb:empty_success(), grpc:metadata()}
     | {error, grpc_cowboy_h:error_response()}.

+ 96 - 57
apps/emqx_exhook/test/props/prop_exhook_hooks.erl

@@ -53,6 +53,8 @@
         ?FORALL(Vars, Types, Exprs)
     )
 ).
+-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
+-define(DEFAULT_CLUSTER_NAME_BIN, <<"emqxcl">>).
 
 %%--------------------------------------------------------------------
 %% Properties
@@ -60,15 +62,16 @@
 
 prop_client_connect() ->
     ?ALL(
-        {ConnInfo, ConnProps},
-        {conninfo(), conn_properties()},
+        {ConnInfo, ConnProps, Meta},
+        {conninfo(), conn_properties(), request_meta()},
         begin
             ok = emqx_hooks:run('client.connect', [ConnInfo, ConnProps]),
             {'on_client_connect', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
                 #{
                     props => properties(ConnProps),
-                    conninfo => from_conninfo(ConnInfo)
+                    conninfo => from_conninfo(ConnInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -77,8 +80,8 @@ prop_client_connect() ->
 
 prop_client_connack() ->
     ?ALL(
-        {ConnInfo, Rc, AckProps},
-        {conninfo(), connack_return_code(), ack_properties()},
+        {ConnInfo, Rc, AckProps, Meta},
+        {conninfo(), connack_return_code(), ack_properties(), request_meta()},
         begin
             ok = emqx_hooks:run('client.connack', [ConnInfo, Rc, AckProps]),
             {'on_client_connack', Resp} = emqx_exhook_demo_svr:take(),
@@ -86,7 +89,8 @@ prop_client_connack() ->
                 #{
                     props => properties(AckProps),
                     result_code => atom_to_binary(Rc, utf8),
-                    conninfo => from_conninfo(ConnInfo)
+                    conninfo => from_conninfo(ConnInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -95,8 +99,8 @@ prop_client_connack() ->
 
 prop_client_authenticate() ->
     ?ALL(
-        {ClientInfo0, AuthResult},
-        {clientinfo(), authresult()},
+        {ClientInfo0, AuthResult, Meta},
+        {clientinfo(), authresult(), request_meta()},
         begin
             ClientInfo = inject_magic_into(username, ClientInfo0),
             OutAuthResult = emqx_hooks:run_fold('client.authenticate', [ClientInfo], AuthResult),
@@ -120,7 +124,8 @@ prop_client_authenticate() ->
             Expected =
                 #{
                     result => authresult_to_bool(AuthResult),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -129,8 +134,8 @@ prop_client_authenticate() ->
 
 prop_client_authorize() ->
     ?ALL(
-        {ClientInfo0, PubSub, Topic, Result},
-        {clientinfo(), oneof([publish, subscribe]), topic(), oneof([allow, deny])},
+        {ClientInfo0, PubSub, Topic, Result, Meta},
+        {clientinfo(), oneof([publish, subscribe]), topic(), oneof([allow, deny]), request_meta()},
         begin
             ClientInfo = inject_magic_into(username, ClientInfo0),
             OutResult = emqx_hooks:run_fold(
@@ -153,7 +158,8 @@ prop_client_authorize() ->
                     result => aclresult_to_bool(Result),
                     type => pubsub_to_enum(PubSub),
                     topic => Topic,
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -162,13 +168,16 @@ prop_client_authorize() ->
 
 prop_client_connected() ->
     ?ALL(
-        {ClientInfo, ConnInfo},
-        {clientinfo(), conninfo()},
+        {ClientInfo, ConnInfo, Meta},
+        {clientinfo(), conninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('client.connected', [ClientInfo, ConnInfo]),
             {'on_client_connected', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
-                #{clientinfo => from_clientinfo(ClientInfo)},
+                #{
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
+                },
             ?assertEqual(Expected, Resp),
             true
         end
@@ -176,15 +185,16 @@ prop_client_connected() ->
 
 prop_client_disconnected() ->
     ?ALL(
-        {ClientInfo, Reason, ConnInfo},
-        {clientinfo(), shutdown_reason(), conninfo()},
+        {ClientInfo, Reason, ConnInfo, Meta},
+        {clientinfo(), shutdown_reason(), conninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('client.disconnected', [ClientInfo, Reason, ConnInfo]),
             {'on_client_disconnected', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
                 #{
                     reason => stringfy(Reason),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -193,8 +203,8 @@ prop_client_disconnected() ->
 
 prop_client_subscribe() ->
     ?ALL(
-        {ClientInfo, SubProps, TopicTab},
-        {clientinfo(), sub_properties(), topictab()},
+        {ClientInfo, SubProps, TopicTab, Meta},
+        {clientinfo(), sub_properties(), topictab(), request_meta()},
         begin
             ok = emqx_hooks:run('client.subscribe', [ClientInfo, SubProps, TopicTab]),
             {'on_client_subscribe', Resp} = emqx_exhook_demo_svr:take(),
@@ -202,7 +212,8 @@ prop_client_subscribe() ->
                 #{
                     props => properties(SubProps),
                     topic_filters => topicfilters(TopicTab),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -211,8 +222,8 @@ prop_client_subscribe() ->
 
 prop_client_unsubscribe() ->
     ?ALL(
-        {ClientInfo, UnSubProps, TopicTab},
-        {clientinfo(), unsub_properties(), topictab()},
+        {ClientInfo, UnSubProps, TopicTab, Meta},
+        {clientinfo(), unsub_properties(), topictab(), request_meta()},
         begin
             ok = emqx_hooks:run('client.unsubscribe', [ClientInfo, UnSubProps, TopicTab]),
             {'on_client_unsubscribe', Resp} = emqx_exhook_demo_svr:take(),
@@ -220,7 +231,8 @@ prop_client_unsubscribe() ->
                 #{
                     props => properties(UnSubProps),
                     topic_filters => topicfilters(TopicTab),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -229,13 +241,16 @@ prop_client_unsubscribe() ->
 
 prop_session_created() ->
     ?ALL(
-        {ClientInfo, SessInfo},
-        {clientinfo(), sessioninfo()},
+        {ClientInfo, SessInfo, Meta},
+        {clientinfo(), sessioninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('session.created', [ClientInfo, SessInfo]),
             {'on_session_created', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
-                #{clientinfo => from_clientinfo(ClientInfo)},
+                #{
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
+                },
             ?assertEqual(Expected, Resp),
             true
         end
@@ -243,8 +258,8 @@ prop_session_created() ->
 
 prop_session_subscribed() ->
     ?ALL(
-        {ClientInfo, Topic, SubOpts},
-        {clientinfo(), topic(), subopts()},
+        {ClientInfo, Topic, SubOpts, Meta},
+        {clientinfo(), topic(), subopts(), request_meta()},
         begin
             ok = emqx_hooks:run('session.subscribed', [ClientInfo, Topic, SubOpts]),
             {'on_session_subscribed', Resp} = emqx_exhook_demo_svr:take(),
@@ -252,7 +267,8 @@ prop_session_subscribed() ->
                 #{
                     topic => Topic,
                     subopts => subopts(SubOpts),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -261,15 +277,16 @@ prop_session_subscribed() ->
 
 prop_session_unsubscribed() ->
     ?ALL(
-        {ClientInfo, Topic, SubOpts},
-        {clientinfo(), topic(), subopts()},
+        {ClientInfo, Topic, SubOpts, Meta},
+        {clientinfo(), topic(), subopts(), request_meta()},
         begin
             ok = emqx_hooks:run('session.unsubscribed', [ClientInfo, Topic, SubOpts]),
             {'on_session_unsubscribed', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
                 #{
                     topic => Topic,
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -278,13 +295,16 @@ prop_session_unsubscribed() ->
 
 prop_session_resumed() ->
     ?ALL(
-        {ClientInfo, SessInfo},
-        {clientinfo(), sessioninfo()},
+        {ClientInfo, SessInfo, Meta},
+        {clientinfo(), sessioninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('session.resumed', [ClientInfo, SessInfo]),
             {'on_session_resumed', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
-                #{clientinfo => from_clientinfo(ClientInfo)},
+                #{
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
+                },
             ?assertEqual(Expected, Resp),
             true
         end
@@ -292,13 +312,13 @@ prop_session_resumed() ->
 
 prop_session_discared() ->
     ?ALL(
-        {ClientInfo, SessInfo},
-        {clientinfo(), sessioninfo()},
+        {ClientInfo, SessInfo, Meta},
+        {clientinfo(), sessioninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('session.discarded', [ClientInfo, SessInfo]),
             {'on_session_discarded', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
-                #{clientinfo => from_clientinfo(ClientInfo)},
+                #{clientinfo => from_clientinfo(ClientInfo), meta => Meta},
             ?assertEqual(Expected, Resp),
             true
         end
@@ -306,13 +326,13 @@ prop_session_discared() ->
 
 prop_session_takenover() ->
     ?ALL(
-        {ClientInfo, SessInfo},
-        {clientinfo(), sessioninfo()},
+        {ClientInfo, SessInfo, Meta},
+        {clientinfo(), sessioninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('session.takenover', [ClientInfo, SessInfo]),
             {'on_session_takenover', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
-                #{clientinfo => from_clientinfo(ClientInfo)},
+                #{clientinfo => from_clientinfo(ClientInfo), meta => Meta},
             ?assertEqual(Expected, Resp),
             true
         end
@@ -320,15 +340,16 @@ prop_session_takenover() ->
 
 prop_session_terminated() ->
     ?ALL(
-        {ClientInfo, Reason, SessInfo},
-        {clientinfo(), shutdown_reason(), sessioninfo()},
+        {ClientInfo, Reason, SessInfo, Meta},
+        {clientinfo(), shutdown_reason(), sessioninfo(), request_meta()},
         begin
             ok = emqx_hooks:run('session.terminated', [ClientInfo, Reason, SessInfo]),
             {'on_session_terminated', Resp} = emqx_exhook_demo_svr:take(),
             Expected =
                 #{
                     reason => stringfy(Reason),
-                    clientinfo => from_clientinfo(ClientInfo)
+                    clientinfo => from_clientinfo(ClientInfo),
+                    meta => Meta
                 },
             ?assertEqual(Expected, Resp),
             true
@@ -337,8 +358,8 @@ prop_session_terminated() ->
 
 prop_message_publish() ->
     ?ALL(
-        Msg0,
-        message(),
+        {Msg0, Meta},
+        {message(), request_meta()},
         begin
             Msg = emqx_message:from_map(
                 inject_magic_into(from, emqx_message:to_map(Msg0))
@@ -381,7 +402,10 @@ prop_message_publish() ->
 
                     {'on_message_publish', Resp} = emqx_exhook_demo_svr:take(),
                     Expected =
-                        #{message => from_message(Msg)},
+                        #{
+                            message => from_message(Msg),
+                            meta => Meta
+                        },
                     ?assertEqual(Expected, Resp)
             end,
             true
@@ -390,8 +414,8 @@ prop_message_publish() ->
 
 prop_message_dropped() ->
     ?ALL(
-        {Msg, By, Reason},
-        {message(), hardcoded, shutdown_reason()},
+        {Msg, By, Reason, Meta},
+        {message(), hardcoded, shutdown_reason(), request_meta()},
         begin
             ok = emqx_hooks:run('message.dropped', [Msg, By, Reason]),
             case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
@@ -402,7 +426,8 @@ prop_message_dropped() ->
                     Expected =
                         #{
                             reason => stringfy(Reason),
-                            message => from_message(Msg)
+                            message => from_message(Msg),
+                            meta => Meta
                         },
                     ?assertEqual(Expected, Resp)
             end,
@@ -412,8 +437,8 @@ prop_message_dropped() ->
 
 prop_message_delivered() ->
     ?ALL(
-        {ClientInfo, Msg},
-        {clientinfo(), message()},
+        {ClientInfo, Msg, Meta},
+        {clientinfo(), message(), request_meta()},
         begin
             ok = emqx_hooks:run('message.delivered', [ClientInfo, Msg]),
             case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
@@ -424,7 +449,8 @@ prop_message_delivered() ->
                     Expected =
                         #{
                             clientinfo => from_clientinfo(ClientInfo),
-                            message => from_message(Msg)
+                            message => from_message(Msg),
+                            meta => Meta
                         },
                     ?assertEqual(Expected, Resp)
             end,
@@ -434,8 +460,8 @@ prop_message_delivered() ->
 
 prop_message_acked() ->
     ?ALL(
-        {ClientInfo, Msg},
-        {clientinfo(), message()},
+        {ClientInfo, Msg, Meta},
+        {clientinfo(), message(), request_meta()},
         begin
             ok = emqx_hooks:run('message.acked', [ClientInfo, Msg]),
             case emqx_topic:match(emqx_message:topic(Msg), <<"$SYS/#">>) of
@@ -446,7 +472,8 @@ prop_message_acked() ->
                     Expected =
                         #{
                             clientinfo => from_clientinfo(ClientInfo),
-                            message => from_message(Msg)
+                            message => from_message(Msg),
+                            meta => Meta
                         },
                     ?assertEqual(Expected, Resp)
             end,
@@ -500,6 +527,8 @@ stringfy(Term) when is_integer(Term) ->
     integer_to_binary(Term);
 stringfy(Term) when is_atom(Term) ->
     atom_to_binary(Term, utf8);
+stringfy(Term) when is_list(Term) ->
+    list_to_binary(Term);
 stringfy(Term) ->
     unicode:characters_to_binary((io_lib:format("~0p", [Term]))).
 
@@ -569,6 +598,8 @@ from_message(Msg) ->
 
 do_setup() ->
     logger:set_primary_config(#{level => warning}),
+    ok = ekka:start(),
+    application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
     _ = emqx_exhook_demo_svr:start(),
     ok = emqx_config:init_load(emqx_exhook_schema, ?CONF_DEFAULT),
     emqx_common_test_helpers:start_apps([emqx_exhook]),
@@ -623,3 +654,11 @@ inject_magic_into(Key, Object) ->
 castspell() ->
     L = [<<"baduser">>, <<"gooduser">>, <<"normaluser">>, muggles],
     lists:nth(rand:uniform(length(L)), L).
+
+request_meta() ->
+    #{
+        node => nodestr(),
+        version => stringfy(emqx_sys:version()),
+        sysdescr => stringfy(emqx_sys:sysdescr()),
+        cluster_name => ?DEFAULT_CLUSTER_NAME_BIN
+    }.