Explorar o código

test(rule): add tests to ensure the rules ordering

JianBo He %!s(int64=2) %!d(string=hai) anos
pai
achega
dcf4819c04

+ 6 - 2
apps/emqx_rule_engine/src/emqx_rule_index.erl

@@ -89,9 +89,13 @@ matches(Topic, Tab, Opts) ->
             [] -> []
         end,
     Matches = matches(Words, RPrefix, AccIn, Tab),
+    %% return rules ordered by Rule ID
     case Matches of
-        #{} -> maps:values(Matches);
-        _ -> Matches
+        #{} ->
+            maps:values(Matches);
+        _ ->
+            F = fun({_, {ID1}}, {_, {ID2}}) -> ID1 < ID2 end,
+            lists:sort(F, Matches)
     end.
 
 matches(Words, RPrefix, Acc, Tab) ->

+ 40 - 0
apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl

@@ -58,6 +58,7 @@ groups() ->
             t_create_existing_rule,
             t_get_rules_for_topic,
             t_get_rules_for_topic_2,
+            t_get_rules_for_topic_3,
             t_get_rules_with_same_event,
             t_get_rule_ids_by_action,
             t_ensure_action_removed
@@ -399,6 +400,45 @@ t_get_rules_for_topic_2(_Config) ->
     ]),
     ok.
 
+t_get_rules_for_topic_3(_Config) ->
+    ok = create_rules(
+        [
+            make_simple_rule(<<"rule-debug-5">>, <<"select * from \"simple/#\"">>),
+            make_simple_rule(<<"rule-debug-4">>, <<"select * from \"simple/+\"">>),
+            make_simple_rule(<<"rule-debug-3">>, <<"select * from \"simple/+/1\"">>),
+            make_simple_rule(<<"rule-debug-2">>, <<"select * from \"simple/1\"">>),
+            make_simple_rule(
+                <<"rule-debug-1">>,
+                <<"select * from \"simple/2\", \"simple/+\", \"simple/3\"">>
+            )
+        ]
+    ),
+    Rules1 = get_rules_for_topic_in_e510_impl(<<"simple/1">>),
+    Rules2 = emqx_rule_engine:get_rules_for_topic(<<"simple/1">>),
+    %% assert, ensure the order of rules is the same as e5.1.0
+    ?assertEqual(Rules1, Rules2),
+    ?assertEqual(
+        [<<"rule-debug-1">>, <<"rule-debug-2">>, <<"rule-debug-4">>, <<"rule-debug-5">>],
+        [Id || #{id := Id} <- Rules1]
+    ),
+
+    ok = delete_rules_by_ids([
+        <<"rule-debug-1">>,
+        <<"rule-debug-2">>,
+        <<"rule-debug-3">>,
+        <<"rule-debug-4">>,
+        <<"rule-debug-5">>,
+        <<"rule-debug-6">>
+    ]),
+    ok.
+
+get_rules_for_topic_in_e510_impl(Topic) ->
+    [
+        Rule
+     || Rule = #{from := From} <- emqx_rule_engine:get_rules(),
+        emqx_topic:match_any(Topic, From)
+    ].
+
 t_get_rules_with_same_event(_Config) ->
     PubT = <<"simple/1">>,
     PubN = length(emqx_rule_engine:get_rules_with_same_event(PubT)),

+ 10 - 0
apps/emqx_rule_engine/test/emqx_rule_index_SUITE.erl

@@ -152,6 +152,16 @@ t_match_unique(_) ->
         [id(M) || M <- emqx_rule_index:matches(<<"a/b/c">>, Tab, [unique])]
     ).
 
+t_match_ordering(_) ->
+    Tab = new(),
+    emqx_rule_index:insert(<<"a/b/+">>, t_match_id2, <<>>, Tab),
+    emqx_rule_index:insert(<<"a/b/c">>, t_match_id1, <<>>, Tab),
+    emqx_rule_index:insert(<<"a/b/#">>, t_match_id3, <<>>, Tab),
+    Ids1 = [id(M) || M <- emqx_rule_index:matches(<<"a/b/c">>, Tab, [])],
+    Ids2 = [id(M) || M <- emqx_rule_index:matches(<<"a/b/c">>, Tab, [unique])],
+    ?assertEqual(Ids1, Ids2),
+    ?assertEqual([t_match_id1, t_match_id2, t_match_id3], Ids1).
+
 new() ->
     ets:new(?MODULE, [public, ordered_set, {write_concurrency, true}]).