parent
							
								
									befb3b3015
								
							
						
					
					
						commit
						481cac6430
					
				|  | @ -86,6 +86,13 @@ run(Config) -> | ||||||
|     %% No connections |     %% No connections | ||||||
|     [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), |     [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), | ||||||
| 
 | 
 | ||||||
|  |     %% Open a WebMQTT connection, command won't list it | ||||||
|  |     WebMqttConfig = [{websocket, true} | Config], | ||||||
|  |     _C0 = connect(<<"simpleWebMqttClient">>, WebMqttConfig, [{ack_timeout, 1}]), | ||||||
|  | 
 | ||||||
|  |     [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), | ||||||
|  | 
 | ||||||
|  |     %% Open a connection | ||||||
|     C1 = connect(<<"simpleClient">>, Config, [{ack_timeout, 1}]), |     C1 = connect(<<"simpleClient">>, Config, [{ack_timeout, 1}]), | ||||||
| 
 | 
 | ||||||
|     timer:sleep(100), |     timer:sleep(100), | ||||||
|  |  | ||||||
|  | @ -0,0 +1,177 @@ | ||||||
|  | %% 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(rabbit_web_mqtt_test_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) -> | ||||||
|  |     rabbit_ct_helpers:set_config(Config, {mqtt_version, Group}). | ||||||
|  | 
 | ||||||
|  | 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}. | ||||||
|  | @ -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}. | ||||||
		Loading…
	
		Reference in New Issue