Skip to content

Commit 337a47e

Browse files
Merge pull request #9254 from rabbitmq/routing-suite
routing_SUITE: extract topic test from unit_access_control_SUITE
2 parents 82fcaf3 + 6b4cfe8 commit 337a47e

File tree

4 files changed

+222
-143
lines changed

4 files changed

+222
-143
lines changed

deps/rabbit/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,11 @@ rabbitmq_integration_suite(
11641164
],
11651165
)
11661166

1167+
rabbitmq_integration_suite(
1168+
name = "routing_SUITE",
1169+
size = "large",
1170+
)
1171+
11671172
assert_suites()
11681173

11691174
filegroup(

deps/rabbit/app.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,3 +2028,12 @@ def test_suite_beam_files(name = "test_suite_beam_files"):
20282028
erlc_opts = "//:test_erlc_opts",
20292029
deps = ["//deps/amqp10_common:erlang_app", "//deps/rabbit_common:erlang_app"],
20302030
)
2031+
erlang_bytecode(
2032+
name = "routing_SUITE_beam_files",
2033+
testonly = True,
2034+
srcs = ["test/routing_SUITE.erl"],
2035+
outs = ["test/routing_SUITE.beam"],
2036+
app_name = "rabbit",
2037+
erlc_opts = "//:test_erlc_opts",
2038+
deps = ["//deps/amqp_client:erlang_app"],
2039+
)

