From f4f375c6a9ef6cb03f0f12ad7f06698fa4786d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 2 Sep 2024 14:55:02 +0200 Subject: [PATCH] Use Make in CI This is a proof of concept that mostly works but is missing some tests, such as rabbitmq_mqtt or rabbitmq_cli. It also doesn't apply to mixed version testing yet. --- .github/workflows/test-make-ct-par.yaml | 55 +++++++++++++ .github/workflows/test-make-ct-seq.yaml | 64 +++++++++++++++ .github/workflows/test-make-jobs.yaml | 95 ++++++++++++++++++++++ .github/workflows/test-make.yaml | 66 +++++++++++++++ .github/workflows/test-mixed-versions.yaml | 4 +- .github/workflows/test.yaml | 21 ++++- deps/rabbit/Makefile | 94 ++++++++++++++++++++- deps/rabbitmq_mqtt/test/shared_SUITE.erl | 2 + rabbitmq-components.mk | 3 + 9 files changed, 397 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/test-make-ct-par.yaml create mode 100644 .github/workflows/test-make-ct-seq.yaml create mode 100644 .github/workflows/test-make-jobs.yaml create mode 100644 .github/workflows/test-make.yaml diff --git a/.github/workflows/test-make-ct-par.yaml b/.github/workflows/test-make-ct-par.yaml new file mode 100644 index 0000000000..24a8ab649e --- /dev/null +++ b/.github/workflows/test-make-ct-par.yaml @@ -0,0 +1,55 @@ +name: Parallel CT (make) +on: + workflow_call: + inputs: + erlang_version: + required: true + type: number + elixir_version: + required: true + type: number + metadata_store: + required: true + type: string + make_target: + required: true + type: string + plugin: + required: true + type: string +jobs: + test: + name: ${{ inputs.plugin }} (${{ inputs.make_target }}) + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: CHECKOUT REPOSITORY + uses: actions/checkout@v4 + + - name: SETUP OTP & ELIXIR + uses: erlef/setup-beam@v1.17 + with: + otp-version: ${{ inputs.erlang_version }} + elixir-version: ${{ inputs.elixir_version }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex + + - name: SETUP DOTNET (rabbit) + uses: actions/setup-dotnet@v4 + if: inputs.plugin == 'rabbit' + with: + dotnet-version: '3.1.x' + + - name: RUN TESTS + run: | + make -C deps/${{ inputs.plugin }} ${{ inputs.make_target }} RABBITMQ_METADATA_STORE=${{ inputs.metadata_store }} + + - name: UPLOAD TEST LOGS + if: always() + uses: actions/upload-artifact@v4 + with: + name: CT logs (${{ inputs.plugin }} ${{ inputs.make_target }} OTP-${{ inputs.erlang_version }} ${{ inputs.metadata_store }}) + path: | + deps/${{ inputs.plugin }}/logs/ + !deps/${{ inputs.plugin }}/logs/**/log_private diff --git a/.github/workflows/test-make-ct-seq.yaml b/.github/workflows/test-make-ct-seq.yaml new file mode 100644 index 0000000000..c8d0b144da --- /dev/null +++ b/.github/workflows/test-make-ct-seq.yaml @@ -0,0 +1,64 @@ +name: Sequential CT (make) +on: + workflow_call: + inputs: + erlang_version: + required: true + type: number + elixir_version: + required: true + type: number + metadata_store: + required: true + type: string + plugin: + required: true + type: string +jobs: + test: + name: ${{ inputs.plugin }} (tests) + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: CHECKOUT REPOSITORY + uses: actions/checkout@v4 + + - name: SETUP OTP & ELIXIR + uses: erlef/setup-beam@v1.17 + with: + otp-version: ${{ inputs.erlang_version }} + elixir-version: ${{ inputs.elixir_version }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex + + - name: SETUP rabbitmq_auth_backend_ldap + if: inputs.plugin == 'rabbitmq_auth_backend_ldap' + run: | + sudo apt-get update && \ + sudo apt-get install -y \ + apparmor-utils \ + ldap-utils \ + slapd + + sudo aa-complain `which slapd` + +# @todo Why? +# - name: CLI COMPILE WARNINGS AS ERRORS +# if: inputs.plugin == 'rabbitmq_cli' +# run: | +# bazel build //deps/rabbitmq_cli:compile_warnings_as_errors \ +# --verbose_failures + + - name: RUN TESTS + run: | + make -C deps/${{ inputs.plugin }} tests RABBITMQ_METADATA_STORE=${{ inputs.metadata_store }} + + - name: UPLOAD TEST LOGS + if: always() + uses: actions/upload-artifact@v4 + with: + name: CT logs (${{ inputs.plugin }} OTP-${{ inputs.erlang_version }} ${{ inputs.metadata_store }}) + path: | + deps/${{ inputs.plugin }}/logs/ + !deps/${{ inputs.plugin }}/logs/**/log_private diff --git a/.github/workflows/test-make-jobs.yaml b/.github/workflows/test-make-jobs.yaml new file mode 100644 index 0000000000..aa03ab377b --- /dev/null +++ b/.github/workflows/test-make-jobs.yaml @@ -0,0 +1,95 @@ +name: Test jobs (make) +on: + workflow_call: + inputs: + erlang_version: + required: true + type: number + elixir_version: + required: true + type: number + metadata_store: + required: true + type: string +jobs: + test-rabbit: + name: Test rabbit + strategy: + fail-fast: false + matrix: + make_target: + - parallel-ct-set-1 + - parallel-ct-set-2 + - parallel-ct-set-3 + - parallel-ct-set-4 + - ct-clustering_management + - eunit ct-dead_lettering + - ct-feature_flags + - ct-metadata_store_clustering + - ct-quorum_queue + - ct-rabbit_stream_queue + uses: ./.github/workflows/test-make-ct-par.yaml + with: + erlang_version: ${{ inputs.erlang_version }} + elixir_version: ${{ inputs.elixir_version }} + metadata_store: ${{ inputs.metadata_store }} + make_target: ${{ matrix.make_target }} + plugin: rabbit + +# @todo test-mqtt using parallel ct + + test-ct-seq: + name: Test plugins + strategy: + fail-fast: false + matrix: + plugin: + - amqp10_client + - amqp10_common + - amqp_client + - oauth2_client + - rabbit_common + - rabbitmq_amqp_client + - rabbitmq_auth_backend_cache + - rabbitmq_auth_backend_http + - rabbitmq_auth_backend_ldap + - rabbitmq_auth_backend_oauth2 + - rabbitmq_auth_mechanism_ssl + - rabbitmq_consistent_hash_exchange + - rabbitmq_event_exchange + - rabbitmq_federation + - rabbitmq_federation_management + - rabbitmq_federation_prometheus + - rabbitmq_jms_topic_exchange + - rabbitmq_management + - rabbitmq_management_agent + - rabbitmq_peer_discovery_common + - rabbitmq_peer_discovery_consul + - rabbitmq_peer_discovery_etcd + - rabbitmq_peer_discovery_k8s + - rabbitmq_prelaunch + - rabbitmq_prometheus + - rabbitmq_recent_history_exchange + - rabbitmq_sharding + - rabbitmq_shovel + - rabbitmq_shovel_management + - rabbitmq_shovel_prometheus + - rabbitmq_stomp + - rabbitmq_stream + - rabbitmq_stream_common + - rabbitmq_stream_management + - rabbitmq_tracing + - rabbitmq_trust_store + - rabbitmq_web_dispatch + - rabbitmq_web_mqtt + - rabbitmq_web_stomp + uses: ./.github/workflows/test-make-ct-seq.yaml + with: + erlang_version: ${{ inputs.erlang_version }} + elixir_version: ${{ inputs.elixir_version }} + metadata_store: ${{ inputs.metadata_store }} + plugin: ${{ matrix.plugin }} + +# @todo Test rabbitmq_cli + +# @todo Dialyzer xref diff --git a/.github/workflows/test-make.yaml b/.github/workflows/test-make.yaml new file mode 100644 index 0000000000..ae40c88d34 --- /dev/null +++ b/.github/workflows/test-make.yaml @@ -0,0 +1,66 @@ +name: Test (make) +on: + push: + branches: + - main + - bump-otp-for-oci + - bump-rbe-* + paths: + - deps/** + - scripts/** + - Makefile + - plugins.mk + - rabbitmq-components.mk + - .github/workflows/test-make.yaml + pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + version-matrix: + name: Test + strategy: + fail-fast: false + matrix: + erlang_version: + - 26 + - 27 + elixir_version: + - 1.17 + metadata_store: + - mnesia + - khepri + uses: ./.github/workflows/test-make-jobs.yaml + with: + erlang_version: ${{ matrix.erlang_version }} + elixir_version: ${{ matrix.elixir_version }} + metadata_store: ${{ matrix.metadata_store }} + + build: + name: Build + strategy: + fail-fast: false + matrix: + erlang_version: + - 26 + - 27 + elixir_version: + - 1.17 + # @todo Add macOS and Windows. + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: CHECKOUT REPOSITORY + uses: actions/checkout@v4 + + - name: SETUP OTP & ELIXIR + uses: erlef/setup-beam@v1.17 + with: + otp-version: ${{ matrix.erlang_version }} + elixir-version: ${{ matrix.elixir_version }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex + + - name: BUILD + run: make diff --git a/.github/workflows/test-mixed-versions.yaml b/.github/workflows/test-mixed-versions.yaml index d287d8e437..efb261cbf1 100644 --- a/.github/workflows/test-mixed-versions.yaml +++ b/.github/workflows/test-mixed-versions.yaml @@ -2,7 +2,7 @@ name: Test Mixed Version Clusters on: push: branches: - - main +# - main - v4.0.x - v3.13.x - bump-otp-* @@ -20,7 +20,7 @@ on: - BUILD.* - '*.bzl' - '*.bazel' - - .github/workflows/test-mixed-versions.yaml +# - .github/workflows/test-mixed-versions.yaml pull_request: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 582de03678..c984ef89c4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -2,7 +2,7 @@ name: Test on: push: branches: - - main +# - main - v4.0.x - v3.13.x - v3.12.x @@ -22,7 +22,7 @@ on: - '*.bzl' - '*.bazel' - .github/workflows/test.yaml - pull_request: +# pull_request: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true @@ -142,6 +142,23 @@ jobs: repo_cache_key: ${{ needs.check-workflow.outputs.repo_cache_key }} plugin: trust_store_http secrets: inherit + test-rabbit-make: +# needs: +# - check-workflow +# - test-amqp10_client +# - test-amqp10_common +# - test-amqp_client +# - test-oauth2_client +# - test-rabbit_common +# - test-rabbitmq_ct_client_helpers +# - test-rabbitmq_ct_helpers +# - test-rabbitmq_stream_common +# - test-trust_store_http + uses: ./.github/workflows/test-plugin-make.yaml + with: + repo_cache_key: ${{ needs.check-workflow.outputs.repo_cache_key }} + plugin: rabbit + secrets: inherit test-rabbit-0: needs: - check-workflow diff --git a/deps/rabbit/Makefile b/deps/rabbit/Makefile index 066e863dec..5371d688ec 100644 --- a/deps/rabbit/Makefile +++ b/deps/rabbit/Makefile @@ -236,7 +236,7 @@ define ct_master.erl peer:call(Pid2, persistent_term, put, [rabbit_ct_tcp_port_base, 25000]), peer:call(Pid3, persistent_term, put, [rabbit_ct_tcp_port_base, 27000]), peer:call(Pid4, persistent_term, put, [rabbit_ct_tcp_port_base, 29000]), - ct_master:run("ct.test.spec"), + ct_master:run("$1"), peer:stop(Pid4), peer:stop(Pid3), peer:stop(Pid2), @@ -244,9 +244,97 @@ define ct_master.erl halt() endef -ct-master: test-build +# @todo We must ensure that the CT_OPTS also apply to ct-master +# @todo We should probably refactor ct_master.erl to have node init in a separate .erl +# @todo We would benefit from having rabbit nodes started with peer (no leftovers) +# @todo We need ct-master to be expanded to all components and not just rabbit +# @todo Generate ct.test.spec from Makefile variables instead of hardcoded for ct-master + + +#PARALLEL_CT_NUM_NODES ?= 4 +#PARALLEL_CT_NODE_NAME = rabbit_shard$1@localhost +#PARALLEL_CT_NODE_INIT_FUN = fun(Pid, Num) -> peer:call(Pid, net_kernel, set_net_ticktime, [5]), peer:call(Pid, persistent_term, put, [rabbit_ct_tcp_port_base, 21000 + 2000 * Num]) end + +#PARALLEL_CT_NUM_SETS = 8 + + +PARALLEL_CT_SET_1_A = amqp_client unit_cluster_formation_locking_mocks unit_cluster_formation_sort_nodes unit_collections unit_config_value_encryption unit_connection_tracking +PARALLEL_CT_SET_1_B = amqp_address amqp_auth amqp_credit_api_v2 amqp_system signal_handling single_active_consumer unit_access_control_authn_authz_context_propagation unit_access_control_credential_validation unit_amqp091_content_framing unit_amqp091_server_properties unit_app_management +PARALLEL_CT_SET_1_C = amqp_proxy_protocol amqpl_consumer_ack amqpl_direct_reply_to backing_queue bindings rabbit_db_maintenance rabbit_db_msup rabbit_db_policy rabbit_db_queue rabbit_db_topic_exchange rabbit_direct_reply_to_prop cluster_limit cluster_minority term_to_binary_compat_prop topic_permission transactions unicode unit_access_control +PARALLEL_CT_SET_1_D = amqqueue_backward_compatibility channel_interceptor channel_operation_timeout classic_queue classic_queue_prop config_schema peer_discovery_dns peer_discovery_tmp_hidden_node per_node_limit per_user_connection_channel_limit + +PARALLEL_CT_SET_2_A = cluster confirms_rejects consumer_timeout rabbit_access_control rabbit_confirms rabbit_core_metrics_gc rabbit_cuttlefish rabbit_db_binding rabbit_db_exchange +PARALLEL_CT_SET_2_B = clustering_recovery crashing_queues deprecated_features direct_exchange_routing_v2 disconnect_detected_during_alarm exchanges unit_gen_server2 +PARALLEL_CT_SET_2_C = disk_monitor dynamic_qq unit_disk_monitor unit_file_handle_cache unit_log_management unit_operator_policy +PARALLEL_CT_SET_2_D = queue_length_limits queue_parallel quorum_queue_member_reconciliation rabbit_fifo rabbit_fifo_dlx rabbit_stream_coordinator + +PARALLEL_CT_SET_3_A = definition_import per_user_connection_channel_limit_partitions per_vhost_connection_limit_partitions policy priority_queue_recovery rabbit_fifo_prop rabbit_fifo_v0 rabbit_stream_sac_coordinator unit_credit_flow unit_queue_consumers unit_queue_location unit_quorum_queue +PARALLEL_CT_SET_3_B = cluster_upgrade list_consumers_sanity_check list_queues_online_and_offline logging lqueue maintenance_mode rabbit_fifo_q +PARALLEL_CT_SET_3_C = cli_forget_cluster_node feature_flags_v2 mc_unit message_containers_deaths_v2 message_size_limit metadata_store_migration +PARALLEL_CT_SET_3_D = metadata_store_phase1 metrics mirrored_supervisor msg_store peer_discovery_classic_config proxy_protocol runtime_parameters unit_stats_and_metrics unit_supervisor2 unit_vm_memory_monitor + +PARALLEL_CT_SET_4_A = clustering_events rabbit_local_random_exchange rabbit_message_interceptor rabbitmq_4_0_deprecations unit_pg_local unit_plugin_directories unit_plugin_versioning unit_policy_validators unit_priority_queue +PARALLEL_CT_SET_4_B = per_user_connection_tracking per_vhost_connection_limit rabbit_fifo_dlx_integration rabbit_fifo_int +PARALLEL_CT_SET_4_C = per_vhost_msg_store per_vhost_queue_limit priority_queue upgrade_preparation vhost +PARALLEL_CT_SET_4_D = per_user_connection_channel_tracking product_info publisher_confirms_parallel queue_type rabbitmq_queues_cli_integration rabbitmqctl_integration rabbitmqctl_shutdown routing + +PARALLEL_CT_SET_1 = $(sort $(PARALLEL_CT_SET_1_A) $(PARALLEL_CT_SET_1_B) $(PARALLEL_CT_SET_1_C) $(PARALLEL_CT_SET_1_D)) +PARALLEL_CT_SET_2 = $(sort $(PARALLEL_CT_SET_2_A) $(PARALLEL_CT_SET_2_B) $(PARALLEL_CT_SET_2_C) $(PARALLEL_CT_SET_2_D)) +PARALLEL_CT_SET_3 = $(sort $(PARALLEL_CT_SET_3_A) $(PARALLEL_CT_SET_3_B) $(PARALLEL_CT_SET_3_C) $(PARALLEL_CT_SET_3_D)) +PARALLEL_CT_SET_4 = $(sort $(PARALLEL_CT_SET_4_A) $(PARALLEL_CT_SET_4_B) $(PARALLEL_CT_SET_4_C) $(PARALLEL_CT_SET_4_D)) + +SEQUENTIAL_CT_SUITES = clustering_management dead_lettering feature_flags metadata_store_clustering quorum_queue rabbit_stream_queue +PARALLEL_CT_SUITES = $(PARALLEL_CT_SET_1) $(PARALLEL_CT_SET_2) $(PARALLEL_CT_SET_3) $(PARALLEL_CT_SET_4) + +ifneq ($(filter-out $(SEQUENTIAL_CT_SUITES) $(PARALLEL_CT_SUITES),$(CT_SUITES)),) +$(error Some test suites in CT_SUITES but not configured for CI.) +endif + + + +define tpl_parallel_ct_test_spec +{logdir, "logs/"}. +{logdir, master, "logs/"}. +{create_priv_dir, all_nodes, auto_per_run}. + +{node, shard1, 'rabbit_shard1@localhost'}. +{node, shard2, 'rabbit_shard2@localhost'}. +{node, shard3, 'rabbit_shard3@localhost'}. +{node, shard4, 'rabbit_shard4@localhost'}. + +{define, 'Set1', [$(call comma_list,$(addsuffix _SUITE,$1))]}. +{define, 'Set2', [$(call comma_list,$(addsuffix _SUITE,$2))]}. +{define, 'Set3', [$(call comma_list,$(addsuffix _SUITE,$3))]}. +{define, 'Set4', [$(call comma_list,$(addsuffix _SUITE,$4))]}. + +{suites, shard1, "test/", 'Set1'}. +{suites, shard2, "test/", 'Set2'}. +{suites, shard3, "test/", 'Set3'}. +{suites, shard4, "test/", 'Set4'}. +endef + +define parallel_ct_set_target +tpl_parallel_ct_test_spec_set_$1 = $$(call tpl_parallel_ct_test_spec,$(PARALLEL_CT_SET_$(1)_A),$(PARALLEL_CT_SET_$(1)_B),$(PARALLEL_CT_SET_$(1)_C),$(PARALLEL_CT_SET_$(1)_D)) + +parallel-ct-set-$(1): test-build $(verbose) mkdir -p $(CT_LOGS_DIR) - $(call erlang,$(ct_master.erl),-sname rabbit_master@localhost -hidden -kernel net_ticktime 5) + $(verbose) $$(call core_render,tpl_parallel_ct_test_spec_set_$(1),ct.set-$(1).spec) + $$(call erlang,$$(call ct_master.erl,ct.set-$(1).spec),-sname parallel_ct_$(PROJECT)@localhost -hidden -kernel net_ticktime 5) +endef + +$(foreach set,1 2 3 4,$(eval $(call parallel_ct_set_target,$(set)))) + + + + + + + + + +parallel-ct: test-build + $(verbose) mkdir -p $(CT_LOGS_DIR) + $(call erlang,$(call ct_master.erl,ct.test.spec),-sname parallel_ct_$(PROJECT)@localhost -hidden -kernel net_ticktime 5) # -------------------------------------------------------------------- # Compilation. diff --git a/deps/rabbitmq_mqtt/test/shared_SUITE.erl b/deps/rabbitmq_mqtt/test/shared_SUITE.erl index 16afac557d..aa518e5d46 100644 --- a/deps/rabbitmq_mqtt/test/shared_SUITE.erl +++ b/deps/rabbitmq_mqtt/test/shared_SUITE.erl @@ -54,6 +54,7 @@ all() -> [{group, mqtt}, + %% @todo Move web_mqtt to rabbitmq_web_mqtt directly. {group, web_mqtt}]. %% The code being tested under v3 and v4 is almost identical. @@ -218,6 +219,7 @@ init_per_testcase(Testcase, Config) -> init_per_testcase0(Testcase, Config) -> Nodes = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + %% @todo This should only be necessary for Bazel's mixed version testing. [ok = rabbit_ct_broker_helpers:enable_plugin(Config, N, rabbitmq_web_mqtt) || N <- Nodes], rabbit_ct_helpers:testcase_started(Config, Testcase). diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk index 7f4ed26236..08903247d5 100644 --- a/rabbitmq-components.mk +++ b/rabbitmq-components.mk @@ -60,6 +60,9 @@ dep_seshat = git https://github.com/rabbitmq/seshat v0.6.1 dep_stdout_formatter = hex 0.2.4 dep_sysmon_handler = hex 1.3.0 +# @todo Move up in the list later. +dep_osiris = git https://github.com/rabbitmq/osiris v1.8.3 + # RabbitMQ applications found in the monorepo. # # Note that rabbitmq_server_release is not a real application