From 5381c667e7a71e7d5c1da59c76fb0ddb31ebb2a5 Mon Sep 17 00:00:00 2001 From: Lois Soto Lopez Date: Thu, 14 Mar 2024 10:41:34 +0100 Subject: [PATCH] Remove unnecessary code and v4 group Discussion #9302 --- deps/rabbitmq_mqtt/test/command_SUITE.erl | 7 + deps/rabbitmq_web_mqtt/test/command_SUITE.erl | 178 ++++++++++++++++++ .../test/rabbit_web_mqtt_test_util.erl | 39 ++++ 3 files changed, 224 insertions(+) create mode 100644 deps/rabbitmq_web_mqtt/test/command_SUITE.erl create mode 100644 deps/rabbitmq_web_mqtt/test/rabbit_web_mqtt_test_util.erl diff --git a/deps/rabbitmq_mqtt/test/command_SUITE.erl b/deps/rabbitmq_mqtt/test/command_SUITE.erl index 07d4a65d62b..68ddbb5caea 100644 --- a/deps/rabbitmq_mqtt/test/command_SUITE.erl +++ b/deps/rabbitmq_mqtt/test/command_SUITE.erl @@ -86,6 +86,13 @@ run(Config) -> %% No connections [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + %% Open a WebMQTT connection, command won't list it + WebMqttConfig = Config#{websocket => true}, + _C0 = connect(<<"simpleWebMqttClient">>, WebMqttConfig, [{ack_timeout, 1}]), + + [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + + %% Open a connection C1 = connect(<<"simpleClient">>, Config, [{ack_timeout, 1}]), timer:sleep(100), diff --git a/deps/rabbitmq_web_mqtt/test/command_SUITE.erl b/deps/rabbitmq_web_mqtt/test/command_SUITE.erl new file mode 100644 index 00000000000..f7f7027788c --- /dev/null +++ b/deps/rabbitmq_web_mqtt/test/command_SUITE.erl @@ -0,0 +1,178 @@ +%% This Source Code Form is subject to the terms of the Mozilla Public +%% License, v. 2.0. If a copy of the MPL was not distributed with this +%% file, You can obtain one at https://mozilla.org/MPL/2.0/. +%% +%% Copyright (c) 2007-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. + + +-module(command_SUITE). +-compile([export_all, nowarn_export_all]). + +-include_lib("eunit/include/eunit.hrl"). +-include_lib("amqp_client/include/amqp_client.hrl"). +-include_lib("rabbitmq_mqtt/include/rabbit_mqtt.hrl"). +-import(util, [connect/3, connect/4]). + +-define(COMMAND, 'Elixir.RabbitMQ.CLI.Ctl.Commands.ListWebMqttConnectionsCommand'). + +all() -> + [ + {group, unit}, + {group, v5} + ]. + +groups() -> + [ + {unit, [], [merge_defaults]}, + {v5, [], [run, + user_property]} + ]. + +suite() -> + [ + {timetrap, {minutes, 10}} + ]. + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + Config1 = rabbit_ct_helpers:set_config(Config, [ + {rmq_nodename_suffix, ?MODULE}, + {rmq_extra_tcp_ports, [tcp_port_mqtt_extra, + tcp_port_mqtt_tls_extra]}, + {rmq_nodes_clustered, true}, + {rmq_nodes_count, 3} + ]), + rabbit_ct_helpers:run_setup_steps(Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()). + +init_per_group(unit, Config) -> + Config; +init_per_group(Group, Config) -> + Config1 = rabbit_ct_helpers:set_config(Config, {mqtt_version, Group}), + util:maybe_skip_v5(Config1). + +end_per_group(_, Config) -> + Config. + +init_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_started(Config, Testcase). + +end_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_finished(Config, Testcase). + +merge_defaults(_Config) -> + {[<<"client_id">>, <<"conn_name">>], #{verbose := false}} = + ?COMMAND:merge_defaults([], #{}), + + {[<<"other_key">>], #{verbose := true}} = + ?COMMAND:merge_defaults([<<"other_key">>], #{verbose => true}), + + {[<<"other_key">>], #{verbose := false}} = + ?COMMAND:merge_defaults([<<"other_key">>], #{verbose => false}). + + +run(BaseConfig) -> + Node = rabbit_ct_broker_helpers:get_node_config(BaseConfig, 0, nodename), + Config = [{websocket, true} | BaseConfig], + Opts = #{node => Node, timeout => 10_000, verbose => false}, + %% No connections + [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + + %% Create MQTT connection + C1 = connect(<<"simpleMqttClient">>, BaseConfig, [{ack_timeout, 1}]), + + timer:sleep(100), + + %% No connections for WebMQTT, C1 is a MQTT connection + [] = 'Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>], Opts)), + + %% Create WebMQTT connection + + C2 = connect(<<"simpleWebMqttClient">>, Config, [{ack_timeout, 1}]), + + timer:sleep(100), + + [[{client_id, <<"simpleWebMqttClient">>}]] = + 'Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>], Opts)), + + C3 = connect(<<"simpleWebMqttClient1">>, Config, [{ack_timeout, 1}]), + + timer:sleep(200), + + [[{client_id, <<"simpleWebMqttClient">>}, {user, <<"guest">>}], + [{client_id, <<"simpleWebMqttClient1">>}, {user, <<"guest">>}]] = + lists:sort( + 'Elixir.Enum':to_list( + ?COMMAND:run([<<"client_id">>, <<"user">>], Opts))), + + Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp), + start_amqp_connection(network, Node, Port), + + %% There are still just two Web MQTT connections + [[{client_id, <<"simpleWebMqttClient">>}], + [{client_id, <<"simpleWebMqttClient1">>}]] = + lists:sort('Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>], Opts))), + + start_amqp_connection(direct, Node, Port), + timer:sleep(200), + + %% Still two Web MQTT connections + [[{client_id, <<"simpleWebMqttClient">>}], + [{client_id, <<"simpleWebMqttClient1">>}]] = + lists:sort('Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>], Opts))), + + %% Verbose returns all keys + AllKeys = lists:map(fun(I) -> atom_to_binary(I) end, ?INFO_ITEMS), + [AllInfos1Con1, _AllInfos1Con2] = + 'Elixir.Enum':to_list(?COMMAND:run(AllKeys, Opts)), + [AllInfos2Con1, _AllInfos2Con2] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts#{verbose => true})), + + %% Keys are INFO_ITEMS + InfoItemsSorted = lists:sort(?INFO_ITEMS), + ?assertEqual(InfoItemsSorted, lists:sort(proplists:get_keys(AllInfos1Con1))), + ?assertEqual(InfoItemsSorted, lists:sort(proplists:get_keys(AllInfos2Con1))), + + %% CLI command should list Web MQTT connections from all nodes. + C4 = connect(<<"simpleWebMqttClient2">>, Config, 1, [{ack_timeout, 1}]), + rabbit_ct_helpers:eventually( + ?_assertEqual( + [[{client_id, <<"simpleWebMqttClient">>}], + [{client_id, <<"simpleWebMqttClient1">>}], + [{client_id, <<"simpleWebMqttClient2">>}]], + lists:sort('Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>], Opts))))), + + ok = emqtt:disconnect(C1), + ok = emqtt:disconnect(C2), + ok = emqtt:disconnect(C3), + ok = emqtt:disconnect(C4). + +user_property(BaseConfig) -> + Node = rabbit_ct_broker_helpers:get_node_config(BaseConfig, 0, nodename), + Config = [{websocket, true} | BaseConfig], + Opts = #{node => Node, timeout => 10_000, verbose => false}, + ClientId = <<"my-client">>, + UserProp = [{<<"name 1">>, <<"value 1">>}, + {<<"name 2">>, <<"value 2">>}, + %% "The same name is allowed to appear more than once." [v5 3.1.2.11.8] + {<<"name 2">>, <<"value 3">>}], + C = connect(ClientId, Config, 1, [{properties, #{'User-Property' => UserProp}}]), + rabbit_ct_helpers:eventually( + ?_assertEqual( + [[{client_id, ClientId}, + {user_property, UserProp}]], + 'Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>, <<"user_property">>], Opts)))), + ok = emqtt:disconnect(C). + +start_amqp_connection(Type, Node, Port) -> + amqp_connection:start(amqp_params(Type, Node, Port)). + +amqp_params(network, _, Port) -> + #amqp_params_network{port = Port}; +amqp_params(direct, Node, _) -> + #amqp_params_direct{node = Node}. diff --git a/deps/rabbitmq_web_mqtt/test/rabbit_web_mqtt_test_util.erl b/deps/rabbitmq_web_mqtt/test/rabbit_web_mqtt_test_util.erl new file mode 100644 index 00000000000..ee89668cf7e --- /dev/null +++ b/deps/rabbitmq_web_mqtt/test/rabbit_web_mqtt_test_util.erl @@ -0,0 +1,39 @@ +-module(rabbit_web_mqtt_test_util). + +-include_lib("eunit/include/eunit.hrl"). + +-export([connect/3, + connect/4 + ]). + +connect(ClientId, Config, AdditionalOpts) -> + connect(ClientId, Config, 0, AdditionalOpts). + +connect(ClientId, Config, Node, AdditionalOpts) -> + {C, Connect} = start_client(ClientId, Config, Node, AdditionalOpts), + {ok, _Properties} = Connect(C), + C. + +start_client(ClientId, Config, Node, AdditionalOpts) -> + {Port, WsOpts, Connect} = + case rabbit_ct_helpers:get_config(Config, websocket, false) of + false -> + {rabbit_ct_broker_helpers:get_node_config(Config, Node, tcp_port_mqtt), + [], + fun emqtt:connect/1}; + true -> + {rabbit_ct_broker_helpers:get_node_config(Config, Node, tcp_port_web_mqtt), + [{ws_path, "/ws"}], + fun emqtt:ws_connect/1} + end, + ProtoVer = proplists:get_value( + proto_ver, + AdditionalOpts, + rabbit_ct_helpers:get_config(Config, mqtt_version, v4)), + Options = [{host, "localhost"}, + {port, Port}, + {proto_ver, ProtoVer}, + {clientid, rabbit_data_coercion:to_binary(ClientId)} + ] ++ WsOpts ++ AdditionalOpts, + {ok, C} = emqtt:start_link(Options), + {C, Connect}.