deps/rabbit/test/routing_SUITE.erl

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
%% This Source Code Form is subject to the terms of the Mozilla Public
2+
%% License, v. 2.0. If a copy of the MPL was not distributed with this
3+
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
%%
5+
%% Copyright (c) 2011-2023 VMware, Inc. or its affiliates. All rights reserved.
6+
%%
7+
8+
-module(routing_SUITE).
9+
10+
-include_lib("eunit/include/eunit.hrl").
11+
-include_lib("amqp_client/include/amqp_client.hrl").
12+
-include_lib("common_test/include/ct.hrl").
13+
14+
-compile([nowarn_export_all, export_all]).
15+
-compile(export_all).
16+
17+
-define(VHOST, <<"/">>).
18+
-define(USER, <<"user">>).
19+
20+
all() ->
21+
[
22+
{group, mnesia_store}
23+
].
24+
25+
suite() ->
26+
[{timetrap, {minutes, 5}}].
27+
28+
groups() ->
29+
[
30+
{mnesia_store, [], all_tests()}
31+
].
32+
33+
all_tests() ->
34+
[
35+
topic
36+
].
37+
38+
%% -------------------------------------------------------------------
39+
%% Test suite setup/teardown.
40+
%% -------------------------------------------------------------------
41+
42+
init_per_suite(Config) ->
43+
rabbit_ct_helpers:log_environment(),
44+
rabbit_ct_helpers:run_setup_steps(Config).
45+
46+
end_per_suite(Config) ->
47+
rabbit_ct_helpers:run_teardown_steps(Config).
48+
49+
init_per_group(mnesia_store = Group, Config) ->
50+
Config1 = rabbit_ct_helpers:set_config(Config, [
51+
{rmq_nodename_suffix, Group},
52+
{rmq_nodes_count, 1}
53+
]),
54+
rabbit_ct_helpers:run_steps(Config1,
55+
rabbit_ct_broker_helpers:setup_steps() ++
56+
rabbit_ct_client_helpers:setup_steps()).
57+
58+
end_per_group(_Group, Config) ->
59+
rabbit_ct_helpers:run_steps(Config,
60+
rabbit_ct_client_helpers:teardown_steps() ++
61+
rabbit_ct_broker_helpers:teardown_steps()).
62+
63+
init_per_testcase(Testcase, Config) ->
64+
rabbit_ct_helpers:testcase_started(Config, Testcase).
65+
66+
end_per_testcase(Testcase, Config) ->
67+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_db_binding, clear, []),
68+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_db_exchange, clear, []),
69+
rabbit_ct_helpers:testcase_finished(Config, Testcase).
70+
71+
%% ---------------------------------------------------------------------------
72+
%% Test Cases
73+
%% ---------------------------------------------------------------------------
74+
75+
topic(Config) ->
76+
passed = rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, topic1, [Config]).
77+
78+
topic1(_Config) ->
79+
XName = rabbit_misc:r(?VHOST, exchange, <<"topic_matching-exchange">>),
80+
X = rabbit_exchange:declare(
81+
XName, topic, _Durable = true, _AutoDelete = false,
82+
_Internal = false, _Args = [], ?USER),
83+
84+
%% add some bindings
85+
Bindings = [#binding{source = XName,
86+
key = list_to_binary(Key),
87+
destination = rabbit_misc:r(
88+
?VHOST, queue, list_to_binary(Q)),
89+
args = Args} ||
90+
{Key, Q, Args} <- [{"a.b.c", "t1", []},
91+
{"a.*.c", "t2", []},
92+
{"a.#.b", "t3", []},
93+
{"a.b.b.c", "t4", []},
94+
{"#", "t5", []},
95+
{"#.#", "t6", []},
96+
{"#.b", "t7", []},
97+
{"*.*", "t8", []},
98+
{"a.*", "t9", []},
99+
{"*.b.c", "t10", []},
100+
{"a.#", "t11", []},
101+
{"a.#.#", "t12", []},
102+
{"b.b.c", "t13", []},
103+
{"a.b.b", "t14", []},
104+
{"a.b", "t15", []},
105+
{"b.c", "t16", []},
106+
{"", "t17", []},
107+
{"*.*.*", "t18", []},
108+
{"vodka.martini", "t19", []},
109+
{"a.b.c", "t20", []},
110+
{"*.#", "t21", []},
111+
{"#.*.#", "t22", []},
112+
{"*.#.#", "t23", []},
113+
{"#.#.#", "t24", []},
114+
{"*", "t25", []},
115+
{"#.b.#", "t26", []},
116+
{"args-test", "t27",
117+
[{<<"foo">>, longstr, <<"bar">>}]},
118+
{"args-test", "t27", %% Note aliasing
119+
[{<<"foo">>, longstr, <<"baz">>}]}]],
120+
[ok = create_binding(Binding) || Binding <- Bindings],
121+
122+
test_topic_expect_match(
123+
X, [{"a.b.c", ["t1", "t2", "t5", "t6", "t10", "t11", "t12",
124+
"t18", "t20", "t21", "t22", "t23", "t24",
125+
"t26"]},
126+
{"a.b", ["t3", "t5", "t6", "t7", "t8", "t9", "t11",
127+
"t12", "t15", "t21", "t22", "t23", "t24",
128+
"t26"]},
129+
{"a.b.b", ["t3", "t5", "t6", "t7", "t11", "t12", "t14",
130+
"t18", "t21", "t22", "t23", "t24", "t26"]},
131+
{"", ["t5", "t6", "t17", "t24"]},
132+
{"b.c.c", ["t5", "t6", "t18", "t21", "t22", "t23",
133+
"t24", "t26"]},
134+
{"a.a.a.a.a", ["t5", "t6", "t11", "t12", "t21", "t22",
135+
"t23", "t24"]},
136+
{"vodka.gin", ["t5", "t6", "t8", "t21", "t22", "t23",
137+
"t24"]},
138+
{"vodka.martini", ["t5", "t6", "t8", "t19", "t21", "t22", "t23",
139+
"t24"]},
140+
{"b.b.c", ["t5", "t6", "t10", "t13", "t18", "t21",
141+
"t22", "t23", "t24", "t26"]},
142+
{"nothing.here.at.all", ["t5", "t6", "t21", "t22", "t23", "t24"]},
143+
{"oneword", ["t5", "t6", "t21", "t22", "t23", "t24",
144+
"t25"]},
145+
{"args-test", ["t5", "t6", "t21", "t22", "t23", "t24",
146+
"t25", "t27"]}]),
147+
148+
%% remove some bindings
149+
RemovedBindings = [lists:nth(N, Bindings) || N <- [1, 5, 11, 19, 21, 28]],
150+
[delete_binding(Binding) || Binding <- RemovedBindings],
151+
152+
%% test some matches
153+
test_topic_expect_match(
154+
X,
155+
[{"a.b.c", ["t2", "t6", "t10", "t12", "t18", "t20", "t22",
156+
"t23", "t24", "t26"]},
157+
{"a.b", ["t3", "t6", "t7", "t8", "t9", "t12", "t15",
158+
"t22", "t23", "t24", "t26"]},
159+
{"a.b.b", ["t3", "t6", "t7", "t12", "t14", "t18", "t22",
160+
"t23", "t24", "t26"]},
161+
{"", ["t6", "t17", "t24"]},
162+
{"b.c.c", ["t6", "t18", "t22", "t23", "t24", "t26"]},
163+
{"a.a.a.a.a", ["t6", "t12", "t22", "t23", "t24"]},
164+
{"vodka.gin", ["t6", "t8", "t22", "t23", "t24"]},
165+
{"vodka.martini", ["t6", "t8", "t22", "t23", "t24"]},
166+
{"b.b.c", ["t6", "t10", "t13", "t18", "t22", "t23",
167+
"t24", "t26"]},
168+
{"nothing.here.at.all", ["t6", "t22", "t23", "t24"]},
169+
{"oneword", ["t6", "t22", "t23", "t24", "t25"]},
170+
{"args-test", ["t6", "t22", "t23", "t24", "t25", "t27"]}]),
171+
172+
%% remove the entire exchange
173+
rabbit_exchange:delete(XName, _IfUnused = false, ?USER),
174+
%% none should match now
175+
test_topic_expect_match(X, [{"a.b.c", []}, {"b.b.c", []}, {"", []}]),
176+
passed.
177+
178+
%% Internal functions.
179+
180+
%% Create a binding, creating the queue if it does not already exist.
181+
create_binding(#binding{destination = QName} = Binding) ->
182+
case rabbit_amqqueue:declare(QName, true, false, [], self(), ?USER) of
183+
{new, _Q} ->
184+
ok;
185+
{existing, _Q} ->
186+
ok
187+
end,
188+
ok = rabbit_binding:add(Binding, ?USER).
189+
190+
delete_binding(Binding) ->
191+
ok = rabbit_binding:remove(Binding, ?USER).
192+
193+
test_topic_expect_match(X, List) ->
194+
lists:foreach(
195+
fun ({Key, Expected}) ->
196+
BinKey = list_to_binary(Key),
197+
Message = rabbit_basic:message(X#exchange.name, BinKey,
198+
#'P_basic'{}, <<>>),
199+
Msg = mc_amqpl:message(X#exchange.name,
200+
BinKey,
201+
Message#basic_message.content),
202+
Res = rabbit_exchange_type_topic:route(X, Msg),
203+
ExpectedRes = [rabbit_misc:r(?VHOST, queue, list_to_binary(Q)) ||
204+
Q <- Expected],
205+
?assertEqual(
206+
lists:usort(ExpectedRes), lists:usort(Res),
207+
lists:flatten(io_lib:format("Routing key: ~p", [BinKey])))
208+
end, List).

deps/rabbit/test/unit_access_control_SUITE.erl

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ groups() ->
3131
login_of_passwordless_user,
3232
set_tags_for_passwordless_user,
3333
change_password,
34-
topic_matching,
3534
auth_backend_internal_expand_topic_permission,
3635
rabbit_direct_extract_extra_auth_props
3736
]}
@@ -296,145 +295,3 @@ test_unsupported_connection_refusal(H, P, Header) ->
296295
{ok, <<"AMQP",0,0,9,1>>} = gen_tcp:recv(C, 8, 100),
297296
ok = gen_tcp:close(C),
298297
passed.
299-
300-
301-
%% -------------------------------------------------------------------
302-
%% Topic matching.
303-
%% -------------------------------------------------------------------
304-
305-
topic_matching(Config) ->
306-
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
307-
?MODULE, topic_matching1, [Config]).
308-
309-
topic_matching1(_Config) ->
310-
XName = #resource{virtual_host = <<"/">>,
311-
kind = exchange,
312-
name = <<"topic_matching-exchange">>},
313-
X0 = #exchange{name = XName, type = topic, durable = false,
314-
auto_delete = false, arguments = []},
315-
X = rabbit_exchange_decorator:set(X0),
316-
%% create
317-
rabbit_exchange_type_topic:validate(X),
318-
exchange_op_callback(X, create, []),
319-
320-
%% add some bindings
321-
Bindings = [#binding{source = XName,
322-
key = list_to_binary(Key),
323-
destination = #resource{virtual_host = <<"/">>,
324-
kind = queue,
325-
name = list_to_binary(Q)},
326-
args = Args} ||
327-
{Key, Q, Args} <- [{"a.b.c", "t1", []},
328-
{"a.*.c", "t2", []},
329-
{"a.#.b", "t3", []},
330-
{"a.b.b.c", "t4", []},
331-
{"#", "t5", []},
332-
{"#.#", "t6", []},
333-
{"#.b", "t7", []},
334-
{"*.*", "t8", []},
335-
{"a.*", "t9", []},
336-
{"*.b.c", "t10", []},
337-
{"a.#", "t11", []},
338-
{"a.#.#", "t12", []},
339-
{"b.b.c", "t13", []},
340-
{"a.b.b", "t14", []},
341-
{"a.b", "t15", []},
342-
{"b.c", "t16", []},
343-
{"", "t17", []},
344-
{"*.*.*", "t18", []},
345-
{"vodka.martini", "t19", []},
346-
{"a.b.c", "t20", []},
347-
{"*.#", "t21", []},
348-
{"#.*.#", "t22", []},
349-
{"*.#.#", "t23", []},
350-
{"#.#.#", "t24", []},
351-
{"*", "t25", []},
352-
{"#.b.#", "t26", []},
353-
{"args-test", "t27",
354-
[{<<"foo">>, longstr, <<"bar">>}]},
355-
{"args-test", "t27", %% Note aliasing
356-
[{<<"foo">>, longstr, <<"baz">>}]}]],
357-
lists:foreach(fun (B) -> exchange_op_callback(X, add_binding, [B]) end,
358-
Bindings),
359-
360-
%% test some matches
361-
test_topic_expect_match(
362-
X, [{"a.b.c", ["t1", "t2", "t5", "t6", "t10", "t11", "t12",
363-
"t18", "t20", "t21", "t22", "t23", "t24",
364-
"t26"]},
365-
{"a.b", ["t3", "t5", "t6", "t7", "t8", "t9", "t11",
366-
"t12", "t15", "t21", "t22", "t23", "t24",
367-
"t26"]},
368-
{"a.b.b", ["t3", "t5", "t6", "t7", "t11", "t12", "t14",
369-
"t18", "t21", "t22", "t23", "t24", "t26"]},
370-
{"", ["t5", "t6", "t17", "t24"]},
371-
{"b.c.c", ["t5", "t6", "t18", "t21", "t22", "t23",
372-
"t24", "t26"]},
373-
{"a.a.a.a.a", ["t5", "t6", "t11", "t12", "t21", "t22",
374-
"t23", "t24"]},
375-
{"vodka.gin", ["t5", "t6", "t8", "t21", "t22", "t23",
376-
"t24"]},
377-
{"vodka.martini", ["t5", "t6", "t8", "t19", "t21", "t22", "t23",
378-
"t24"]},
379-
{"b.b.c", ["t5", "t6", "t10", "t13", "t18", "t21",
380-
"t22", "t23", "t24", "t26"]},
381-
{"nothing.here.at.all", ["t5", "t6", "t21", "t22", "t23", "t24"]},
382-
{"oneword", ["t5", "t6", "t21", "t22", "t23", "t24",
383-
"t25"]},
384-
{"args-test", ["t5", "t6", "t21", "t22", "t23", "t24",
385-
"t25", "t27"]}]),
386-
%% remove some bindings
387-
RemovedBindings = [lists:nth(1, Bindings), lists:nth(5, Bindings),
388-
lists:nth(11, Bindings), lists:nth(19, Bindings),
389-
lists:nth(21, Bindings), lists:nth(28, Bindings)],
390-
exchange_op_callback(X, remove_bindings, [RemovedBindings]),
391-
_RemainingBindings = ordsets:to_list(
392-
ordsets:subtract(ordsets:from_list(Bindings),
393-
ordsets:from_list(RemovedBindings))),
394-
395-
%% test some matches
396-
test_topic_expect_match(
397-
X,
398-
[{"a.b.c", ["t2", "t6", "t10", "t12", "t18", "t20", "t22",
399-
"t23", "t24", "t26"]},
400-
{"a.b", ["t3", "t6", "t7", "t8", "t9", "t12", "t15",
401-
"t22", "t23", "t24", "t26"]},
402-
{"a.b.b", ["t3", "t6", "t7", "t12", "t14", "t18", "t22",
403-
"t23", "t24", "t26"]},
404-
{"", ["t6", "t17", "t24"]},
405-
{"b.c.c", ["t6", "t18", "t22", "t23", "t24", "t26"]},
406-
{"a.a.a.a.a", ["t6", "t12", "t22", "t23", "t24"]},
407-
{"vodka.gin", ["t6", "t8", "t22", "t23", "t24"]},
408-
{"vodka.martini", ["t6", "t8", "t22", "t23", "t24"]},
409-
{"b.b.c", ["t6", "t10", "t13", "t18", "t22", "t23",
410-
"t24", "t26"]},
411-
{"nothing.here.at.all", ["t6", "t22", "t23", "t24"]},
412-
{"oneword", ["t6", "t22", "t23", "t24", "t25"]},
413-
{"args-test", ["t6", "t22", "t23", "t24", "t25", "t27"]}]),
414-
415-
%% remove the entire exchange
416-
exchange_op_callback(X, delete, []),
417-
%% none should match now
418-
test_topic_expect_match(X, [{"a.b.c", []}, {"b.b.c", []}, {"", []}]),
419-
passed.
420-
421-
exchange_op_callback(X, Fun, Args) ->
422-
rabbit_exchange:callback(X, Fun, none, [X] ++ Args).
423-
424-
test_topic_expect_match(X, List) ->
425-
lists:foreach(
426-
fun ({Key, Expected}) ->
427-
BinKey = list_to_binary(Key),
428-
Message = rabbit_basic:message(X#exchange.name, BinKey,
429-
#'P_basic'{}, <<>>),
430-
Msg = mc_amqpl:message(X#exchange.name,
431-
BinKey,
432-
Message#basic_message.content),
433-
Res = rabbit_exchange_type_topic:route(X, Msg),
434-
ExpectedRes = lists:map(
435-
fun (Q) -> #resource{virtual_host = <<"/">>,
436-
kind = queue,
437-
name = list_to_binary(Q)}
438-
end, Expected),
439-
true = (lists:usort(ExpectedRes) =:= lists:usort(Res))
440-
end, List).

0 commit comments

Comments
 (0)