emqx_rule_engine_api_SUITE.erl 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. -module(emqx_rule_engine_api_SUITE).
  2. -compile(nowarn_export_all).
  3. -compile(export_all).
  4. -include_lib("eunit/include/eunit.hrl").
  5. -include_lib("common_test/include/ct.hrl").
  6. -define(CONF_DEFAULT, <<"rule_engine {rules {}}">>).
  7. all() ->
  8. emqx_common_test_helpers:all(?MODULE).
  9. init_per_suite(Config) ->
  10. application:load(emqx_conf),
  11. ok = emqx_common_test_helpers:load_config(emqx_rule_engine_schema, ?CONF_DEFAULT),
  12. ok = emqx_common_test_helpers:start_apps([emqx_conf, emqx_rule_engine]),
  13. Config.
  14. end_per_suite(_Config) ->
  15. emqx_common_test_helpers:stop_apps([emqx_conf, emqx_rule_engine]),
  16. ok.
  17. init_per_testcase(_, Config) ->
  18. Config.
  19. end_per_testcase(_, _Config) ->
  20. {200, #{data := Rules}} =
  21. emqx_rule_engine_api:'/rules'(get, #{query_string => #{}}),
  22. lists:foreach(
  23. fun(#{id := Id}) ->
  24. emqx_rule_engine_api:'/rules/:id'(
  25. delete,
  26. #{bindings => #{id => Id}}
  27. )
  28. end,
  29. Rules
  30. ).
  31. t_crud_rule_api(_Config) ->
  32. RuleID = <<"my_rule">>,
  33. Params0 = #{
  34. <<"description">> => <<"A simple rule">>,
  35. <<"enable">> => true,
  36. <<"id">> => RuleID,
  37. <<"actions">> => [#{<<"function">> => <<"console">>}],
  38. <<"sql">> => <<"SELECT * from \"t/1\"">>,
  39. <<"name">> => <<"test_rule">>
  40. },
  41. {201, Rule} = emqx_rule_engine_api:'/rules'(post, #{body => Params0}),
  42. %% if we post again with the same params, it return with 400 "rule id already exists"
  43. ?assertMatch(
  44. {400, #{code := _, message := _Message}},
  45. emqx_rule_engine_api:'/rules'(post, #{body => Params0})
  46. ),
  47. ?assertEqual(RuleID, maps:get(id, Rule)),
  48. {200, #{data := Rules}} = emqx_rule_engine_api:'/rules'(get, #{query_string => #{}}),
  49. ct:pal("RList : ~p", [Rules]),
  50. ?assert(length(Rules) > 0),
  51. {204} = emqx_rule_engine_api:'/rules/:id/metrics/reset'(put, #{
  52. bindings => #{id => RuleID}
  53. }),
  54. {200, Rule1} = emqx_rule_engine_api:'/rules/:id'(get, #{bindings => #{id => RuleID}}),
  55. ct:pal("RShow : ~p", [Rule1]),
  56. ?assertEqual(Rule, Rule1),
  57. {200, Metrics} = emqx_rule_engine_api:'/rules/:id/metrics'(get, #{bindings => #{id => RuleID}}),
  58. ct:pal("RMetrics : ~p", [Metrics]),
  59. ?assertMatch(#{id := RuleID, metrics := _, node_metrics := _}, Metrics),
  60. {200, Rule2} = emqx_rule_engine_api:'/rules/:id'(put, #{
  61. bindings => #{id => RuleID},
  62. body => Params0#{<<"sql">> => <<"select * from \"t/b\"">>}
  63. }),
  64. {200, Rule3} = emqx_rule_engine_api:'/rules/:id'(get, #{bindings => #{id => RuleID}}),
  65. %ct:pal("RShow : ~p", [Rule3]),
  66. ?assertEqual(Rule3, Rule2),
  67. ?assertEqual(<<"select * from \"t/b\"">>, maps:get(sql, Rule3)),
  68. {404, _} = emqx_rule_engine_api:'/rules/:id'(get, #{bindings => #{id => <<"unknown_rule">>}}),
  69. {404, _} = emqx_rule_engine_api:'/rules/:id/metrics'(get, #{
  70. bindings => #{id => <<"unknown_rule">>}
  71. }),
  72. {404, _} = emqx_rule_engine_api:'/rules/:id/metrics/reset'(put, #{
  73. bindings => #{id => <<"unknown_rule">>}
  74. }),
  75. ?assertMatch(
  76. {204},
  77. emqx_rule_engine_api:'/rules/:id'(
  78. delete,
  79. #{bindings => #{id => RuleID}}
  80. )
  81. ),
  82. %ct:pal("Show After Deleted: ~p", [NotFound]),
  83. ?assertMatch(
  84. {404, #{code := _, message := _Message}},
  85. emqx_rule_engine_api:'/rules/:id'(get, #{bindings => #{id => RuleID}})
  86. ),
  87. ?assertMatch(
  88. {400, #{
  89. code := 'BAD_REQUEST',
  90. message := <<"{select_and_transform_error,{error,{decode_json_failed,", _/binary>>
  91. }},
  92. emqx_rule_engine_api:'/rule_test'(post, test_rule_params())
  93. ),
  94. ok.
  95. t_list_rule_api(_Config) ->
  96. AddIds =
  97. lists:map(
  98. fun(Seq0) ->
  99. Seq = integer_to_binary(Seq0),
  100. Params = #{
  101. <<"description">> => <<"A simple rule">>,
  102. <<"enable">> => true,
  103. <<"actions">> => [#{<<"function">> => <<"console">>}],
  104. <<"sql">> => <<"SELECT * from \"t/1\"">>,
  105. <<"name">> => <<"test_rule", Seq/binary>>
  106. },
  107. {201, #{id := Id}} = emqx_rule_engine_api:'/rules'(post, #{body => Params}),
  108. Id
  109. end,
  110. lists:seq(1, 20)
  111. ),
  112. {200, #{data := Rules, meta := #{count := Count}}} =
  113. emqx_rule_engine_api:'/rules'(get, #{query_string => #{}}),
  114. ?assertEqual(20, length(AddIds)),
  115. ?assertEqual(20, length(Rules)),
  116. ?assertEqual(20, Count),
  117. [RuleID | _] = AddIds,
  118. UpdateParams = #{
  119. <<"description">> => <<"中文的描述也能搜索"/utf8>>,
  120. <<"enable">> => false,
  121. <<"actions">> => [#{<<"function">> => <<"console">>}],
  122. <<"sql">> => <<"SELECT * from \"t/1/+\"">>,
  123. <<"name">> => <<"test_rule_update1">>
  124. },
  125. {200, _Rule2} = emqx_rule_engine_api:'/rules/:id'(put, #{
  126. bindings => #{id => RuleID},
  127. body => UpdateParams
  128. }),
  129. QueryStr1 = #{query_string => #{<<"enable">> => false}},
  130. {200, Result1 = #{meta := #{count := Count1}}} = emqx_rule_engine_api:'/rules'(get, QueryStr1),
  131. ?assertEqual(1, Count1),
  132. QueryStr2 = #{query_string => #{<<"like_description">> => <<"也能"/utf8>>}},
  133. {200, Result2} = emqx_rule_engine_api:'/rules'(get, QueryStr2),
  134. ?assertEqual(maps:get(data, Result1), maps:get(data, Result2)),
  135. QueryStr3 = #{query_string => #{<<"from">> => <<"t/1">>}},
  136. {200, #{data := Data3}} = emqx_rule_engine_api:'/rules'(get, QueryStr3),
  137. ?assertEqual(19, length(Data3)),
  138. QueryStr4 = #{query_string => #{<<"like_from">> => <<"t/1/+">>}},
  139. {200, Result4} = emqx_rule_engine_api:'/rules'(get, QueryStr4),
  140. ?assertEqual(maps:get(data, Result1), maps:get(data, Result4)),
  141. QueryStr5 = #{query_string => #{<<"match_from">> => <<"t/+/+">>}},
  142. {200, Result5} = emqx_rule_engine_api:'/rules'(get, QueryStr5),
  143. ?assertEqual(maps:get(data, Result1), maps:get(data, Result5)),
  144. QueryStr6 = #{query_string => #{<<"like_id">> => RuleID}},
  145. {200, Result6} = emqx_rule_engine_api:'/rules'(get, QueryStr6),
  146. ?assertEqual(maps:get(data, Result1), maps:get(data, Result6)),
  147. ok.
  148. test_rule_params() ->
  149. #{
  150. body => #{
  151. <<"context">> =>
  152. #{
  153. <<"clientid">> => <<"c_emqx">>,
  154. <<"event_type">> => <<"message_publish">>,
  155. <<"payload">> => <<"{\"msg\": \"hel">>,
  156. <<"qos">> => 1,
  157. <<"topic">> => <<"t/a">>,
  158. <<"username">> => <<"u_emqx">>
  159. },
  160. <<"sql">> =>
  161. <<"SELECT\n payload.msg\nFROM\n \"t/#\"">>
  162. }
  163. }.