rabbitmq-server/deps/rabbitmq_peer_discovery_aws/test/integration_SUITE.erl

183 lines
8.3 KiB
Erlang

%% 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-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%
-module(integration_SUITE).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("rabbitmq_ct_helpers/include/rabbit_assert.hrl").
-define(CLUSTER_SIZE, 3).
-define(TIMEOUT_MILLIS, 180_000).
-export([all/0,
suite/0,
groups/0,
init_per_suite/1, end_per_suite/1,
init_per_group/2, end_per_group/2,
init_per_testcase/2, end_per_testcase/2,
cluster_was_formed/1
]).
all() ->
[
{group, using_tags},
{group, using_autoscaling_group}
].
suite() ->
[
{timetrap, {minutes, 20}}
].
groups() ->
[
{using_tags, [parallel], [cluster_was_formed]},
{using_autoscaling_group, [parallel], [cluster_was_formed]}
].
init_per_suite(Config) ->
case rabbit_ct_helpers:is_mixed_versions() of
true ->
%% These test would likely pass in mixed versions, but they won't
%% actually honor mixed versions like the other suites, as these
%% tests are docker image based
{skip, "not mixed versions compatible"};
_ ->
inets:start(),
rabbit_ct_helpers:log_environment(),
Config1 = rabbit_ct_helpers:set_config(
Config, [
{ecs_region, "eu-west-1"},
{ecs_cluster_name, os:getenv("AWS_ECS_CLUSTER_NAME", "rabbitmq-peer-discovery-aws")},
{ecs_profile_name, "rabbitmq-peer-discovery-aws-profile"},
{ecs_instance_role, "ecs-peer-discovery-aws"},
{ecs_cluster_size, ?CLUSTER_SIZE},
{rabbitmq_default_user, "test"},
{rabbitmq_default_pass, rabbit_ct_helpers:random_term_checksum()},
{rabbitmq_erlang_cookie, rabbit_ct_helpers:random_term_checksum()}
]),
Config2 = rabbit_ct_helpers:register_teardown_step(Config1, fun aws_ecs_util:destroy_ecs_cluster/1),
rabbit_ct_helpers:run_steps(
Config2, [
fun rabbit_ct_helpers:init_skip_as_error_flag/1,
fun rabbit_ct_helpers:start_long_running_testsuite_monitor/1,
fun aws_ecs_util:ensure_aws_cli/1,
fun aws_ecs_util:ensure_ecs_cli/1,
fun aws_ecs_util:init_aws_credentials/1,
fun aws_ecs_util:ensure_rabbitmq_image/1,
fun aws_ecs_util:start_ecs_cluster/1
])
end.
end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config).
init_per_group(using_tags, Config) ->
Config1 = rabbit_ct_helpers:set_config(
Config,
[{ecs_service_name, "rabbitmq-tagged"}]),
rabbit_ct_helpers:run_steps(Config1, [fun register_tagged_task/1,
fun aws_ecs_util:create_service/1]);
init_per_group(using_autoscaling_group, Config) ->
Config1 = rabbit_ct_helpers:set_config(
Config,
[{ecs_service_name, "rabbitmq-autoscaled"}]),
rabbit_ct_helpers:run_steps(Config1, [fun register_autoscaled_task/1,
fun aws_ecs_util:create_service/1]).
end_per_group(_Group, Config) ->
rabbit_ct_helpers:run_steps(Config, [fun aws_ecs_util:delete_service/1,
fun (C) ->
% A short delay so that all tasks
% associated with the service can
% be deregistered
timer:sleep(15000),
C
end,
fun aws_ecs_util:deregister_tasks/1]).
init_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_started(Config, Testcase).
end_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_finished(Config, Testcase).
cluster_was_formed(Config) ->
{ok, [H1, H2, H3]} = ?awaitMatch({ok, L} when length(L) == ?CLUSTER_SIZE,
aws_ecs_util:public_dns_names(Config),
?TIMEOUT_MILLIS),
[N1Nodes, N2Nodes, N3Nodes] =
[begin
{ok, R} = ?awaitMatch({ok, R} when is_list(R) andalso length(R) == ?CLUSTER_SIZE,
aws_ecs_util:fetch_nodes_endpoint(Config, binary_to_list(H)),
?TIMEOUT_MILLIS),
[maps:get(<<"name">>, N) || N <- R]
end || H <- [H1, H2, H3]],
?assertEqual(lists:sort(N1Nodes), lists:sort(N2Nodes)),
?assertEqual(lists:sort(N2Nodes), lists:sort(N3Nodes)).
register_tagged_task(Config) ->
RabbitmqDefaultUser = ?config(rabbitmq_default_user, Config),
RabbitmqDefaultPass = ?config(rabbitmq_default_pass, Config),
RabbitmqConf = string:join([
"log.console.level = debug",
"default_user = " ++ RabbitmqDefaultUser,
"default_pass = " ++ RabbitmqDefaultPass,
"cluster_formation.peer_discovery_backend = aws",
"cluster_formation.aws.instance_tags.service = rabbitmq",
""
], "\n"),
TaskJson = task_json(Config, RabbitmqConf),
aws_ecs_util:register_task(Config, TaskJson).
register_autoscaled_task(Config) ->
RabbitmqDefaultUser = ?config(rabbitmq_default_user, Config),
RabbitmqDefaultPass = ?config(rabbitmq_default_pass, Config),
RabbitmqConf = string:join([
"log.console.level = debug",
"default_user = " ++ RabbitmqDefaultUser,
"default_pass = " ++ RabbitmqDefaultPass,
"cluster_formation.peer_discovery_backend = aws",
"cluster_formation.aws.use_autoscaling_group = true",
""
], "\n"),
TaskJson = task_json(Config, RabbitmqConf),
aws_ecs_util:register_task(Config, TaskJson).
task_json(Config, RabbitmqConf) ->
DataDir = ?config(data_dir, Config),
RabbitmqImage = ?config(rabbitmq_image, Config),
RabbitmqErlangCookie = ?config(rabbitmq_erlang_cookie, Config),
ServiceName = ?config(ecs_service_name, Config),
ClusterName = ?config(ecs_cluster_name, Config),
{ok, Binary} = file:read_file(filename:join(DataDir, "task_definition.json")),
TaskDef = rabbit_json:decode(Binary),
[RabbitContainerDef, SidecarContainerDef] = maps:get(<<"containerDefinitions">>, TaskDef),
LogConfiguration = maps:get(<<"logConfiguration">>, RabbitContainerDef),
Options = maps:get(<<"options">>, LogConfiguration),
Options1 = Options#{<<"awslogs-stream-prefix">> := list_to_binary(ClusterName)},
LogConfiguration1 = LogConfiguration#{<<"options">> := Options1},
RabbitContainerDef1 =
RabbitContainerDef#{
<<"image">> := list_to_binary(RabbitmqImage),
<<"environment">> := [#{<<"name">> => <<"RABBITMQ_ERLANG_COOKIE">>,
<<"value">> => list_to_binary(RabbitmqErlangCookie)}],
<<"logConfiguration">> := LogConfiguration1
},
SidecarContainerDef1 =
SidecarContainerDef#{<<"environment">> := [#{<<"name">> => <<"DATA">>,
<<"value">> => base64:encode(RabbitmqConf)}]},
rabbit_json:encode(
TaskDef#{<<"family">> := list_to_binary(ServiceName),
<<"containerDefinitions">> := [RabbitContainerDef1, SidecarContainerDef1]}).