From 14d1af279e68a3c9a673ea32fb1f22bb20741bf5 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 22 Apr 2022 10:39:57 +0400 Subject: [PATCH] List #4588 in 3.10.0 release notes --- deps/rabbit/scripts/rabbitmq-defaults.bat | 42 +- deps/rabbit/scripts/rabbitmq-diagnostics.bat | 110 +- deps/rabbit/scripts/rabbitmq-echopid.bat | 114 +- deps/rabbit/scripts/rabbitmq-env.bat | 362 ++-- deps/rabbit/scripts/rabbitmq-plugins.bat | 112 +- deps/rabbit/scripts/rabbitmq-queues.bat | 112 +- deps/rabbit/scripts/rabbitmq-server.bat | 184 +- deps/rabbit/scripts/rabbitmq-service.bat | 548 ++--- deps/rabbit/scripts/rabbitmq-streams.bat | 110 +- deps/rabbit/scripts/rabbitmqctl.bat | 112 +- deps/rabbit_common/mk/xrefr | 338 --- .../system_SUITE_data/java-tests/mvnw.cmd | 322 +-- .../rabbitmq_auth_backend_php/var/log.log | 0 .../App_Start/WebApiConfig.cs | 24 +- .../Controllers/AuthController.cs | 286 +-- .../Global.asax | 2 +- .../Global.asax.cs | 24 +- .../Properties/AssemblyInfo.cs | 70 +- .../Web.Debug.config | 58 +- .../Web.Release.config | 60 +- .../Web.config | 88 +- .../WebApiHttpAuthService.csproj | 272 +-- .../WebApiHttpAuthService.csproj.user | 84 +- .../WebApiHttpAuthService.sln | 50 +- .../packages.config | 14 +- deps/rabbitmq_aws/rabbitmq_aws.iml | 25 - .../examples/ruby/Gemfile.lock | 15 - deps/rabbitmq_ct_client_helpers/.gitignore | 23 - deps/rabbitmq_ct_client_helpers/BUILD.bazel | 11 - .../CODE_OF_CONDUCT.md | 1 - .../CONTRIBUTING.md | 1 - deps/rabbitmq_ct_client_helpers/LICENSE | 4 - .../LICENSE-MPL-RabbitMQ | 373 ---- deps/rabbitmq_ct_client_helpers/Makefile | 16 - .../WORKSPACE.bazel | 24 - .../src/rabbit_ct_client_helpers.erl | 302 --- deps/rabbitmq_ct_helpers/.gitignore | 27 - deps/rabbitmq_ct_helpers/BUILD.bazel | 14 - deps/rabbitmq_ct_helpers/CODE_OF_CONDUCT.md | 1 - deps/rabbitmq_ct_helpers/CONTRIBUTING.md | 1 - deps/rabbitmq_ct_helpers/LICENSE | 12 - deps/rabbitmq_ct_helpers/LICENSE-APACHE2 | 202 -- deps/rabbitmq_ct_helpers/LICENSE-MPL-RabbitMQ | 373 ---- deps/rabbitmq_ct_helpers/Makefile | 25 - deps/rabbitmq_ct_helpers/WORKSPACE.bazel | 18 - .../include/rabbit_assert.hrl | 49 - .../include/rabbit_mgmt_test.hrl | 11 - .../src/rabbit_control_helper.erl | 46 - .../src/rabbit_ct_broker_helpers.erl | 1919 ----------------- .../src/rabbit_ct_config_schema.erl | 107 - .../src/rabbit_ct_helpers.erl | 1098 ---------- .../src/rabbit_ct_proper_helpers.erl | 21 - .../src/rabbit_ct_vm_helpers.erl | 1140 ---------- .../src/rabbit_mgmt_test_util.erl | 323 --- .../test/terraform_SUITE.erl | 166 -- .../tools/terraform/autoscaling-group/main.tf | 78 - .../terraform/autoscaling-group/outputs.tf | 5 - .../terraform/autoscaling-group/setup-vms.sh | 178 -- .../terraform/autoscaling-group/variables.tf | 80 - .../tools/terraform/direct-vms/main.tf | 234 -- .../tools/terraform/direct-vms/outputs.tf | 59 - .../tools/terraform/direct-vms/setup-vms.sh | 187 -- .../direct-vms/templates/setup-erlang.sh | 264 --- .../tools/terraform/direct-vms/variables.tf | 147 -- .../tools/terraform/vms-query/main.tf | 31 - .../tools/terraform/vms-query/outputs.tf | 21 - .../tools/terraform/vms-query/query-vms.sh | 55 - .../tools/terraform/vms-query/variables.tf | 14 - .../tools/tls-certs/.gitignore | 1 - .../tools/tls-certs/Makefile | 70 - .../tools/tls-certs/openssl.cnf.in | 62 - .../config_schema_SUITE_data/certs/cacert.pem | 1 - .../config_schema_SUITE_data/certs/cert.pem | 1 - .../config_schema_SUITE_data/certs/key.pem | 1 - .../rabbit-mgmt/access.log | 0 .../test/java_SUITE_data/mvnw.cmd | 322 +-- .../schema/rabbitmq_management.schema | 436 ---- .../schema/rabbitmq_management_agent.schema | 4 - .../schema/rabbitmq_prometheus.schema | 116 - .../.mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .../.mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .../priv/www/js/tmpl/traces.ejs | 174 -- release-notes/3.10.0.md | 10 + 83 files changed, 1751 insertions(+), 10646 deletions(-) delete mode 100755 deps/rabbit_common/mk/xrefr delete mode 100755 deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_php/var/log.log delete mode 100644 deps/rabbitmq_aws/rabbitmq_aws.iml delete mode 100644 deps/rabbitmq_consistent_hash_exchange/examples/ruby/Gemfile.lock delete mode 100644 deps/rabbitmq_ct_client_helpers/.gitignore delete mode 100644 deps/rabbitmq_ct_client_helpers/BUILD.bazel delete mode 120000 deps/rabbitmq_ct_client_helpers/CODE_OF_CONDUCT.md delete mode 120000 deps/rabbitmq_ct_client_helpers/CONTRIBUTING.md delete mode 100644 deps/rabbitmq_ct_client_helpers/LICENSE delete mode 100644 deps/rabbitmq_ct_client_helpers/LICENSE-MPL-RabbitMQ delete mode 100644 deps/rabbitmq_ct_client_helpers/Makefile delete mode 100644 deps/rabbitmq_ct_client_helpers/WORKSPACE.bazel delete mode 100644 deps/rabbitmq_ct_client_helpers/src/rabbit_ct_client_helpers.erl delete mode 100644 deps/rabbitmq_ct_helpers/.gitignore delete mode 100644 deps/rabbitmq_ct_helpers/BUILD.bazel delete mode 120000 deps/rabbitmq_ct_helpers/CODE_OF_CONDUCT.md delete mode 120000 deps/rabbitmq_ct_helpers/CONTRIBUTING.md delete mode 100644 deps/rabbitmq_ct_helpers/LICENSE delete mode 100644 deps/rabbitmq_ct_helpers/LICENSE-APACHE2 delete mode 100644 deps/rabbitmq_ct_helpers/LICENSE-MPL-RabbitMQ delete mode 100644 deps/rabbitmq_ct_helpers/Makefile delete mode 100644 deps/rabbitmq_ct_helpers/WORKSPACE.bazel delete mode 100644 deps/rabbitmq_ct_helpers/include/rabbit_assert.hrl delete mode 100644 deps/rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_control_helper.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_ct_broker_helpers.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_ct_config_schema.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_ct_helpers.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_ct_proper_helpers.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_ct_vm_helpers.erl delete mode 100644 deps/rabbitmq_ct_helpers/src/rabbit_mgmt_test_util.erl delete mode 100644 deps/rabbitmq_ct_helpers/test/terraform_SUITE.erl delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/main.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/outputs.tf delete mode 100755 deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/setup-vms.sh delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/variables.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/main.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/outputs.tf delete mode 100755 deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/setup-vms.sh delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/templates/setup-erlang.sh delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/variables.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/vms-query/main.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/vms-query/outputs.tf delete mode 100755 deps/rabbitmq_ct_helpers/tools/terraform/vms-query/query-vms.sh delete mode 100644 deps/rabbitmq_ct_helpers/tools/terraform/vms-query/variables.tf delete mode 100644 deps/rabbitmq_ct_helpers/tools/tls-certs/.gitignore delete mode 100644 deps/rabbitmq_ct_helpers/tools/tls-certs/Makefile delete mode 100644 deps/rabbitmq_ct_helpers/tools/tls-certs/openssl.cnf.in delete mode 100644 deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cacert.pem delete mode 100644 deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cert.pem delete mode 100644 deps/rabbitmq_management/test/config_schema_SUITE_data/certs/key.pem delete mode 100644 deps/rabbitmq_management/test/config_schema_SUITE_data/rabbit-mgmt/access.log delete mode 100644 deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management.schema delete mode 100644 deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management_agent.schema delete mode 100644 deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_prometheus.schema delete mode 100644 deps/rabbitmq_stream/test/rabbit_stream_SUITE_data/.mvn/wrapper/maven-wrapper.jar delete mode 100644 deps/rabbitmq_stream_management/test/http_SUITE_data/.mvn/wrapper/maven-wrapper.jar delete mode 100644 deps/rabbitmq_tracing/priv/www/js/tmpl/traces.ejs diff --git a/deps/rabbit/scripts/rabbitmq-defaults.bat b/deps/rabbit/scripts/rabbitmq-defaults.bat index 41b3d2b47c3d..2452ba1b912e 100644 --- a/deps/rabbit/scripts/rabbitmq-defaults.bat +++ b/deps/rabbit/scripts/rabbitmq-defaults.bat @@ -1,21 +1,21 @@ -@echo off - -set SASL_BOOT_FILE=start_sasl -set CLEAN_BOOT_FILE=start_clean -set BOOT_MODULE=rabbit - -if "!RABBITMQ_BASE!"=="" ( - set RABBITMQ_BASE=!APPDATA!\RabbitMQ -) else ( - set RABBITMQ_BASE=!RABBITMQ_BASE:"=! -) - -if not exist "!RABBITMQ_BASE!" ( - mkdir "!RABBITMQ_BASE!" -) - -if "!RABBITMQ_CONF_ENV_FILE!"=="" ( - if "!CONF_ENV_FILE!"=="" ( - set CONF_ENV_FILE=!RABBITMQ_BASE!\rabbitmq-env-conf.bat - ) -) +@echo off + +set SASL_BOOT_FILE=start_sasl +set CLEAN_BOOT_FILE=start_clean +set BOOT_MODULE=rabbit + +if "!RABBITMQ_BASE!"=="" ( + set RABBITMQ_BASE=!APPDATA!\RabbitMQ +) else ( + set RABBITMQ_BASE=!RABBITMQ_BASE:"=! +) + +if not exist "!RABBITMQ_BASE!" ( + mkdir "!RABBITMQ_BASE!" +) + +if "!RABBITMQ_CONF_ENV_FILE!"=="" ( + if "!CONF_ENV_FILE!"=="" ( + set CONF_ENV_FILE=!RABBITMQ_BASE!\rabbitmq-env-conf.bat + ) +) diff --git a/deps/rabbit/scripts/rabbitmq-diagnostics.bat b/deps/rabbit/scripts/rabbitmq-diagnostics.bat index af2982559cee..d9133f74d5ab 100644 --- a/deps/rabbit/scripts/rabbitmq-diagnostics.bat +++ b/deps/rabbit/scripts/rabbitmq-diagnostics.bat @@ -1,55 +1,55 @@ -@echo off -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -REM Scopes the variables to the current batch file -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -setlocal enabledelayedexpansion - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -REM Disable erl_crash.dump by default for control scripts. -if not defined ERL_CRASH_DUMP_SECONDS ( - set ERL_CRASH_DUMP_SECONDS=0 -) - -"!ERLANG_HOME!\bin\erl.exe" +B ^ --boot !CLEAN_BOOT_FILE! ^ --noinput -noshell -hidden -smp enable ^ -!RABBITMQ_CTL_ERL_ARGS! ^ --kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ --kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ --run escript start ^ --escript main rabbitmqctl_escript ^ --extra "%RABBITMQ_HOME%\escript\rabbitmq-diagnostics" !STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -endlocal +@echo off +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +REM Scopes the variables to the current batch file +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +setlocal enabledelayedexpansion + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +REM Disable erl_crash.dump by default for control scripts. +if not defined ERL_CRASH_DUMP_SECONDS ( + set ERL_CRASH_DUMP_SECONDS=0 +) + +"!ERLANG_HOME!\bin\erl.exe" +B ^ +-boot !CLEAN_BOOT_FILE! ^ +-noinput -noshell -hidden -smp enable ^ +!RABBITMQ_CTL_ERL_ARGS! ^ +-kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ +-kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ +-run escript start ^ +-escript main rabbitmqctl_escript ^ +-extra "%RABBITMQ_HOME%\escript\rabbitmq-diagnostics" !STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +endlocal diff --git a/deps/rabbit/scripts/rabbitmq-echopid.bat b/deps/rabbit/scripts/rabbitmq-echopid.bat index 98080afd1f98..a5420518f1ad 100644 --- a/deps/rabbit/scripts/rabbitmq-echopid.bat +++ b/deps/rabbit/scripts/rabbitmq-echopid.bat @@ -1,57 +1,57 @@ -@echo off - -REM Usage: rabbitmq-echopid.bat -REM -REM (s)name of the erlang node to connect to (required) - -setlocal - -set TDP0=%~dp0 - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if "%1"=="" goto argfail - -:: set timeout vars :: -set TIMEOUT=10 -set TIMER=1 - -:: check that wmic exists :: -set WMIC_PATH=%SYSTEMROOT%\System32\Wbem\wmic.exe -if not exist "%WMIC_PATH%" ( - goto fail -) - -:getpid -for /f "usebackq tokens=* skip=1" %%P IN (`%%WMIC_PATH%% process where "name='erl.exe' and commandline like '%%%RABBITMQ_NAME_TYPE% %1%%'" get processid 2^>nul`) do ( - set PID=%%P - goto echopid -) - -:echopid -:: check for pid not found :: -if "%PID%" == "" ( - PING 127.0.0.1 -n 2 > nul - set /a TIMER+=1 - if %TIMEOUT%==%TIMER% goto fail - goto getpid -) - -:: show pid :: -echo %PID% - -:: all done :: -:ok -endlocal -EXIT /B 0 - -:: argument is required :: -:argfail -echo Please provide your RabbitMQ node name as the argument to this script. - -:: something went wrong :: -:fail -endlocal -EXIT /B 1 +@echo off + +REM Usage: rabbitmq-echopid.bat +REM +REM (s)name of the erlang node to connect to (required) + +setlocal + +set TDP0=%~dp0 + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if "%1"=="" goto argfail + +:: set timeout vars :: +set TIMEOUT=10 +set TIMER=1 + +:: check that wmic exists :: +set WMIC_PATH=%SYSTEMROOT%\System32\Wbem\wmic.exe +if not exist "%WMIC_PATH%" ( + goto fail +) + +:getpid +for /f "usebackq tokens=* skip=1" %%P IN (`%%WMIC_PATH%% process where "name='erl.exe' and commandline like '%%%RABBITMQ_NAME_TYPE% %1%%'" get processid 2^>nul`) do ( + set PID=%%P + goto echopid +) + +:echopid +:: check for pid not found :: +if "%PID%" == "" ( + PING 127.0.0.1 -n 2 > nul + set /a TIMER+=1 + if %TIMEOUT%==%TIMER% goto fail + goto getpid +) + +:: show pid :: +echo %PID% + +:: all done :: +:ok +endlocal +EXIT /B 0 + +:: argument is required :: +:argfail +echo Please provide your RabbitMQ node name as the argument to this script. + +:: something went wrong :: +:fail +endlocal +EXIT /B 1 diff --git a/deps/rabbit/scripts/rabbitmq-env.bat b/deps/rabbit/scripts/rabbitmq-env.bat index 049010556c32..567381074e1d 100644 --- a/deps/rabbit/scripts/rabbitmq-env.bat +++ b/deps/rabbit/scripts/rabbitmq-env.bat @@ -1,181 +1,181 @@ -@echo off - -REM Scopes the variables to the current batch file -REM setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -REM setlocal enabledelayedexpansion - -REM SCRIPT_DIR=`dirname $SCRIPT_PATH` -REM RABBITMQ_HOME="${SCRIPT_DIR}/.." -set SCRIPT_DIR=%TDP0% -set SCRIPT_NAME=%1 -for /f "delims=" %%F in ("%SCRIPT_DIR%..") do set RABBITMQ_HOME=%%~dpF%%~nF%%~xF - -if defined ERL_LIBS ( - set "ERL_LIBS=%RABBITMQ_HOME%\plugins;%ERL_LIBS%" -) else ( - set "ERL_LIBS=%RABBITMQ_HOME%\plugins" -) - -REM If ERLANG_HOME is not defined, check if "erl.exe" is available in -REM the path and use that. -if not defined ERLANG_HOME ( - for /f "delims=" %%F in ('powershell.exe -NoLogo -NoProfile -NonInteractive -Command "(Get-Command erl.exe).Definition"') do @set ERL_PATH=%%F - if exist "!ERL_PATH!" ( - for /f "delims=" %%F in ("!ERL_PATH!") do set ERL_DIRNAME=%%~dpF - for /f "delims=" %%F in ("!ERL_DIRNAME!\..") do @set ERLANG_HOME=%%~dpF%%~nF%%~xF - ) - set ERL_PATH= - set ERL_DIRNAME= -) - -REM ## Set defaults -call "%SCRIPT_DIR%\rabbitmq-defaults.bat" - -if "!RABBITMQ_CONF_ENV_FILE!"=="" ( - set RABBITMQ_CONF_ENV_FILE=!CONF_ENV_FILE:"=! -) else ( - set RABBITMQ_CONF_ENV_FILE=!RABBITMQ_CONF_ENV_FILE:"=! -) - -if exist "!RABBITMQ_CONF_ENV_FILE!" ( - call "!RABBITMQ_CONF_ENV_FILE!" -) - -rem Bump ETS table limit to 50000 -if "!ERL_MAX_ETS_TABLES!"=="" ( - set ERL_MAX_ETS_TABLES=50000 -) - -rem Default is defined here: -rem https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_port.h -if "!ERL_MAX_PORTS!"=="" ( - set ERL_MAX_PORTS=65536 -) - -set DEFAULT_SCHEDULER_BIND_TYPE=db -if "!RABBITMQ_SCHEDULER_BIND_TYPE!"=="" ( - set RABBITMQ_SCHEDULER_BIND_TYPE=!SCHEDULER_BIND_TYPE! -) -if "!RABBITMQ_SCHEDULER_BIND_TYPE!"=="" ( - set RABBITMQ_SCHEDULER_BIND_TYPE=!DEFAULT_SCHEDULER_BIND_TYPE! -) - -set DEFAULT_DISTRIBUTION_BUFFER_SIZE=128000 -if "!RABBITMQ_DISTRIBUTION_BUFFER_SIZE!"=="" ( - set RABBITMQ_DISTRIBUTION_BUFFER_SIZE=!DISTRIBUTION_BUFFER_SIZE! -) -if "!RABBITMQ_DISTRIBUTION_BUFFER_SIZE!"=="" ( - set RABBITMQ_DISTRIBUTION_BUFFER_SIZE=!DEFAULT_DISTRIBUTION_BUFFER_SIZE! -) - -set DEFAULT_MAX_NUMBER_OF_PROCESSES=1048576 -if "!RABBITMQ_MAX_NUMBER_OF_PROCESSES!"=="" ( - set RABBITMQ_MAX_NUMBER_OF_PROCESSES=!MAX_NUMBER_OF_PROCESSES! -) -if "!RABBITMQ_MAX_NUMBER_OF_PROCESSES!"=="" ( - set RABBITMQ_MAX_NUMBER_OF_PROCESSES=!DEFAULT_MAX_NUMBER_OF_PROCESSES! -) - -set DEFAULT_MAX_NUMBER_OF_ATOMS=5000000 -if "!RABBITMQ_MAX_NUMBER_OF_ATOMS!"=="" ( - set RABBITMQ_MAX_NUMBER_OF_ATOMS=!MAX_NUMBER_OF_ATOMS! -) -if "!RABBITMQ_MAX_NUMBER_OF_ATOMS!"=="" ( - set RABBITMQ_MAX_NUMBER_OF_ATOMS=!DEFAULT_MAX_NUMBER_OF_ATOMS! -) - -set DEFAULT_SCHEDULER_BUSY_WAIT_THRESHOLD=none -if "!RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD!"=="" ( - set RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD=!SCHEDULER_BUSY_WAIT_THRESHOLD! -) -if "!RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD!"=="" ( - set RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD=!DEFAULT_SCHEDULER_BUSY_WAIT_THRESHOLD! -) - -REM Common server defaults -set SERVER_ERL_ARGS=+P !RABBITMQ_MAX_NUMBER_OF_PROCESSES! +t !RABBITMQ_MAX_NUMBER_OF_ATOMS! +stbt !RABBITMQ_SCHEDULER_BIND_TYPE! +zdbbl !RABBITMQ_DISTRIBUTION_BUFFER_SIZE! +sbwt !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! +sbwtdcpu !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! +sbwtdio !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! - -REM ##--- Set environment vars RABBITMQ_ to defaults if not set - -REM [ "x" = "x$RABBITMQ_SERVER_ERL_ARGS" ] && RABBITMQ_SERVER_ERL_ARGS=${SERVER_ERL_ARGS} -if "!RABBITMQ_SERVER_ERL_ARGS!"=="" ( - set RABBITMQ_SERVER_ERL_ARGS=!SERVER_ERL_ARGS! -) - -REM [ "x" = "x$RABBITMQ_SERVER_START_ARGS" ] && RABBITMQ_SERVER_START_ARGS=${SERVER_START_ARGS} -if "!RABBITMQ_SERVER_START_ARGS!"=="" ( - if not "!SERVER_START_ARGS!"=="" ( - set RABBITMQ_SERVER_START_ARGS=!SERVER_START_ARGS! - ) -) - -REM [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} -if "!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS!"=="" ( - if not "!SERVER_ADDITIONAL_ERL_ARGS!"=="" ( - set RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=!SERVER_ADDITIONAL_ERL_ARGS! - ) -) - -REM [ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE} -if "!RABBITMQ_BOOT_MODULE!"=="" ( - if "!BOOT_MODULE!"=="" ( - set RABBITMQ_BOOT_MODULE=rabbit - ) else ( - set RABBITMQ_BOOT_MODULE=!BOOT_MODULE! - ) -) - -REM [ "x" = "x$RABBITMQ_CTL_ERL_ARGS" ] && RABBITMQ_CTL_ERL_ARGS=${CTL_ERL_ARGS} -if "!RABBITMQ_CTL_ERL_ARGS!"=="" ( - if not "!CTL_ERL_ARGS!"=="" ( - set RABBITMQ_CTL_ERL_ARGS=!CTL_ERL_ARGS! - ) -) - -if "!RABBITMQ_CTL_DIST_PORT_MIN!"=="" ( - if not "!CTL_DIST_PORT_MIN!"=="" ( - set RABBITMQ_CTL_DIST_PORT_MIN=!CTL_DIST_PORT_MIN! - ) -) -if "!RABBITMQ_CTL_DIST_PORT_MAX!"=="" ( - if not "!CTL_DIST_PORT_MAX!"=="" ( - set RABBITMQ_CTL_DIST_PORT_MAX=!CTL_DIST_PORT_MAX! - ) -) -if "!RABBITMQ_CTL_DIST_PORT_MIN!"=="" ( - set RABBITMQ_CTL_DIST_PORT_MIN=35672 -) -if "!RABBITMQ_CTL_DIST_PORT_MAX!"=="" ( - set /a RABBITMQ_CTL_DIST_PORT_MAX=10+!RABBITMQ_CTL_DIST_PORT_MIN! -) - -REM ADDITIONAL WINDOWS ONLY CONFIG ITEMS - -if "!RABBITMQ_SERVICENAME!"=="" ( - if "!SERVICENAME!"=="" ( - set RABBITMQ_SERVICENAME=RabbitMQ - ) else ( - set RABBITMQ_SERVICENAME=!SERVICENAME! - ) -) - -REM Environment cleanup -set BOOT_MODULE= -set CONFIG_FILE= -set FEATURE_FLAGS_FILE= -set ENABLED_PLUGINS_FILE= -set LOG_BASE= -set MNESIA_BASE= -set PLUGINS_DIR= -set SCRIPT_DIR= -set SCRIPT_NAME= -set TDP0= - -REM ##--- End of overridden variables - -REM # Since we source this elsewhere, don't accidentally stop execution -REM true +@echo off + +REM Scopes the variables to the current batch file +REM setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +REM setlocal enabledelayedexpansion + +REM SCRIPT_DIR=`dirname $SCRIPT_PATH` +REM RABBITMQ_HOME="${SCRIPT_DIR}/.." +set SCRIPT_DIR=%TDP0% +set SCRIPT_NAME=%1 +for /f "delims=" %%F in ("%SCRIPT_DIR%..") do set RABBITMQ_HOME=%%~dpF%%~nF%%~xF + +if defined ERL_LIBS ( + set "ERL_LIBS=%RABBITMQ_HOME%\plugins;%ERL_LIBS%" +) else ( + set "ERL_LIBS=%RABBITMQ_HOME%\plugins" +) + +REM If ERLANG_HOME is not defined, check if "erl.exe" is available in +REM the path and use that. +if not defined ERLANG_HOME ( + for /f "delims=" %%F in ('powershell.exe -NoLogo -NoProfile -NonInteractive -Command "(Get-Command erl.exe).Definition"') do @set ERL_PATH=%%F + if exist "!ERL_PATH!" ( + for /f "delims=" %%F in ("!ERL_PATH!") do set ERL_DIRNAME=%%~dpF + for /f "delims=" %%F in ("!ERL_DIRNAME!\..") do @set ERLANG_HOME=%%~dpF%%~nF%%~xF + ) + set ERL_PATH= + set ERL_DIRNAME= +) + +REM ## Set defaults +call "%SCRIPT_DIR%\rabbitmq-defaults.bat" + +if "!RABBITMQ_CONF_ENV_FILE!"=="" ( + set RABBITMQ_CONF_ENV_FILE=!CONF_ENV_FILE:"=! +) else ( + set RABBITMQ_CONF_ENV_FILE=!RABBITMQ_CONF_ENV_FILE:"=! +) + +if exist "!RABBITMQ_CONF_ENV_FILE!" ( + call "!RABBITMQ_CONF_ENV_FILE!" +) + +rem Bump ETS table limit to 50000 +if "!ERL_MAX_ETS_TABLES!"=="" ( + set ERL_MAX_ETS_TABLES=50000 +) + +rem Default is defined here: +rem https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_port.h +if "!ERL_MAX_PORTS!"=="" ( + set ERL_MAX_PORTS=65536 +) + +set DEFAULT_SCHEDULER_BIND_TYPE=db +if "!RABBITMQ_SCHEDULER_BIND_TYPE!"=="" ( + set RABBITMQ_SCHEDULER_BIND_TYPE=!SCHEDULER_BIND_TYPE! +) +if "!RABBITMQ_SCHEDULER_BIND_TYPE!"=="" ( + set RABBITMQ_SCHEDULER_BIND_TYPE=!DEFAULT_SCHEDULER_BIND_TYPE! +) + +set DEFAULT_DISTRIBUTION_BUFFER_SIZE=128000 +if "!RABBITMQ_DISTRIBUTION_BUFFER_SIZE!"=="" ( + set RABBITMQ_DISTRIBUTION_BUFFER_SIZE=!DISTRIBUTION_BUFFER_SIZE! +) +if "!RABBITMQ_DISTRIBUTION_BUFFER_SIZE!"=="" ( + set RABBITMQ_DISTRIBUTION_BUFFER_SIZE=!DEFAULT_DISTRIBUTION_BUFFER_SIZE! +) + +set DEFAULT_MAX_NUMBER_OF_PROCESSES=1048576 +if "!RABBITMQ_MAX_NUMBER_OF_PROCESSES!"=="" ( + set RABBITMQ_MAX_NUMBER_OF_PROCESSES=!MAX_NUMBER_OF_PROCESSES! +) +if "!RABBITMQ_MAX_NUMBER_OF_PROCESSES!"=="" ( + set RABBITMQ_MAX_NUMBER_OF_PROCESSES=!DEFAULT_MAX_NUMBER_OF_PROCESSES! +) + +set DEFAULT_MAX_NUMBER_OF_ATOMS=5000000 +if "!RABBITMQ_MAX_NUMBER_OF_ATOMS!"=="" ( + set RABBITMQ_MAX_NUMBER_OF_ATOMS=!MAX_NUMBER_OF_ATOMS! +) +if "!RABBITMQ_MAX_NUMBER_OF_ATOMS!"=="" ( + set RABBITMQ_MAX_NUMBER_OF_ATOMS=!DEFAULT_MAX_NUMBER_OF_ATOMS! +) + +set DEFAULT_SCHEDULER_BUSY_WAIT_THRESHOLD=none +if "!RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD!"=="" ( + set RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD=!SCHEDULER_BUSY_WAIT_THRESHOLD! +) +if "!RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD!"=="" ( + set RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD=!DEFAULT_SCHEDULER_BUSY_WAIT_THRESHOLD! +) + +REM Common server defaults +set SERVER_ERL_ARGS=+P !RABBITMQ_MAX_NUMBER_OF_PROCESSES! +t !RABBITMQ_MAX_NUMBER_OF_ATOMS! +stbt !RABBITMQ_SCHEDULER_BIND_TYPE! +zdbbl !RABBITMQ_DISTRIBUTION_BUFFER_SIZE! +sbwt !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! +sbwtdcpu !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! +sbwtdio !RABBITMQ_SCHEDULER_BUSY_WAIT_THRESHOLD! + +REM ##--- Set environment vars RABBITMQ_ to defaults if not set + +REM [ "x" = "x$RABBITMQ_SERVER_ERL_ARGS" ] && RABBITMQ_SERVER_ERL_ARGS=${SERVER_ERL_ARGS} +if "!RABBITMQ_SERVER_ERL_ARGS!"=="" ( + set RABBITMQ_SERVER_ERL_ARGS=!SERVER_ERL_ARGS! +) + +REM [ "x" = "x$RABBITMQ_SERVER_START_ARGS" ] && RABBITMQ_SERVER_START_ARGS=${SERVER_START_ARGS} +if "!RABBITMQ_SERVER_START_ARGS!"=="" ( + if not "!SERVER_START_ARGS!"=="" ( + set RABBITMQ_SERVER_START_ARGS=!SERVER_START_ARGS! + ) +) + +REM [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} +if "!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS!"=="" ( + if not "!SERVER_ADDITIONAL_ERL_ARGS!"=="" ( + set RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=!SERVER_ADDITIONAL_ERL_ARGS! + ) +) + +REM [ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE} +if "!RABBITMQ_BOOT_MODULE!"=="" ( + if "!BOOT_MODULE!"=="" ( + set RABBITMQ_BOOT_MODULE=rabbit + ) else ( + set RABBITMQ_BOOT_MODULE=!BOOT_MODULE! + ) +) + +REM [ "x" = "x$RABBITMQ_CTL_ERL_ARGS" ] && RABBITMQ_CTL_ERL_ARGS=${CTL_ERL_ARGS} +if "!RABBITMQ_CTL_ERL_ARGS!"=="" ( + if not "!CTL_ERL_ARGS!"=="" ( + set RABBITMQ_CTL_ERL_ARGS=!CTL_ERL_ARGS! + ) +) + +if "!RABBITMQ_CTL_DIST_PORT_MIN!"=="" ( + if not "!CTL_DIST_PORT_MIN!"=="" ( + set RABBITMQ_CTL_DIST_PORT_MIN=!CTL_DIST_PORT_MIN! + ) +) +if "!RABBITMQ_CTL_DIST_PORT_MAX!"=="" ( + if not "!CTL_DIST_PORT_MAX!"=="" ( + set RABBITMQ_CTL_DIST_PORT_MAX=!CTL_DIST_PORT_MAX! + ) +) +if "!RABBITMQ_CTL_DIST_PORT_MIN!"=="" ( + set RABBITMQ_CTL_DIST_PORT_MIN=35672 +) +if "!RABBITMQ_CTL_DIST_PORT_MAX!"=="" ( + set /a RABBITMQ_CTL_DIST_PORT_MAX=10+!RABBITMQ_CTL_DIST_PORT_MIN! +) + +REM ADDITIONAL WINDOWS ONLY CONFIG ITEMS + +if "!RABBITMQ_SERVICENAME!"=="" ( + if "!SERVICENAME!"=="" ( + set RABBITMQ_SERVICENAME=RabbitMQ + ) else ( + set RABBITMQ_SERVICENAME=!SERVICENAME! + ) +) + +REM Environment cleanup +set BOOT_MODULE= +set CONFIG_FILE= +set FEATURE_FLAGS_FILE= +set ENABLED_PLUGINS_FILE= +set LOG_BASE= +set MNESIA_BASE= +set PLUGINS_DIR= +set SCRIPT_DIR= +set SCRIPT_NAME= +set TDP0= + +REM ##--- End of overridden variables + +REM # Since we source this elsewhere, don't accidentally stop execution +REM true diff --git a/deps/rabbit/scripts/rabbitmq-plugins.bat b/deps/rabbit/scripts/rabbitmq-plugins.bat index e1f13b7073b2..81024f680643 100644 --- a/deps/rabbit/scripts/rabbitmq-plugins.bat +++ b/deps/rabbit/scripts/rabbitmq-plugins.bat @@ -1,56 +1,56 @@ -@echo off - -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -setlocal enabledelayedexpansion - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "!TDP0!\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -REM Disable erl_crash.dump by default for control scripts. -if not defined ERL_CRASH_DUMP_SECONDS ( - set ERL_CRASH_DUMP_SECONDS=0 -) - -"!ERLANG_HOME!\bin\erl.exe" +B ^ --boot !CLEAN_BOOT_FILE! ^ --noinput -noshell -hidden -smp enable ^ -!RABBITMQ_CTL_ERL_ARGS! ^ --kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ --kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ --run escript start ^ --escript main rabbitmqctl_escript ^ --extra "%RABBITMQ_HOME%\escript\rabbitmq-plugins" !STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -endlocal -endlocal +@echo off + +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +setlocal enabledelayedexpansion + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "!TDP0!\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +REM Disable erl_crash.dump by default for control scripts. +if not defined ERL_CRASH_DUMP_SECONDS ( + set ERL_CRASH_DUMP_SECONDS=0 +) + +"!ERLANG_HOME!\bin\erl.exe" +B ^ +-boot !CLEAN_BOOT_FILE! ^ +-noinput -noshell -hidden -smp enable ^ +!RABBITMQ_CTL_ERL_ARGS! ^ +-kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ +-kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ +-run escript start ^ +-escript main rabbitmqctl_escript ^ +-extra "%RABBITMQ_HOME%\escript\rabbitmq-plugins" !STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +endlocal +endlocal diff --git a/deps/rabbit/scripts/rabbitmq-queues.bat b/deps/rabbit/scripts/rabbitmq-queues.bat index 99fce6479f4a..ce90eedb76ac 100644 --- a/deps/rabbit/scripts/rabbitmq-queues.bat +++ b/deps/rabbit/scripts/rabbitmq-queues.bat @@ -1,56 +1,56 @@ -@echo off -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -REM Scopes the variables to the current batch file -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -setlocal enabledelayedexpansion - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -REM Disable erl_crash.dump by default for control scripts. -if not defined ERL_CRASH_DUMP_SECONDS ( - set ERL_CRASH_DUMP_SECONDS=0 -) - -"!ERLANG_HOME!\bin\erl.exe" +B ^ --boot !CLEAN_BOOT_FILE! ^ --noinput -noshell -hidden -smp enable ^ -!RABBITMQ_CTL_ERL_ARGS! ^ --kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ --kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ --run escript start ^ --escript main rabbitmqctl_escript ^ --extra "%RABBITMQ_HOME%\escript\rabbitmq-queues" !STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -endlocal -endlocal +@echo off +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +REM Scopes the variables to the current batch file +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +setlocal enabledelayedexpansion + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +REM Disable erl_crash.dump by default for control scripts. +if not defined ERL_CRASH_DUMP_SECONDS ( + set ERL_CRASH_DUMP_SECONDS=0 +) + +"!ERLANG_HOME!\bin\erl.exe" +B ^ +-boot !CLEAN_BOOT_FILE! ^ +-noinput -noshell -hidden -smp enable ^ +!RABBITMQ_CTL_ERL_ARGS! ^ +-kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ +-kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ +-run escript start ^ +-escript main rabbitmqctl_escript ^ +-extra "%RABBITMQ_HOME%\escript\rabbitmq-queues" !STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +endlocal +endlocal diff --git a/deps/rabbit/scripts/rabbitmq-server.bat b/deps/rabbit/scripts/rabbitmq-server.bat index 970a1014798f..107129ebeadd 100644 --- a/deps/rabbit/scripts/rabbitmq-server.bat +++ b/deps/rabbit/scripts/rabbitmq-server.bat @@ -1,92 +1,92 @@ -@echo off -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -set CONF_SCRIPT_DIR=%~dp0 -setlocal enabledelayedexpansion -setlocal enableextensions - -if ERRORLEVEL 1 ( - echo "Failed to enable command extensions!" - exit /B 1 -) - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -set RABBITMQ_DEFAULT_ALLOC_ARGS=+MBas ageffcbf +MHas ageffcbf +MBlmbcs 512 +MHlmbcs 512 +MMmcs 30 - -set RABBITMQ_START_RABBIT= -if "!RABBITMQ_ALLOW_INPUT!"=="" ( - set RABBITMQ_START_RABBIT=!RABBITMQ_START_RABBIT! -noinput -) -if "!RABBITMQ_NODE_ONLY!"=="" ( - set RABBITMQ_START_RABBIT=!RABBITMQ_START_RABBIT! -s "!RABBITMQ_BOOT_MODULE!" boot -) - -set ENV_OK=true -CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE! - -if "!ENV_OK!"=="false" ( - EXIT /b 78 -) - -if "!RABBITMQ_ALLOW_INPUT!"=="" ( - set ERL_CMD=erl.exe -) else ( - set ERL_CMD=werl.exe -) - -"!ERLANG_HOME!\bin\!ERL_CMD!" ^ -!RABBITMQ_START_RABBIT! ^ --boot "!SASL_BOOT_FILE!" ^ -+W w ^ -!RABBITMQ_DEFAULT_ALLOC_ARGS! ^ -!RABBITMQ_SERVER_ERL_ARGS! ^ -!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ -!RABBITMQ_SERVER_START_ARGS! ^ --syslog logger [] ^ --syslog syslog_error_logger false ^ --kernel prevent_overlapping_partitions false ^ -!STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -:check_not_empty -if "%~2"=="" ( - ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env and rabbitmq-defaults, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings" - set ENV_OK=false - EXIT /B 78 - ) -EXIT /B 0 - -endlocal -endlocal -endlocal +@echo off +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +set CONF_SCRIPT_DIR=%~dp0 +setlocal enabledelayedexpansion +setlocal enableextensions + +if ERRORLEVEL 1 ( + echo "Failed to enable command extensions!" + exit /B 1 +) + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +set RABBITMQ_DEFAULT_ALLOC_ARGS=+MBas ageffcbf +MHas ageffcbf +MBlmbcs 512 +MHlmbcs 512 +MMmcs 30 + +set RABBITMQ_START_RABBIT= +if "!RABBITMQ_ALLOW_INPUT!"=="" ( + set RABBITMQ_START_RABBIT=!RABBITMQ_START_RABBIT! -noinput +) +if "!RABBITMQ_NODE_ONLY!"=="" ( + set RABBITMQ_START_RABBIT=!RABBITMQ_START_RABBIT! -s "!RABBITMQ_BOOT_MODULE!" boot +) + +set ENV_OK=true +CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE! + +if "!ENV_OK!"=="false" ( + EXIT /b 78 +) + +if "!RABBITMQ_ALLOW_INPUT!"=="" ( + set ERL_CMD=erl.exe +) else ( + set ERL_CMD=werl.exe +) + +"!ERLANG_HOME!\bin\!ERL_CMD!" ^ +!RABBITMQ_START_RABBIT! ^ +-boot "!SASL_BOOT_FILE!" ^ ++W w ^ +!RABBITMQ_DEFAULT_ALLOC_ARGS! ^ +!RABBITMQ_SERVER_ERL_ARGS! ^ +!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ +!RABBITMQ_SERVER_START_ARGS! ^ +-syslog logger [] ^ +-syslog syslog_error_logger false ^ +-kernel prevent_overlapping_partitions false ^ +!STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +:check_not_empty +if "%~2"=="" ( + ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env and rabbitmq-defaults, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings" + set ENV_OK=false + EXIT /B 78 + ) +EXIT /B 0 + +endlocal +endlocal +endlocal diff --git a/deps/rabbit/scripts/rabbitmq-service.bat b/deps/rabbit/scripts/rabbitmq-service.bat index 7870417b462b..eb46d564de46 100644 --- a/deps/rabbit/scripts/rabbitmq-service.bat +++ b/deps/rabbit/scripts/rabbitmq-service.bat @@ -1,274 +1,274 @@ -@echo off -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TN0=%~n0 -set TDP0=%~dp0 -set CONF_SCRIPT_DIR=%~dp0 -set P1=%1 -setlocal enabledelayedexpansion -setlocal enableextensions - -if ERRORLEVEL 1 ( - echo "Failed to enable command extensions!" - exit /B 1 -) - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -REM Check for the short names here too -if "!RABBITMQ_USE_LONGNAME!"=="true" ( - set RABBITMQ_NAME_TYPE=-name - set NAMETYPE=longnames -) else ( - if "!USE_LONGNAME!"=="true" ( - set RABBITMQ_USE_LONGNAME=true - set RABBITMQ_NAME_TYPE=-name - set NAMETYPE=longnames - ) else ( - set RABBITMQ_USE_LONGNAME=false - set RABBITMQ_NAME_TYPE=-sname - set NAMETYPE=shortnames - ) -) - -REM [ "x" = "x$RABBITMQ_NODENAME" ] && RABBITMQ_NODENAME=${NODENAME} -if "!RABBITMQ_NODENAME!"=="" ( - if "!NODENAME!"=="" ( - REM We use Erlang to query the local hostname because - REM !COMPUTERNAME! and Erlang may return different results. - REM Start erl with -sname to make sure epmd is started. - call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -sname rabbit-prelaunch-epmd -eval "init:stop()." >nul 2>&1 - for /f "delims=" %%F in ('call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -eval "net_kernel:start([list_to_atom(""rabbit-gethostname-"" ++ os:getpid()), %NAMETYPE%]), [_, H] = string:tokens(atom_to_list(node()), ""@""), io:format(""~s~n"", [H]), init:stop()."') do @set HOSTNAME=%%F - set RABBITMQ_NODENAME=rabbit@!HOSTNAME! - set HOSTNAME= - ) else ( - set RABBITMQ_NODENAME=!NODENAME! - ) -) -set NAMETYPE= - -REM Set Erlang distribution port, based on the AMQP TCP port. -REM -REM We do this only for the Windows service because in this case, the node has -REM to start with the distribution enabled on the command line. For all other -REM cases, distribution is configured at runtime. -if "!RABBITMQ_NODE_PORT!"=="" ( - if not "!NODE_PORT!"=="" ( - set RABBITMQ_NODE_PORT=!NODE_PORT! - ) else ( - set RABBITMQ_NODE_PORT=5672 - ) -) - -if "!RABBITMQ_DIST_PORT!"=="" ( - if "!DIST_PORT!"=="" ( - if "!RABBITMQ_NODE_PORT!"=="" ( - set RABBITMQ_DIST_PORT=25672 - ) else ( - set /a RABBITMQ_DIST_PORT=20000+!RABBITMQ_NODE_PORT! - ) - ) else ( - set RABBITMQ_DIST_PORT=!DIST_PORT! - ) -) - -set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT! - -set STARVAR= -shift -:loop1 -if "%1"=="" goto after_loop - set STARVAR=%STARVAR% %1 - shift -goto loop1 -:after_loop - -if "!ERLANG_SERVICE_MANAGER_PATH!"=="" ( - if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B - ) - for /f "delims=" %%i in ('dir /ad/b "!ERLANG_HOME!"') do if exist "!ERLANG_HOME!\%%i\bin\erlsrv.exe" ( - set ERLANG_SERVICE_MANAGER_PATH=!ERLANG_HOME!\%%i\bin - ) -) - -set CONSOLE_FLAG= -set CONSOLE_LOG_VALID= -for %%i in (new reuse) do if "%%i" == "!RABBITMQ_CONSOLE_LOG!" set CONSOLE_LOG_VALID=TRUE -if "!CONSOLE_LOG_VALID!" == "TRUE" ( - set CONSOLE_FLAG=-debugtype !RABBITMQ_CONSOLE_LOG! -) - -rem *** End of configuration *** - -if not exist "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" ( - echo. - echo ********************************************** - echo ERLANG_SERVICE_MANAGER_PATH not set correctly. - echo ********************************************** - echo. - echo "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" not found - echo Please set ERLANG_SERVICE_MANAGER_PATH to the folder containing "erlsrv.exe". - echo. - exit /B 1 -) - -if "!P1!" == "install" goto INSTALL_SERVICE -for %%i in (start stop) do if "%%i" == "!P1!" goto START_STOP_SERVICE -for %%i in (disable enable list remove) do if "%%i" == "!P1!" goto MODIFY_SERVICE - -echo. -echo ********************* -echo Service control usage -echo ********************* -echo. -echo !TN0! help - Display this help -echo !TN0! install - Install the !RABBITMQ_SERVICENAME! service -echo !TN0! remove - Remove the !RABBITMQ_SERVICENAME! service -echo. -echo The following actions can also be accomplished by using -echo Windows Services Management Console (services.msc): -echo. -echo !TN0! start - Start the !RABBITMQ_SERVICENAME! service -echo !TN0! stop - Stop the !RABBITMQ_SERVICENAME! service -echo !TN0! disable - Disable the !RABBITMQ_SERVICENAME! service -echo !TN0! enable - Enable the !RABBITMQ_SERVICENAME! service -echo. -exit /B - - -:INSTALL_SERVICE - -if not exist "!RABBITMQ_BASE!" ( - echo Creating base directory !RABBITMQ_BASE! & mkdir "!RABBITMQ_BASE!" -) - -"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" list !RABBITMQ_SERVICENAME! 2>NUL 1>NUL -if errorlevel 1 ( - "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" add !RABBITMQ_SERVICENAME! -internalservicename !RABBITMQ_SERVICENAME! -) else ( - echo !RABBITMQ_SERVICENAME! service is already present - only updating service parameters -) - -set RABBITMQ_DEFAULT_ALLOC_ARGS=+MBas ageffcbf +MHas ageffcbf +MBlmbcs 512 +MHlmbcs 512 +MMmcs 30 - -set RABBITMQ_START_RABBIT= -if "!RABBITMQ_NODE_ONLY!"=="" ( - set RABBITMQ_START_RABBIT=-s "!RABBITMQ_BOOT_MODULE!" boot -) - -if "!RABBITMQ_SERVICE_RESTART!"=="" ( - set RABBITMQ_SERVICE_RESTART=restart -) - -set ENV_OK=true -CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE! -CALL :check_not_empty "RABBITMQ_NAME_TYPE" !RABBITMQ_NAME_TYPE! -CALL :check_not_empty "RABBITMQ_NODENAME" !RABBITMQ_NODENAME! - -if "!ENV_OK!"=="false" ( - EXIT /b 78 -) - -set ERLANG_SERVICE_ARGUMENTS= ^ -!RABBITMQ_START_RABBIT! ^ --boot "!SASL_BOOT_FILE!" ^ -+W w ^ -!RABBITMQ_DEFAULT_ALLOC_ARGS! ^ -!RABBITMQ_SERVER_ERL_ARGS! ^ -!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ -!RABBITMQ_SERVER_START_ARGS! ^ -!RABBITMQ_DIST_ARG! ^ --syslog logger [] ^ --syslog syslog_error_logger false ^ --kernel prevent_overlapping_partitions false ^ -!STARVAR! - -set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\! -set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:"=\"! - -rem We resolve %APPDATA% at install time so that the user's %APPDATA% -rem is passed to `rabbit_env` at runtime (instead of the service's -rem %APPDAT%). -rem -rem The goal is to keep the same behavior as when RabbitMQ data -rem locations were decided in `rabbitmq-env.bat` (sourced by this -rem script), even if now, we compute everything in `rabbit_env` at -rem runtime. -rem -rem We may revisit this in the future so that no data is stored in a -rem user-specific directory. -"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" set !RABBITMQ_SERVICENAME! ^ --onfail !RABBITMQ_SERVICE_RESTART! ^ --machine "!ERLANG_SERVICE_MANAGER_PATH!\erl.exe" ^ --env APPDATA="!APPDATA!" ^ --env ERL_LIBS="!ERL_LIBS!" ^ --env ERL_MAX_ETS_TABLES="!ERL_MAX_ETS_TABLES!" ^ --env ERL_MAX_PORTS="!ERL_MAX_PORTS!" ^ --env RABBITMQ_BASE="!RABBITMQ_BASE!" ^ --env RABBITMQ_NODENAME="!RABBITMQ_NODENAME!" ^ --workdir "!RABBITMQ_BASE!" ^ --stopaction "rabbit:stop_and_halt()." ^ -!RABBITMQ_NAME_TYPE! !RABBITMQ_NODENAME! ^ -!CONSOLE_FLAG! ^ --comment "Multi-protocol open source messaging broker" ^ --args "!ERLANG_SERVICE_ARGUMENTS!" > NUL - -if ERRORLEVEL 1 ( - EXIT /B 1 -) -goto END - - -:MODIFY_SERVICE - -"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" !P1! !RABBITMQ_SERVICENAME! -if ERRORLEVEL 1 ( - EXIT /B 1 -) -goto END - - -:START_STOP_SERVICE - -REM start and stop via erlsrv reports no error message. Using net instead -net !P1! !RABBITMQ_SERVICENAME! -if ERRORLEVEL 1 ( - EXIT /B 1 -) -goto END - -:END - -EXIT /B 0 - -:check_not_empty -if "%~2"=="" ( - ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env, rabbitmq-default, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings" - set ENV_OK=false - EXIT /B 78 - ) -EXIT /B 0 - -endlocal -endlocal -endlocal +@echo off +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TN0=%~n0 +set TDP0=%~dp0 +set CONF_SCRIPT_DIR=%~dp0 +set P1=%1 +setlocal enabledelayedexpansion +setlocal enableextensions + +if ERRORLEVEL 1 ( + echo "Failed to enable command extensions!" + exit /B 1 +) + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +REM Check for the short names here too +if "!RABBITMQ_USE_LONGNAME!"=="true" ( + set RABBITMQ_NAME_TYPE=-name + set NAMETYPE=longnames +) else ( + if "!USE_LONGNAME!"=="true" ( + set RABBITMQ_USE_LONGNAME=true + set RABBITMQ_NAME_TYPE=-name + set NAMETYPE=longnames + ) else ( + set RABBITMQ_USE_LONGNAME=false + set RABBITMQ_NAME_TYPE=-sname + set NAMETYPE=shortnames + ) +) + +REM [ "x" = "x$RABBITMQ_NODENAME" ] && RABBITMQ_NODENAME=${NODENAME} +if "!RABBITMQ_NODENAME!"=="" ( + if "!NODENAME!"=="" ( + REM We use Erlang to query the local hostname because + REM !COMPUTERNAME! and Erlang may return different results. + REM Start erl with -sname to make sure epmd is started. + call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -sname rabbit-prelaunch-epmd -eval "init:stop()." >nul 2>&1 + for /f "delims=" %%F in ('call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -eval "net_kernel:start([list_to_atom(""rabbit-gethostname-"" ++ os:getpid()), %NAMETYPE%]), [_, H] = string:tokens(atom_to_list(node()), ""@""), io:format(""~s~n"", [H]), init:stop()."') do @set HOSTNAME=%%F + set RABBITMQ_NODENAME=rabbit@!HOSTNAME! + set HOSTNAME= + ) else ( + set RABBITMQ_NODENAME=!NODENAME! + ) +) +set NAMETYPE= + +REM Set Erlang distribution port, based on the AMQP TCP port. +REM +REM We do this only for the Windows service because in this case, the node has +REM to start with the distribution enabled on the command line. For all other +REM cases, distribution is configured at runtime. +if "!RABBITMQ_NODE_PORT!"=="" ( + if not "!NODE_PORT!"=="" ( + set RABBITMQ_NODE_PORT=!NODE_PORT! + ) else ( + set RABBITMQ_NODE_PORT=5672 + ) +) + +if "!RABBITMQ_DIST_PORT!"=="" ( + if "!DIST_PORT!"=="" ( + if "!RABBITMQ_NODE_PORT!"=="" ( + set RABBITMQ_DIST_PORT=25672 + ) else ( + set /a RABBITMQ_DIST_PORT=20000+!RABBITMQ_NODE_PORT! + ) + ) else ( + set RABBITMQ_DIST_PORT=!DIST_PORT! + ) +) + +set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT! + +set STARVAR= +shift +:loop1 +if "%1"=="" goto after_loop + set STARVAR=%STARVAR% %1 + shift +goto loop1 +:after_loop + +if "!ERLANG_SERVICE_MANAGER_PATH!"=="" ( + if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B + ) + for /f "delims=" %%i in ('dir /ad/b "!ERLANG_HOME!"') do if exist "!ERLANG_HOME!\%%i\bin\erlsrv.exe" ( + set ERLANG_SERVICE_MANAGER_PATH=!ERLANG_HOME!\%%i\bin + ) +) + +set CONSOLE_FLAG= +set CONSOLE_LOG_VALID= +for %%i in (new reuse) do if "%%i" == "!RABBITMQ_CONSOLE_LOG!" set CONSOLE_LOG_VALID=TRUE +if "!CONSOLE_LOG_VALID!" == "TRUE" ( + set CONSOLE_FLAG=-debugtype !RABBITMQ_CONSOLE_LOG! +) + +rem *** End of configuration *** + +if not exist "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" ( + echo. + echo ********************************************** + echo ERLANG_SERVICE_MANAGER_PATH not set correctly. + echo ********************************************** + echo. + echo "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" not found + echo Please set ERLANG_SERVICE_MANAGER_PATH to the folder containing "erlsrv.exe". + echo. + exit /B 1 +) + +if "!P1!" == "install" goto INSTALL_SERVICE +for %%i in (start stop) do if "%%i" == "!P1!" goto START_STOP_SERVICE +for %%i in (disable enable list remove) do if "%%i" == "!P1!" goto MODIFY_SERVICE + +echo. +echo ********************* +echo Service control usage +echo ********************* +echo. +echo !TN0! help - Display this help +echo !TN0! install - Install the !RABBITMQ_SERVICENAME! service +echo !TN0! remove - Remove the !RABBITMQ_SERVICENAME! service +echo. +echo The following actions can also be accomplished by using +echo Windows Services Management Console (services.msc): +echo. +echo !TN0! start - Start the !RABBITMQ_SERVICENAME! service +echo !TN0! stop - Stop the !RABBITMQ_SERVICENAME! service +echo !TN0! disable - Disable the !RABBITMQ_SERVICENAME! service +echo !TN0! enable - Enable the !RABBITMQ_SERVICENAME! service +echo. +exit /B + + +:INSTALL_SERVICE + +if not exist "!RABBITMQ_BASE!" ( + echo Creating base directory !RABBITMQ_BASE! & mkdir "!RABBITMQ_BASE!" +) + +"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" list !RABBITMQ_SERVICENAME! 2>NUL 1>NUL +if errorlevel 1 ( + "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" add !RABBITMQ_SERVICENAME! -internalservicename !RABBITMQ_SERVICENAME! +) else ( + echo !RABBITMQ_SERVICENAME! service is already present - only updating service parameters +) + +set RABBITMQ_DEFAULT_ALLOC_ARGS=+MBas ageffcbf +MHas ageffcbf +MBlmbcs 512 +MHlmbcs 512 +MMmcs 30 + +set RABBITMQ_START_RABBIT= +if "!RABBITMQ_NODE_ONLY!"=="" ( + set RABBITMQ_START_RABBIT=-s "!RABBITMQ_BOOT_MODULE!" boot +) + +if "!RABBITMQ_SERVICE_RESTART!"=="" ( + set RABBITMQ_SERVICE_RESTART=restart +) + +set ENV_OK=true +CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE! +CALL :check_not_empty "RABBITMQ_NAME_TYPE" !RABBITMQ_NAME_TYPE! +CALL :check_not_empty "RABBITMQ_NODENAME" !RABBITMQ_NODENAME! + +if "!ENV_OK!"=="false" ( + EXIT /b 78 +) + +set ERLANG_SERVICE_ARGUMENTS= ^ +!RABBITMQ_START_RABBIT! ^ +-boot "!SASL_BOOT_FILE!" ^ ++W w ^ +!RABBITMQ_DEFAULT_ALLOC_ARGS! ^ +!RABBITMQ_SERVER_ERL_ARGS! ^ +!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ +!RABBITMQ_SERVER_START_ARGS! ^ +!RABBITMQ_DIST_ARG! ^ +-syslog logger [] ^ +-syslog syslog_error_logger false ^ +-kernel prevent_overlapping_partitions false ^ +!STARVAR! + +set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\! +set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:"=\"! + +rem We resolve %APPDATA% at install time so that the user's %APPDATA% +rem is passed to `rabbit_env` at runtime (instead of the service's +rem %APPDAT%). +rem +rem The goal is to keep the same behavior as when RabbitMQ data +rem locations were decided in `rabbitmq-env.bat` (sourced by this +rem script), even if now, we compute everything in `rabbit_env` at +rem runtime. +rem +rem We may revisit this in the future so that no data is stored in a +rem user-specific directory. +"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" set !RABBITMQ_SERVICENAME! ^ +-onfail !RABBITMQ_SERVICE_RESTART! ^ +-machine "!ERLANG_SERVICE_MANAGER_PATH!\erl.exe" ^ +-env APPDATA="!APPDATA!" ^ +-env ERL_LIBS="!ERL_LIBS!" ^ +-env ERL_MAX_ETS_TABLES="!ERL_MAX_ETS_TABLES!" ^ +-env ERL_MAX_PORTS="!ERL_MAX_PORTS!" ^ +-env RABBITMQ_BASE="!RABBITMQ_BASE!" ^ +-env RABBITMQ_NODENAME="!RABBITMQ_NODENAME!" ^ +-workdir "!RABBITMQ_BASE!" ^ +-stopaction "rabbit:stop_and_halt()." ^ +!RABBITMQ_NAME_TYPE! !RABBITMQ_NODENAME! ^ +!CONSOLE_FLAG! ^ +-comment "Multi-protocol open source messaging broker" ^ +-args "!ERLANG_SERVICE_ARGUMENTS!" > NUL + +if ERRORLEVEL 1 ( + EXIT /B 1 +) +goto END + + +:MODIFY_SERVICE + +"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" !P1! !RABBITMQ_SERVICENAME! +if ERRORLEVEL 1 ( + EXIT /B 1 +) +goto END + + +:START_STOP_SERVICE + +REM start and stop via erlsrv reports no error message. Using net instead +net !P1! !RABBITMQ_SERVICENAME! +if ERRORLEVEL 1 ( + EXIT /B 1 +) +goto END + +:END + +EXIT /B 0 + +:check_not_empty +if "%~2"=="" ( + ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env, rabbitmq-default, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings" + set ENV_OK=false + EXIT /B 78 + ) +EXIT /B 0 + +endlocal +endlocal +endlocal diff --git a/deps/rabbit/scripts/rabbitmq-streams.bat b/deps/rabbit/scripts/rabbitmq-streams.bat index 532094f5590c..eac6754d59d7 100644 --- a/deps/rabbit/scripts/rabbitmq-streams.bat +++ b/deps/rabbit/scripts/rabbitmq-streams.bat @@ -1,55 +1,55 @@ -@echo off - -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. -REM - -REM Scopes the variables to the current batch file -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -setlocal enabledelayedexpansion - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -REM Disable erl_crash.dump by default for control scripts. -if not defined ERL_CRASH_DUMP_SECONDS ( - set ERL_CRASH_DUMP_SECONDS=0 -) - -"!ERLANG_HOME!\bin\erl.exe" +B ^ --boot !CLEAN_BOOT_FILE! ^ --noinput -noshell -hidden -smp enable ^ -!RABBITMQ_CTL_ERL_ARGS! ^ --run escript start ^ --escript main rabbitmqctl_escript ^ --extra "%RABBITMQ_HOME%\escript\rabbitmq-streams" !STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -endlocal -endlocal +@echo off + +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. +REM + +REM Scopes the variables to the current batch file +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +setlocal enabledelayedexpansion + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +REM Disable erl_crash.dump by default for control scripts. +if not defined ERL_CRASH_DUMP_SECONDS ( + set ERL_CRASH_DUMP_SECONDS=0 +) + +"!ERLANG_HOME!\bin\erl.exe" +B ^ +-boot !CLEAN_BOOT_FILE! ^ +-noinput -noshell -hidden -smp enable ^ +!RABBITMQ_CTL_ERL_ARGS! ^ +-run escript start ^ +-escript main rabbitmqctl_escript ^ +-extra "%RABBITMQ_HOME%\escript\rabbitmq-streams" !STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +endlocal +endlocal diff --git a/deps/rabbit/scripts/rabbitmqctl.bat b/deps/rabbit/scripts/rabbitmqctl.bat index 711ec6e990ec..2fd4a19dada6 100644 --- a/deps/rabbit/scripts/rabbitmqctl.bat +++ b/deps/rabbit/scripts/rabbitmqctl.bat @@ -1,56 +1,56 @@ -@echo off -REM This Source Code Form is subject to the terms of the Mozilla Public -REM License, v. 2.0. If a copy of the MPL was not distributed with this -REM file, You can obtain one at https://mozilla.org/MPL/2.0/. -REM -REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. -REM - -REM Scopes the variables to the current batch file -setlocal - -rem Preserve values that might contain exclamation marks before -rem enabling delayed expansion -set TDP0=%~dp0 -set STAR=%* -setlocal enabledelayedexpansion - -REM Get default settings with user overrides for (RABBITMQ_) -REM Non-empty defaults should be set in rabbitmq-env -call "%TDP0%\rabbitmq-env.bat" %~n0 - -if not exist "!ERLANG_HOME!\bin\erl.exe" ( - echo. - echo ****************************** - echo ERLANG_HOME not set correctly. - echo ****************************** - echo. - echo Please either set ERLANG_HOME to point to your Erlang installation or place the - echo RabbitMQ server distribution in the Erlang lib folder. - echo. - exit /B 1 -) - -REM Disable erl_crash.dump by default for control scripts. -if not defined ERL_CRASH_DUMP_SECONDS ( - set ERL_CRASH_DUMP_SECONDS=0 -) - -"!ERLANG_HOME!\bin\erl.exe" +B ^ --boot !CLEAN_BOOT_FILE! ^ --noinput -noshell -hidden -smp enable ^ -!RABBITMQ_CTL_ERL_ARGS! ^ --kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ --kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ --run escript start ^ --escript main rabbitmqctl_escript ^ --extra "%RABBITMQ_HOME%\escript\rabbitmqctl" !STAR! - -if ERRORLEVEL 1 ( - exit /B %ERRORLEVEL% -) - -EXIT /B 0 - -endlocal -endlocal +@echo off +REM This Source Code Form is subject to the terms of the Mozilla Public +REM License, v. 2.0. If a copy of the MPL was not distributed with this +REM file, You can obtain one at https://mozilla.org/MPL/2.0/. +REM +REM Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +REM + +REM Scopes the variables to the current batch file +setlocal + +rem Preserve values that might contain exclamation marks before +rem enabling delayed expansion +set TDP0=%~dp0 +set STAR=%* +setlocal enabledelayedexpansion + +REM Get default settings with user overrides for (RABBITMQ_) +REM Non-empty defaults should be set in rabbitmq-env +call "%TDP0%\rabbitmq-env.bat" %~n0 + +if not exist "!ERLANG_HOME!\bin\erl.exe" ( + echo. + echo ****************************** + echo ERLANG_HOME not set correctly. + echo ****************************** + echo. + echo Please either set ERLANG_HOME to point to your Erlang installation or place the + echo RabbitMQ server distribution in the Erlang lib folder. + echo. + exit /B 1 +) + +REM Disable erl_crash.dump by default for control scripts. +if not defined ERL_CRASH_DUMP_SECONDS ( + set ERL_CRASH_DUMP_SECONDS=0 +) + +"!ERLANG_HOME!\bin\erl.exe" +B ^ +-boot !CLEAN_BOOT_FILE! ^ +-noinput -noshell -hidden -smp enable ^ +!RABBITMQ_CTL_ERL_ARGS! ^ +-kernel inet_dist_listen_min !RABBITMQ_CTL_DIST_PORT_MIN! ^ +-kernel inet_dist_listen_max !RABBITMQ_CTL_DIST_PORT_MAX! ^ +-run escript start ^ +-escript main rabbitmqctl_escript ^ +-extra "%RABBITMQ_HOME%\escript\rabbitmqctl" !STAR! + +if ERRORLEVEL 1 ( + exit /B %ERRORLEVEL% +) + +EXIT /B 0 + +endlocal +endlocal diff --git a/deps/rabbit_common/mk/xrefr b/deps/rabbit_common/mk/xrefr deleted file mode 100755 index 03c408fcb43f..000000000000 --- a/deps/rabbit_common/mk/xrefr +++ /dev/null @@ -1,338 +0,0 @@ -#!/usr/bin/env escript -%% vim:ft=erlang: - -%% The code is copied from xref_runner. -%% https://github.com/inaka/xref_runner -%% -%% The only change is the support of our erlang_version_support -%% attribute: we don't want any warnings about functions which will be -%% dropped at load time. -%% -%% It's also a plain text escript instead of a compiled one because we -%% want to support Erlang R16B03 and the version of xref_runner uses -%% maps and is built with something like Erlang 18. - -%% This mode allows us to reference local function. For instance: -%% lists:map(fun generate_comment/1, Comments) --mode(compile). - --define(DIRS, ["ebin", "test"]). - --define(CHECKS, [undefined_function_calls, - undefined_functions, - locals_not_used]). - -main(_) -> - Checks = ?CHECKS, - ElixirDeps = get_elixir_deps_paths(), - [true = code:add_path(P) || P <- ElixirDeps], - XrefWarnings = lists:append([check(Check) || Check <- Checks]), - warnings_prn(XrefWarnings), - case XrefWarnings of - [] -> ok; - _ -> halt(1) - end. - -get_elixir_deps_paths() -> - case os:getenv("ERLANG_MK_RECURSIVE_DEPS_LIST") of - false -> - []; - Filename -> - {ok, Fd} = file:open(Filename, [read]), - get_elixir_deps_paths1(Fd, []) - end. - -get_elixir_deps_paths1(Fd, Paths) -> - case file:read_line(Fd) of - {ok, Line0} -> - Line = Line0 -- [$\r, $\n], - RootPath = case os:type() of - {unix, _} -> - Line; - {win32, _} -> - case os:find_executable("cygpath.exe") of - false -> - Line; - Cygpath -> - os:cmd( - io_lib:format("~s --windows \"~s\"", - [Cygpath, Line])) - -- [$\r, $\n] - end - end, - Glob = filename:join([RootPath, "_build", "dev", "lib", "*", "ebin"]), - NewPaths = filelib:wildcard(Glob), - get_elixir_deps_paths1(Fd, Paths ++ NewPaths); - eof -> - add_elixir_stdlib_path(Paths) - end. - -add_elixir_stdlib_path(Paths) -> - case find_elixir_home() of - false -> Paths; - ElixirLibDir -> [ElixirLibDir | Paths] - end. - -find_elixir_home() -> - ElixirExe = case os:type() of - {unix, _} -> "elixir"; - {win32, _} -> "elixir.bat" - end, - case os:find_executable(ElixirExe) of - false -> false; - ExePath -> resolve_symlink(ExePath) - end. - -resolve_symlink(ExePath) -> - case file:read_link_all(ExePath) of - {error, einval} -> - determine_elixir_home(ExePath); - {ok, ResolvedLink} -> - ExePath1 = filename:absname(ResolvedLink, - filename:dirname(ExePath)), - resolve_symlink(ExePath1); - {error, _} -> - false - end. - -determine_elixir_home(ExePath) -> - LibPath = filename:join([filename:dirname(filename:dirname(ExePath)), - "lib", - "elixir", - "ebin"]), - case filelib:is_dir(LibPath) of - true -> LibPath; - false -> {skip, "Failed to locate Elixir lib dir"} - end. -check(Check) -> - Dirs = ?DIRS, - lists:foreach(fun code:add_path/1, Dirs), - - {ok, Xref} = xref:start([]), - try - ok = xref:set_library_path(Xref, code:get_path()), - - lists:foreach( - fun(Dir) -> - case filelib:is_dir(Dir) of - true -> {ok, _} = xref:add_directory(Xref, Dir); - false -> ok - end - end, Dirs), - - {ok, Results} = xref:analyze(Xref, Check), - - FilteredResults = filter_xref_results(Check, Results), - - [result_to_warning(Check, Result) || Result <- FilteredResults] - after - stopped = xref:stop(Xref) - end. - -%% ------------------------------------------------------------------- -%% Filtering results. -%% ------------------------------------------------------------------- - -filter_xref_results(Check, Results) -> - SourceModules = - lists:usort([source_module(Result) || Result <- Results]), - - Ignores = lists:flatmap( - fun(Module) -> get_ignorelist(Module, Check) end, SourceModules), - - UnusedFunctions = lists:flatmap( - fun(Mod) -> get_unused_compat_functions(Mod) end, - SourceModules), - - ToIgnore = case get(results_to_ignore) of - undefined -> []; - RTI -> RTI - end, - NewToIgnore = [parse_xref_target(Result) - || Result <- Results, - lists:member(parse_xref_source(Result), UnusedFunctions)], - AllToIgnore = ToIgnore ++ NewToIgnore ++ [mfa(M, {F, A}) - || {_, {M, F, A}} <- Ignores], - put(results_to_ignore, AllToIgnore), - - [Result || Result <- Results, - not lists:member(parse_xref_result(Result), Ignores) andalso - not lists:member(parse_xref_result(Result), AllToIgnore) andalso - not lists:member(parse_xref_source(Result), UnusedFunctions)]. - -source_module({Mt, _Ft, _At}) -> Mt; -source_module({{Ms, _Fs, _As}, _Target}) -> Ms. - -%% -%% Ignore behaviour functions, and explicitly marked functions -%% -%% Functions can be ignored by using -%% -ignore_xref([{F, A}, {M, F, A}...]). -get_ignorelist(Mod, Check) -> - %% Get ignore_xref attribute and combine them in one list - Attributes = - try - Mod:module_info(attributes) - catch - _Class:_Error -> [] - end, - - IgnoreXref = - [mfa(Mod, Value) || {ignore_xref, Values} <- Attributes, Value <- Values], - - BehaviourCallbacks = get_behaviour_callbacks(Check, Mod, Attributes), - - %% And create a flat {M, F, A} list - IgnoreXref ++ BehaviourCallbacks. - -get_behaviour_callbacks(exports_not_used, Mod, Attributes) -> - Behaviours = [Value || {behaviour, Values} <- Attributes, Value <- Values], - [{Mod, {Mod, F, A}} - || B <- Behaviours, {F, A} <- B:behaviour_info(callbacks)]; -get_behaviour_callbacks(_Check, _Mod, _Attributes) -> - []. - -get_unused_compat_functions(Module) -> - OTPVersion = code_version:get_otp_version(), - Attributes = try - Module:module_info(attributes) - catch - _Class:_Error -> [] - end, - CompatTuples = [Tuple - || {erlang_version_support, Tuples} <- Attributes, - Tuple <- Tuples], - get_unused_compat_functions(Module, OTPVersion, CompatTuples, []). - -get_unused_compat_functions(_, _, [], Result) -> - Result; -get_unused_compat_functions(Module, - OTPVersion, - [{MinOTPVersion, Choices} | Rest], - Result) -> - Functions = lists:map( - fun({_, Arity, Pre, Post}) -> - if - OTPVersion >= MinOTPVersion -> - %% We ignore the "pre" function. - mfa(Module, {Pre, Arity}); - true -> - %% We ignore the "post" function. - mfa(Module, {Post, Arity}) - end - end, Choices), - get_unused_compat_functions(Module, OTPVersion, Rest, - Result ++ Functions). - -mfa(M, {F, A}) -> {M, {M, F, A}}; -mfa(M, MFA) -> {M, MFA}. - -parse_xref_result({{SM, _, _}, MFAt}) -> {SM, MFAt}; -parse_xref_result({TM, _, _} = MFAt) -> {TM, MFAt}. - -parse_xref_source({{SM, _, _} = MFAt, _}) -> {SM, MFAt}; -parse_xref_source({TM, _, _} = MFAt) -> {TM, MFAt}. - -parse_xref_target({_, {TM, _, _} = MFAt}) -> {TM, MFAt}; -parse_xref_target({TM, _, _} = MFAt) -> {TM, MFAt}. - -%% ------------------------------------------------------------------- -%% Preparing results. -%% ------------------------------------------------------------------- - -result_to_warning(Check, {MFASource, MFATarget}) -> - {Filename, Line} = get_source(MFASource), - [{filename, Filename}, - {line, Line}, - {source, MFASource}, - {target, MFATarget}, - {check, Check}]; -result_to_warning(Check, MFA) -> - {Filename, Line} = get_source(MFA), - [{filename, Filename}, - {line, Line}, - {source, MFA}, - {check, Check}]. - -%% -%% Given a MFA, find the file and LOC where it's defined. Note that -%% xref doesn't work if there is no abstract_code, so we can avoid -%% being too paranoid here. -%% -get_source({M, F, A}) -> - case code:get_object_code(M) of - error -> {"", 0}; - {M, Bin, _} -> find_function_source(M, F, A, Bin) - end. - -find_function_source(M, F, A, Bin) -> - AbstractCode = beam_lib:chunks(Bin, [abstract_code]), - {ok, {M, [{abstract_code, {raw_abstract_v1, Code}}]}} = AbstractCode, - - %% Extract the original source filename from the abstract code - [Source|_] = [S || {attribute, _, file, {S, _}} <- Code], - - %% Extract the line number for a given function def - Fn = [E || E <- Code, - element(1, E) == function, - element(3, E) == F, - element(4, E) == A], - - case Fn of - [{function, Line, F, _, _}] when is_integer(Line) -> - {Source, Line}; - [{function, Line, F, _, _}] -> - {Source, erl_anno:line(Line)}; - %% do not crash if functions are exported, even though they - %% are not in the source. - %% parameterized modules add new/1 and instance/1 for example. - [] -> {Source, 0} - end. - -%% ------------------------------------------------------------------- -%% Reporting results. -%% ------------------------------------------------------------------- - -warnings_prn([]) -> - ok; -warnings_prn(Comments) -> - Messages = lists:map(fun generate_comment/1, Comments), - lists:foreach(fun warning_prn/1, Messages). - -warning_prn(Message) -> - FullMessage = Message ++ "~n", - io:format(FullMessage, []). - -generate_comment(XrefWarning) -> - Filename = proplists:get_value(filename, XrefWarning), - Line = proplists:get_value(line, XrefWarning), - Source = proplists:get_value(source, XrefWarning), - Check = proplists:get_value(check, XrefWarning), - Target = proplists:get_value(target, XrefWarning), - Position = case {Filename, Line} of - {"", _} -> ""; - {Filename, 0} -> [Filename, " "]; - {Filename, Line} -> [Filename, ":", - integer_to_list(Line), " "] - end, - [Position, generate_comment_text(Check, Source, Target)]. - -generate_comment_text(Check, {SM, SF, SA}, TMFA) -> - SMFA = io_lib:format("`~p:~p/~p`", [SM, SF, SA]), - generate_comment_text(Check, SMFA, TMFA); -generate_comment_text(Check, SMFA, {TM, TF, TA}) -> - TMFA = io_lib:format("`~p:~p/~p`", [TM, TF, TA]), - generate_comment_text(Check, SMFA, TMFA); - -generate_comment_text(undefined_function_calls, SMFA, TMFA) -> - io_lib:format("~s calls undefined function ~s", [SMFA, TMFA]); -generate_comment_text(undefined_functions, SMFA, _TMFA) -> - io_lib:format("~s is not defined as a function", [SMFA]); -generate_comment_text(locals_not_used, SMFA, _TMFA) -> - io_lib:format("~s is an unused local function", [SMFA]); -generate_comment_text(exports_not_used, SMFA, _TMFA) -> - io_lib:format("~s is an unused export", [SMFA]); -generate_comment_text(deprecated_function_calls, SMFA, TMFA) -> - io_lib:format("~s calls deprecated function ~s", [SMFA, TMFA]); -generate_comment_text(deprecated_functions, SMFA, _TMFA) -> - io_lib:format("~s is deprecated", [SMFA]). diff --git a/deps/rabbitmq_amqp1_0/test/system_SUITE_data/java-tests/mvnw.cmd b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/java-tests/mvnw.cmd index a5284c79395d..fef5a8f7f988 100755 --- a/deps/rabbitmq_amqp1_0/test/system_SUITE_data/java-tests/mvnw.cmd +++ b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/java-tests/mvnw.cmd @@ -1,161 +1,161 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_php/var/log.log b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_php/var/log.log deleted file mode 100755 index e69de29bb2d1..000000000000 diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/App_Start/WebApiConfig.cs b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/App_Start/WebApiConfig.cs index bd11ca20c490..31a428c9512d 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/App_Start/WebApiConfig.cs +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/App_Start/WebApiConfig.cs @@ -1,12 +1,12 @@ -using System.Web.Http; - -namespace WebApiHttpAuthService -{ - public static class WebApiConfig - { - public static void Register(HttpConfiguration config) - { - config.MapHttpAttributeRoutes(); - } - } -} +using System.Web.Http; + +namespace WebApiHttpAuthService +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + config.MapHttpAttributeRoutes(); + } + } +} diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Controllers/AuthController.cs b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Controllers/AuthController.cs index 8282d1407e1e..a1529b11dd13 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Controllers/AuthController.cs +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Controllers/AuthController.cs @@ -1,143 +1,143 @@ -using System; -using System.Net; -using System.Net.Http; -using System.Net.Http.Formatting; -using System.Text; -using System.Web.Http; - -namespace WebApiHttpAuthService.Controllers -{ - [RoutePrefix("auth")] - public class AuthController : ApiController - { - // Note: the following is necessary to ensure that no - // BOM is part of the response - private static readonly UTF8Encoding encoding = new UTF8Encoding(false); - - [Route("user")] - [HttpPost] - public HttpResponseMessage user(FormDataCollection form) - { - string content = "allow administrator management"; - try - { - if (form != null) - { - string username = form.Get("username"); - string password = form.Get("password"); - - if(username=="authuser") //Sample check you can put your custom logic over here - content = "deny"; - - string userlog = string.Format("user :{0}, password :{1}", username, password); - } - } - catch(Exception ex) - { - //check or log error - } - - var resp = new HttpResponseMessage(HttpStatusCode.OK); - resp.Content = new StringContent(content, encoding, "text/plain"); - return resp; - } - - [Route("vhost")] - [HttpPost] - public HttpResponseMessage vhost(FormDataCollection form) - { - string content = "allow"; - try - { - if (form != null) - { - string username = form.Get("username"); - string ip = form.Get("ip"); - - if (username == "authuser") //Sample checks you can put your custom logic over here - content = "deny"; - - string userlog = string.Format("user :{0}, ip :{1}", username, ip); - } - } - catch (Exception ex) - { - //check or log error - } - - var resp = new HttpResponseMessage(HttpStatusCode.OK); - resp.Content = new StringContent(content, encoding, "text/plain"); - return resp; - } - - [Route("resource")] - [HttpPost] - public HttpResponseMessage resource(FormDataCollection form) - { - string content = "allow"; - - try - { - if (form != null) - { - string username = form.Get("username"); - string vhost = form.Get("vhost"); - string resource = form.Get("resource"); - string name = form.Get("name"); - string permission = form.Get("permission"); - - if (username == "authuser") //Sample checks you can put your custom logic over here - content = "deny"; - - string userlog = string.Format("user :{0}, vhost :{1}, resource :{2}, name: {3}, permission: {4}", username, vhost, resource, name, permission); - - } - } - catch (Exception ex) - { - //check or log error - } - - - var resp = new HttpResponseMessage(HttpStatusCode.OK); - resp.Content = new StringContent(content, encoding, "text/plain"); - return resp; - } - - [Route("topic")] - [HttpPost] - public HttpResponseMessage topic(FormDataCollection form) - { - string content = "allow"; - try - { - if (form != null) - { - string username = form.Get("username"); - string vhost = form.Get("vhost"); - string resource = form.Get("resource"); - string name = form.Get("name"); - string permission = form.Get("permission"); - string routing_key = form.Get("routing_key"); - - if (username == "authuser") //Sample checks you can put your custom logic over here - content = "deny"; - - string userlog = string.Format("user :{0}, vhost :{1}, resource :{2}, name: {3}, permission: {4}, routing_key :{5}", username, vhost, resource, name, permission, routing_key); - - } - } - catch (Exception ex) - { - //check or log error - } - - var resp = new HttpResponseMessage(HttpStatusCode.OK); - resp.Content = new StringContent(content, encoding, "text/plain"); - return resp; - } - - - - } -} +using System; +using System.Net; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Text; +using System.Web.Http; + +namespace WebApiHttpAuthService.Controllers +{ + [RoutePrefix("auth")] + public class AuthController : ApiController + { + // Note: the following is necessary to ensure that no + // BOM is part of the response + private static readonly UTF8Encoding encoding = new UTF8Encoding(false); + + [Route("user")] + [HttpPost] + public HttpResponseMessage user(FormDataCollection form) + { + string content = "allow administrator management"; + try + { + if (form != null) + { + string username = form.Get("username"); + string password = form.Get("password"); + + if(username=="authuser") //Sample check you can put your custom logic over here + content = "deny"; + + string userlog = string.Format("user :{0}, password :{1}", username, password); + } + } + catch(Exception ex) + { + //check or log error + } + + var resp = new HttpResponseMessage(HttpStatusCode.OK); + resp.Content = new StringContent(content, encoding, "text/plain"); + return resp; + } + + [Route("vhost")] + [HttpPost] + public HttpResponseMessage vhost(FormDataCollection form) + { + string content = "allow"; + try + { + if (form != null) + { + string username = form.Get("username"); + string ip = form.Get("ip"); + + if (username == "authuser") //Sample checks you can put your custom logic over here + content = "deny"; + + string userlog = string.Format("user :{0}, ip :{1}", username, ip); + } + } + catch (Exception ex) + { + //check or log error + } + + var resp = new HttpResponseMessage(HttpStatusCode.OK); + resp.Content = new StringContent(content, encoding, "text/plain"); + return resp; + } + + [Route("resource")] + [HttpPost] + public HttpResponseMessage resource(FormDataCollection form) + { + string content = "allow"; + + try + { + if (form != null) + { + string username = form.Get("username"); + string vhost = form.Get("vhost"); + string resource = form.Get("resource"); + string name = form.Get("name"); + string permission = form.Get("permission"); + + if (username == "authuser") //Sample checks you can put your custom logic over here + content = "deny"; + + string userlog = string.Format("user :{0}, vhost :{1}, resource :{2}, name: {3}, permission: {4}", username, vhost, resource, name, permission); + + } + } + catch (Exception ex) + { + //check or log error + } + + + var resp = new HttpResponseMessage(HttpStatusCode.OK); + resp.Content = new StringContent(content, encoding, "text/plain"); + return resp; + } + + [Route("topic")] + [HttpPost] + public HttpResponseMessage topic(FormDataCollection form) + { + string content = "allow"; + try + { + if (form != null) + { + string username = form.Get("username"); + string vhost = form.Get("vhost"); + string resource = form.Get("resource"); + string name = form.Get("name"); + string permission = form.Get("permission"); + string routing_key = form.Get("routing_key"); + + if (username == "authuser") //Sample checks you can put your custom logic over here + content = "deny"; + + string userlog = string.Format("user :{0}, vhost :{1}, resource :{2}, name: {3}, permission: {4}, routing_key :{5}", username, vhost, resource, name, permission, routing_key); + + } + } + catch (Exception ex) + { + //check or log error + } + + var resp = new HttpResponseMessage(HttpStatusCode.OK); + resp.Content = new StringContent(content, encoding, "text/plain"); + return resp; + } + + + + } +} diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax index b1a51c9b48b6..0c48f91ae764 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax @@ -1 +1 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="WebApiHttpAuthService.WebApiApplication" Language="C#" %> +<%@ Application Codebehind="Global.asax.cs" Inherits="WebApiHttpAuthService.WebApiApplication" Language="C#" %> diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax.cs b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax.cs index 0f7abd87dcba..8299a1ff460c 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax.cs +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Global.asax.cs @@ -1,12 +1,12 @@ -using System.Web.Http; - -namespace WebApiHttpAuthService -{ - public class WebApiApplication : System.Web.HttpApplication - { - protected void Application_Start() - { - GlobalConfiguration.Configure(WebApiConfig.Register); - } - } -} +using System.Web.Http; + +namespace WebApiHttpAuthService +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Properties/AssemblyInfo.cs b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Properties/AssemblyInfo.cs index 1da9738e4d69..290b45817f61 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Properties/AssemblyInfo.cs +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Properties/AssemblyInfo.cs @@ -1,35 +1,35 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WebApiHttpAuthService")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WebApiHttpAuthService")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f141c3e3-fd04-475b-b2b9-00328d0f907b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WebApiHttpAuthService")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WebApiHttpAuthService")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f141c3e3-fd04-475b-b2b9-00328d0f907b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Debug.config b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Debug.config index c1a56423b02a..fae9cfefa971 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Debug.config +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Debug.config @@ -1,30 +1,30 @@ - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Release.config b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Release.config index 19058ed3535a..da6e960b8d1e 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Release.config +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.Release.config @@ -1,31 +1,31 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.config b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.config index 1c190314d0a5..f1a49df0598d 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.config +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/Web.config @@ -1,45 +1,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj index 912a9fdc7d41..6e5737a1d290 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj @@ -1,136 +1,136 @@ - - - - Debug - AnyCPU - - - 2.0 - {F141C3E3-FD04-475B-B2B9-00328D0F907B} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - WebApiHttpAuthService - WebApiHttpAuthService - v4.5 - true - - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - true - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - ..\..\VEMS.Sample\Dependencies\WSF\Microsoft.Practices.ServiceLocation.dll - - - - - packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - - - - - - - - - - - - packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - - - packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - - - - - - - - - Designer - - - - - - - Global.asax - - - - - - - Web.config - - - Web.config - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - True - 62243 - / - http://localhost:62190/ - False - False - - - False - - - - - - + + + + Debug + AnyCPU + + + 2.0 + {F141C3E3-FD04-475B-B2B9-00328D0F907B} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + WebApiHttpAuthService + WebApiHttpAuthService + v4.5 + true + + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + true + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + ..\..\VEMS.Sample\Dependencies\WSF\Microsoft.Practices.ServiceLocation.dll + + + + + packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + + + + + + + + + + packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + Designer + + + + + + + Global.asax + + + + + + + Web.config + + + Web.config + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 62243 + / + http://localhost:62190/ + False + False + + + False + + + + + + diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj.user b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj.user index 1a60d6407fa1..d8fbc1154bbc 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj.user +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.csproj.user @@ -1,43 +1,43 @@ - - - - true - - - - - - - 600 - True - False - True - - False - - - - - - - - CurrentPage - True - False - False - False - - - - - - - - - True - True - - - - + + + + true + + + + + + + 600 + True + False + True + + False + + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + True + True + + + + \ No newline at end of file diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.sln b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.sln index 5dc14fc12cc6..8f23d65a88a3 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.sln +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/WebApiHttpAuthService.sln @@ -1,25 +1,25 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.8 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApiHttpAuthService", "WebApiHttpAuthService.csproj", "{F141C3E3-FD04-475B-B2B9-00328D0F907B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {2E60A79D-A68A-4486-A8F2-917C08BA2C8A} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.8 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApiHttpAuthService", "WebApiHttpAuthService.csproj", "{F141C3E3-FD04-475B-B2B9-00328D0F907B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F141C3E3-FD04-475B-B2B9-00328D0F907B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2E60A79D-A68A-4486-A8F2-917C08BA2C8A} + EndGlobalSection +EndGlobal diff --git a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/packages.config b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/packages.config index f7de90115584..245e762967fa 100644 --- a/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/packages.config +++ b/deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_webapi_dotnet/packages.config @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/deps/rabbitmq_aws/rabbitmq_aws.iml b/deps/rabbitmq_aws/rabbitmq_aws.iml deleted file mode 100644 index 3850ccd77df2..000000000000 --- a/deps/rabbitmq_aws/rabbitmq_aws.iml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/deps/rabbitmq_consistent_hash_exchange/examples/ruby/Gemfile.lock b/deps/rabbitmq_consistent_hash_exchange/examples/ruby/Gemfile.lock deleted file mode 100644 index 04835be092ec..000000000000 --- a/deps/rabbitmq_consistent_hash_exchange/examples/ruby/Gemfile.lock +++ /dev/null @@ -1,15 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - amq-protocol (2.3.1) - bunny (2.15.0) - amq-protocol (~> 2.3, >= 2.3.1) - -PLATFORMS - ruby - -DEPENDENCIES - bunny (>= 2.15.0, < 3.0) - -BUNDLED WITH - 2.1.4 diff --git a/deps/rabbitmq_ct_client_helpers/.gitignore b/deps/rabbitmq_ct_client_helpers/.gitignore deleted file mode 100644 index 987a3071d0a7..000000000000 --- a/deps/rabbitmq_ct_client_helpers/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -*~ -.sw? -.*.sw? -*.beam -/.erlang.mk/ -/cover/ -/deps/ -/doc/ -/ebin/ -/escript/ -/escript.lock -/logs/ -/plugins/ -/plugins.lock -/sbin/ -/sbin.lock -/xrefr - -/rabbitmq_ct_client_helpers.d -/.rabbitmq_ct_client_helpers.plt - -/.bazelrc -/bazel-* diff --git a/deps/rabbitmq_ct_client_helpers/BUILD.bazel b/deps/rabbitmq_ct_client_helpers/BUILD.bazel deleted file mode 100644 index 1cd7cb6d3445..000000000000 --- a/deps/rabbitmq_ct_client_helpers/BUILD.bazel +++ /dev/null @@ -1,11 +0,0 @@ -load("@rules_erlang//:erlang_app.bzl", "erlang_app") - -erlang_app( - app_name = "rabbitmq_ct_client_helpers", - app_version = "master", - deps = [ - "//deps/amqp_client:erlang_app", - "//deps/rabbit_common:erlang_app", - "//deps/rabbitmq_ct_helpers:erlang_app", - ], -) diff --git a/deps/rabbitmq_ct_client_helpers/CODE_OF_CONDUCT.md b/deps/rabbitmq_ct_client_helpers/CODE_OF_CONDUCT.md deleted file mode 120000 index a3613c99f0b0..000000000000 --- a/deps/rabbitmq_ct_client_helpers/CODE_OF_CONDUCT.md +++ /dev/null @@ -1 +0,0 @@ -../../CODE_OF_CONDUCT.md \ No newline at end of file diff --git a/deps/rabbitmq_ct_client_helpers/CONTRIBUTING.md b/deps/rabbitmq_ct_client_helpers/CONTRIBUTING.md deleted file mode 120000 index f939e75f21a8..000000000000 --- a/deps/rabbitmq_ct_client_helpers/CONTRIBUTING.md +++ /dev/null @@ -1 +0,0 @@ -../../CONTRIBUTING.md \ No newline at end of file diff --git a/deps/rabbitmq_ct_client_helpers/LICENSE b/deps/rabbitmq_ct_client_helpers/LICENSE deleted file mode 100644 index f2da65d1753a..000000000000 --- a/deps/rabbitmq_ct_client_helpers/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -This package is licensed under the MPL 2.0. For the MPL 2.0, please see LICENSE-MPL-RabbitMQ. - -If you have any questions regarding licensing, please contact us at -info@rabbitmq.com. diff --git a/deps/rabbitmq_ct_client_helpers/LICENSE-MPL-RabbitMQ b/deps/rabbitmq_ct_client_helpers/LICENSE-MPL-RabbitMQ deleted file mode 100644 index 14e2f777f6c3..000000000000 --- a/deps/rabbitmq_ct_client_helpers/LICENSE-MPL-RabbitMQ +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - 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 http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/deps/rabbitmq_ct_client_helpers/Makefile b/deps/rabbitmq_ct_client_helpers/Makefile deleted file mode 100644 index eb18f4fbadf5..000000000000 --- a/deps/rabbitmq_ct_client_helpers/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -PROJECT = rabbitmq_ct_client_helpers -PROJECT_DESCRIPTION = Common Test helpers for RabbitMQ (client-side helpers) - -DEPS = rabbit_common rabbitmq_ct_helpers amqp_client - -# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be -# reviewed and merged. - -ERLANG_MK_REPO = https://github.com/rabbitmq/erlang.mk.git -ERLANG_MK_COMMIT = rabbitmq-tmp - -DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk \ - rabbit_common/mk/rabbitmq-tools.mk - -include ../../rabbitmq-components.mk -include ../../erlang.mk diff --git a/deps/rabbitmq_ct_client_helpers/WORKSPACE.bazel b/deps/rabbitmq_ct_client_helpers/WORKSPACE.bazel deleted file mode 100644 index ae6897a168ba..000000000000 --- a/deps/rabbitmq_ct_client_helpers/WORKSPACE.bazel +++ /dev/null @@ -1,24 +0,0 @@ -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "bazel-erlang", - sha256 = "422a9222522216f59a01703a13f578c601d6bddf5617bee8da3c43e3b299fc4e", - strip_prefix = "bazel-erlang-1.1.0", - urls = ["https://github.com/rabbitmq/bazel-erlang/archive/refs/tags/1.1.0.zip"], -) - -http_archive( - name = "rabbitmq-server", - strip_prefix = "rabbitmq-server-master", - urls = ["https://github.com/rabbitmq/rabbitmq-server/archive/master.zip"], -) - -http_archive( - name = "rabbitmq_ct_helpers", - strip_prefix = "rabbitmq-ct-helpers-master", - urls = ["https://github.com/rabbitmq/rabbitmq-ct-helpers/archive/master.zip"], -) - -load("@rabbitmq-server//:workspace_helpers.bzl", "rabbitmq_external_deps") - -rabbitmq_external_deps() diff --git a/deps/rabbitmq_ct_client_helpers/src/rabbit_ct_client_helpers.erl b/deps/rabbitmq_ct_client_helpers/src/rabbit_ct_client_helpers.erl deleted file mode 100644 index 96c44bc35d5a..000000000000 --- a/deps/rabbitmq_ct_client_helpers/src/rabbit_ct_client_helpers.erl +++ /dev/null @@ -1,302 +0,0 @@ -%% 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-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_client_helpers). - --include_lib("common_test/include/ct.hrl"). --include_lib("amqp_client/include/amqp_client.hrl"). - --export([ - setup_steps/0, - teardown_steps/0, - start_channels_managers/1, - stop_channels_managers/1, - - open_connection/2, - open_unmanaged_connection/1, open_unmanaged_connection/2, - open_unmanaged_connection/3, open_unmanaged_connection/4, open_unmanaged_connection/5, - open_unmanaged_connection_direct/1, open_unmanaged_connection_direct/2, - open_unmanaged_connection_direct/3, open_unmanaged_connection_direct/4, - open_unmanaged_connection_direct/5, - open_unmanaged_connection/6, - close_connection/1, open_channel/2, open_channel/1, - close_channel/1, - open_connection_and_channel/2, open_connection_and_channel/1, - close_connection_and_channel/2, - close_channels_and_connection/2, - - publish/3, consume/3, consume_without_acknowledging/3, fetch/3 - ]). - -%% ------------------------------------------------------------------- -%% Client setup/teardown steps. -%% ------------------------------------------------------------------- - -setup_steps() -> - [ - fun start_channels_managers/1 - ]. - -teardown_steps() -> - [ - fun stop_channels_managers/1 - ]. - -start_channels_managers(Config) -> - ok = application:set_env(amqp_client, gen_server_call_timeout, infinity), - NodeConfigs = rabbit_ct_broker_helpers:get_node_configs(Config), - NodeConfigs1 = [start_channels_manager(NC) || NC <- NodeConfigs], - rabbit_ct_helpers:set_config(Config, {rmq_nodes, NodeConfigs1}). - -start_channels_manager(NodeConfig) -> - Pid = erlang:spawn( - fun() -> channels_manager(NodeConfig, undefined, []) end), - rabbit_ct_helpers:set_config(NodeConfig, {channels_manager, Pid}). - -stop_channels_managers(Config) -> - NodeConfigs = rabbit_ct_broker_helpers:get_node_configs(Config), - NodeConfigs1 = [stop_channels_manager(NC) || NC <- NodeConfigs], - rabbit_ct_helpers:set_config(Config, {rmq_nodes, NodeConfigs1}). - -stop_channels_manager(NodeConfig) -> - Pid = ?config(channels_manager, NodeConfig), - Pid ! stop, - proplists:delete(channels_manager, NodeConfig). - -channels_manager(NodeConfig, ConnTuple, Channels) -> - receive - {open_connection, From} -> - {Conn1, _} = ConnTuple1 = open_conn(NodeConfig, ConnTuple), - From ! Conn1, - channels_manager(NodeConfig, ConnTuple1, Channels); - {open_channel, From} -> - {Conn1, _} = ConnTuple1 = open_conn(NodeConfig, ConnTuple), - {ok, Ch} = amqp_connection:open_channel(Conn1), - ChMRef = erlang:monitor(process, Ch), - From ! Ch, - channels_manager(NodeConfig, ConnTuple1, - [{Ch, ChMRef} | Channels]); - {close_everything, From} -> - close_everything(ConnTuple, Channels), - From ! ok, - channels_manager(NodeConfig, undefined, []); - {'DOWN', ConnMRef, process, Conn, _} - when {Conn, ConnMRef} =:= ConnTuple -> - channels_manager(NodeConfig, undefined, Channels); - {'DOWN', ChMRef, process, Ch, _} -> - Channels1 = Channels -- [{Ch, ChMRef}], - channels_manager(NodeConfig, ConnTuple, Channels1); - stop -> - close_everything(ConnTuple, Channels); - Unhandled -> - ct:pal(?LOW_IMPORTANCE, - "Channels manager ~p: unhandled message: ~p", - [self(), Unhandled]), - channels_manager(NodeConfig, ConnTuple, Channels) - end. - -open_conn(NodeConfig, undefined) -> - Port = ?config(tcp_port_amqp, NodeConfig), - Params = #amqp_params_network{port = Port}, - {ok, Conn} = amqp_connection:start(Params), - MRef = erlang:monitor(process, Conn), - {Conn, MRef}; -open_conn(NodeConfig, {Conn, _} = ConnTuple) -> - case erlang:is_process_alive(Conn) of - true -> ConnTuple; - false -> open_conn(NodeConfig, undefined) - end. - -close_everything(Conn, [{Ch, MRef} | Rest]) -> - case erlang:is_process_alive(Ch) of - true -> - amqp_channel:close(Ch), - receive - {'DOWN', MRef, _, Ch, Info} -> - ct:pal("Channel ~p closed: ~p~n", [Ch, Info]) - end; - false -> - ok - end, - close_everything(Conn, Rest); -close_everything({Conn, MRef}, []) -> - case erlang:is_process_alive(Conn) of - true -> - amqp_connection:close(Conn), - receive - {'DOWN', MRef, _, Conn, Info} -> - ct:pal("Connection ~p closed: ~p~n", [Conn, Info]) - end; - false -> - ok - end; -close_everything(undefined, []) -> - ok. - -%% ------------------------------------------------------------------- -%% Public API. -%% ------------------------------------------------------------------- - -open_connection(Config, Node) -> - Pid = rabbit_ct_broker_helpers:get_node_config(Config, Node, - channels_manager), - Pid ! {open_connection, self()}, - receive - Conn when is_pid(Conn) -> Conn - end. - -open_unmanaged_connection(Config) -> - open_unmanaged_connection(Config, 0). - -open_unmanaged_connection(Config, Node) -> - open_unmanaged_connection(Config, Node, ?config(rmq_vhost, Config)). - -open_unmanaged_connection(Config, Node, VHost) -> - open_unmanaged_connection(Config, Node, VHost, - ?config(rmq_username, Config), ?config(rmq_password, Config)). - -open_unmanaged_connection(Config, Node, Username, Password) -> - open_unmanaged_connection(Config, Node, ?config(rmq_vhost, Config), - Username, Password). - -open_unmanaged_connection(Config, Node, VHost, Username, Password) -> - open_unmanaged_connection(Config, Node, VHost, Username, Password, - network). - -open_unmanaged_connection_direct(Config) -> - open_unmanaged_connection_direct(Config, 0). - -open_unmanaged_connection_direct(Config, Node) -> - open_unmanaged_connection_direct(Config, Node, ?config(rmq_vhost, Config)). - -open_unmanaged_connection_direct(Config, Node, VHost) -> - open_unmanaged_connection_direct(Config, Node, VHost, - ?config(rmq_username, Config), ?config(rmq_password, Config)). - -open_unmanaged_connection_direct(Config, Node, Username, Password) -> - open_unmanaged_connection_direct(Config, Node, ?config(rmq_vhost, Config), - Username, Password). - -open_unmanaged_connection_direct(Config, Node, VHost, Username, Password) -> - open_unmanaged_connection(Config, Node, VHost, Username, Password, direct). - -open_unmanaged_connection(Config, Node, VHost, Username, Password, Type) -> - Params = case Type of - network -> - Port = rabbit_ct_broker_helpers:get_node_config(Config, Node, - tcp_port_amqp), - #amqp_params_network{port = Port, - virtual_host = VHost, - username = Username, - password = Password}; - direct -> - NodeName = rabbit_ct_broker_helpers:get_node_config(Config, Node, - nodename), - #amqp_params_direct{node = NodeName, - virtual_host = VHost, - username = Username, - password = Password} - end, - case amqp_connection:start(Params) of - {ok, Conn} -> Conn; - {error, _} = Error -> Error - end. - -open_channel(Config) -> - open_channel(Config, 0). - -open_channel(Config, Node) -> - Pid = rabbit_ct_broker_helpers:get_node_config(Config, Node, - channels_manager), - Pid ! {open_channel, self()}, - receive - Ch when is_pid(Ch) -> Ch - end. - -open_connection_and_channel(Config) -> - open_connection_and_channel(Config, 0). - -open_connection_and_channel(Config, Node) -> - Conn = open_connection(Config, Node), - Ch = open_channel(Config, Node), - {Conn, Ch}. - -close_channel(Ch) -> - case is_process_alive(Ch) of - true -> amqp_channel:close(Ch); - false -> ok - end. - -close_connection(Conn) -> - case is_process_alive(Conn) of - true -> amqp_connection:close(Conn); - false -> ok - end. - -close_connection_and_channel(Conn, Ch) -> - _ = close_channel(Ch), - case close_connection(Conn) of - ok -> ok; - closing -> ok - end. - -close_channels_and_connection(Config, Node) -> - Pid = rabbit_ct_broker_helpers:get_node_config(Config, Node, - channels_manager), - Pid ! {close_everything, self()}, - receive - ok -> ok - end. - -publish(Ch, QName, Count) -> - amqp_channel:call(Ch, #'confirm.select'{}), - [amqp_channel:call(Ch, - #'basic.publish'{routing_key = QName}, - #amqp_msg{props = #'P_basic'{delivery_mode = 2}, - payload = list_to_binary(integer_to_list(I))}) - || I <- lists:seq(1, Count)], - amqp_channel:wait_for_confirms(Ch). - -consume(Ch, QName, Count) -> - amqp_channel:subscribe(Ch, #'basic.consume'{queue = QName, no_ack = true}, - self()), - CTag = receive #'basic.consume_ok'{consumer_tag = C} -> C end, - [begin - Exp = integer_to_binary(I), - receive {#'basic.deliver'{consumer_tag = CTag}, - #amqp_msg{payload = Exp}} -> - ok - after 5000 -> - exit(timeout) - end - end || I <- lists:seq(1, Count)], - amqp_channel:call(Ch, #'basic.cancel'{consumer_tag = CTag}), - ok. - -consume_without_acknowledging(Ch, QName, Count) -> - amqp_channel:subscribe(Ch, #'basic.consume'{queue = QName, no_ack = false}, - self()), - CTag = receive #'basic.consume_ok'{consumer_tag = C} -> C end, - accumulate_without_acknowledging(Ch, CTag, Count, []). - -accumulate_without_acknowledging(Ch, CTag, Remaining, Acc) when Remaining =:= 0 -> - amqp_channel:call(Ch, #'basic.cancel'{consumer_tag = CTag}), - lists:reverse(Acc); -accumulate_without_acknowledging(Ch, CTag, Remaining, Acc) -> - receive {#'basic.deliver'{consumer_tag = CTag, delivery_tag = DTag}, _Msg} -> - accumulate_without_acknowledging(Ch, CTag, Remaining - 1, [DTag | Acc]) - after 5000 -> - amqp_channel:call(Ch, #'basic.cancel'{consumer_tag = CTag}), - exit(timeout) - end. - - -fetch(Ch, QName, Count) -> - [{#'basic.get_ok'{}, _} = - amqp_channel:call(Ch, #'basic.get'{queue = QName}) || - _ <- lists:seq(1, Count)], - ok. diff --git a/deps/rabbitmq_ct_helpers/.gitignore b/deps/rabbitmq_ct_helpers/.gitignore deleted file mode 100644 index 85195da77ad9..000000000000 --- a/deps/rabbitmq_ct_helpers/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -*~ -.sw? -.*.sw? -*.beam -.terraform/ -.terraform-* -terraform.tfstate* -*terraform.lock* -/.erlang.mk/ -/cover/ -/deps/ -/doc/ -/ebin/ -/escript/ -/escript.lock -/logs/ -/plugins/ -/plugins.lock -/sbin/ -/sbin.lock -/xrefr - -/rabbitmq_ct_helpers.d -/.rabbitmq_ct_helpers.plt - -/.bazelrc -/bazel-* diff --git a/deps/rabbitmq_ct_helpers/BUILD.bazel b/deps/rabbitmq_ct_helpers/BUILD.bazel deleted file mode 100644 index 6aaa7d1369b5..000000000000 --- a/deps/rabbitmq_ct_helpers/BUILD.bazel +++ /dev/null @@ -1,14 +0,0 @@ -load("@rules_erlang//:erlang_app.bzl", "erlang_app") - -erlang_app( - app_name = "rabbitmq_ct_helpers", - app_version = "master", - extra_priv = [ - "tools/tls-certs/Makefile", - "tools/tls-certs/openssl.cnf.in", - ], - deps = [ - "//deps/rabbit_common:erlang_app", - "@proper//:erlang_app", - ], -) diff --git a/deps/rabbitmq_ct_helpers/CODE_OF_CONDUCT.md b/deps/rabbitmq_ct_helpers/CODE_OF_CONDUCT.md deleted file mode 120000 index a3613c99f0b0..000000000000 --- a/deps/rabbitmq_ct_helpers/CODE_OF_CONDUCT.md +++ /dev/null @@ -1 +0,0 @@ -../../CODE_OF_CONDUCT.md \ No newline at end of file diff --git a/deps/rabbitmq_ct_helpers/CONTRIBUTING.md b/deps/rabbitmq_ct_helpers/CONTRIBUTING.md deleted file mode 120000 index f939e75f21a8..000000000000 --- a/deps/rabbitmq_ct_helpers/CONTRIBUTING.md +++ /dev/null @@ -1 +0,0 @@ -../../CONTRIBUTING.md \ No newline at end of file diff --git a/deps/rabbitmq_ct_helpers/LICENSE b/deps/rabbitmq_ct_helpers/LICENSE deleted file mode 100644 index 5bba9af374bf..000000000000 --- a/deps/rabbitmq_ct_helpers/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -This package, rabbitmq_ct_helpers, is dual-licensed under -the Apache License v2 and the Mozilla Public License v2.0. - -For the Apache License, please see the file LICENSE-APACHE2. - -For the Mozilla Public License, please see the file LICENSE-MPL-RabbitMQ. - -For attribution of copyright and other details of provenance, please -refer to the source code. - -If you have any questions regarding licensing, please contact us at -info@rabbitmq.com. diff --git a/deps/rabbitmq_ct_helpers/LICENSE-APACHE2 b/deps/rabbitmq_ct_helpers/LICENSE-APACHE2 deleted file mode 100644 index 7017ed9108c4..000000000000 --- a/deps/rabbitmq_ct_helpers/LICENSE-APACHE2 +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017-2020 VMware, Inc. or its affiliates. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/deps/rabbitmq_ct_helpers/LICENSE-MPL-RabbitMQ b/deps/rabbitmq_ct_helpers/LICENSE-MPL-RabbitMQ deleted file mode 100644 index 14e2f777f6c3..000000000000 --- a/deps/rabbitmq_ct_helpers/LICENSE-MPL-RabbitMQ +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - 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 http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/deps/rabbitmq_ct_helpers/Makefile b/deps/rabbitmq_ct_helpers/Makefile deleted file mode 100644 index 45f3d99c45e9..000000000000 --- a/deps/rabbitmq_ct_helpers/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -PROJECT = rabbitmq_ct_helpers -PROJECT_DESCRIPTION = Common Test helpers for RabbitMQ - -DEPS = rabbit_common proper inet_tcp_proxy -TEST_DEPS = rabbit - -dep_rabbit_common = git-subfolder https://github.com/rabbitmq/rabbitmq-server master deps/rabbit_common -dep_rabbit = git-subfolder https://github.com/rabbitmq/rabbitmq-server master deps/rabbit -dep_inet_tcp_proxy = git https://github.com/rabbitmq/inet_tcp_proxy master - -# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be -# reviewed and merged. - -ERLANG_MK_REPO = https://github.com/rabbitmq/erlang.mk.git -ERLANG_MK_COMMIT = rabbitmq-tmp - -DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk \ - rabbit_common/mk/rabbitmq-dist.mk \ - rabbit_common/mk/rabbitmq-run.mk \ - rabbit_common/mk/rabbitmq-tools.mk - -include ../../rabbitmq-components.mk -include ../../erlang.mk - -ERLC_OPTS += +nowarn_export_all diff --git a/deps/rabbitmq_ct_helpers/WORKSPACE.bazel b/deps/rabbitmq_ct_helpers/WORKSPACE.bazel deleted file mode 100644 index e863f6c2b87d..000000000000 --- a/deps/rabbitmq_ct_helpers/WORKSPACE.bazel +++ /dev/null @@ -1,18 +0,0 @@ -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "bazel-erlang", - sha256 = "422a9222522216f59a01703a13f578c601d6bddf5617bee8da3c43e3b299fc4e", - strip_prefix = "bazel-erlang-1.1.0", - urls = ["https://github.com/rabbitmq/bazel-erlang/archive/refs/tags/1.1.0.zip"], -) - -http_archive( - name = "rabbitmq-server", - strip_prefix = "rabbitmq-server-master", - urls = ["https://github.com/rabbitmq/rabbitmq-server/archive/master.zip"], -) - -load("@rabbitmq-server//:workspace_helpers.bzl", "rabbitmq_external_deps") - -rabbitmq_external_deps() diff --git a/deps/rabbitmq_ct_helpers/include/rabbit_assert.hrl b/deps/rabbitmq_ct_helpers/include/rabbit_assert.hrl deleted file mode 100644 index e1981ac4b354..000000000000 --- a/deps/rabbitmq_ct_helpers/include/rabbit_assert.hrl +++ /dev/null @@ -1,49 +0,0 @@ --define(AWAIT_MATCH_DEFAULT_POLLING_INTERVAL, 50). - --define(awaitMatch(Guard, Expr, Timeout, PollingInterval), - begin - ((fun AwaitMatchFilter(AwaitMatchHorizon) -> - AwaitMatchResult = Expr, - case (AwaitMatchResult) of - Guard -> AwaitMatchResult; - __V -> case erlang:system_time(millisecond) of - AwaitMatchNow when AwaitMatchNow < AwaitMatchHorizon -> - timer:sleep( - min(PollingInterval, - AwaitMatchHorizon - AwaitMatchNow)), - AwaitMatchFilter(AwaitMatchHorizon); - _ -> - erlang:error({awaitMatch, - [{module, ?MODULE}, - {line, ?LINE}, - {expression, (??Expr)}, - {pattern, (??Guard)}, - {value, __V}]}) - end - end - end)(erlang:system_time(millisecond) + Timeout)) - end). - --define(awaitMatch(Guard, Expr, Timeout), - begin - ((fun AwaitMatchFilter(AwaitMatchHorizon) -> - AwaitMatchResult = Expr, - case (AwaitMatchResult) of - Guard -> AwaitMatchResult; - __V -> case erlang:system_time(millisecond) of - AwaitMatchNow when AwaitMatchNow < AwaitMatchHorizon -> - timer:sleep( - min(?AWAIT_MATCH_DEFAULT_POLLING_INTERVAL, - AwaitMatchHorizon - AwaitMatchNow)), - AwaitMatchFilter(AwaitMatchHorizon); - _ -> - erlang:error({awaitMatch, - [{module, ?MODULE}, - {line, ?LINE}, - {expression, (??Expr)}, - {pattern, (??Guard)}, - {value, __V}]}) - end - end - end)(erlang:system_time(millisecond) + Timeout)) - end). diff --git a/deps/rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl b/deps/rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl deleted file mode 100644 index 47509a616458..000000000000 --- a/deps/rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl +++ /dev/null @@ -1,11 +0,0 @@ --include_lib("eunit/include/eunit.hrl"). - --define(OK, 200). --define(CREATED, 201). --define(NO_CONTENT, 204). --define(SEE_OTHER, 303). --define(BAD_REQUEST, 400). --define(NOT_AUTHORISED, 401). -%%-define(NOT_FOUND, 404). Defined for AMQP by amqp_client.hrl (as 404) -%% httpc seems to get racy when using HTTP 1.1 --define(HTTPC_OPTS, [{version, "HTTP/1.0"}, {autoredirect, false}]). diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_control_helper.erl b/deps/rabbitmq_ct_helpers/src/rabbit_control_helper.erl deleted file mode 100644 index 37b5aa3db8a5..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_control_helper.erl +++ /dev/null @@ -1,46 +0,0 @@ -%% 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-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_control_helper). - --export([command/2, command/3, command/4, command_with_output/4, format_command/4]). - -command(Command, Node, Args) -> - command(Command, Node, Args, []). - -command(Command, Node) -> - command(Command, Node, [], []). - -command(Command, Node, Args, Opts) -> - case command_with_output(Command, Node, Args, Opts) of - {ok, _} -> ok; - ok -> ok; - Error -> Error - end. - -command_with_output(Command, Node, Args, Opts) -> - Formatted = format_command(Command, Node, Args, Opts), - CommandResult = 'Elixir.RabbitMQCtl':exec_command( - Formatted, fun(Output,_,_) -> Output end), - ct:pal("Executed command ~p against node ~p~nResult: ~p~n", [Formatted, Node, CommandResult]), - CommandResult. - -format_command(Command, Node, Args, Opts) -> - Formatted = io_lib:format("~tp ~ts ~ts", - [Command, - format_args(Args), - format_options([{"--node", Node} | Opts])]), - 'Elixir.OptionParser':split(iolist_to_binary(Formatted)). - -format_args(Args) -> - iolist_to_binary([ io_lib:format("~tp ", [Arg]) || Arg <- Args ]). - -format_options(Opts) -> - EffectiveOpts = [{"--script-name", "rabbitmqctl"} | Opts], - iolist_to_binary([io_lib:format("~s=~tp ", [Key, Value]) - || {Key, Value} <- EffectiveOpts ]). - diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_ct_broker_helpers.erl b/deps/rabbitmq_ct_helpers/src/rabbit_ct_broker_helpers.erl deleted file mode 100644 index b22e508e000e..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_ct_broker_helpers.erl +++ /dev/null @@ -1,1919 +0,0 @@ -%% 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-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_broker_helpers). - --include_lib("common_test/include/ct.hrl"). --include_lib("kernel/include/inet.hrl"). --include_lib("rabbit_common/include/rabbit.hrl"). --include_lib("eunit/include/eunit.hrl"). - --export([ - setup_steps/0, - setup_steps_for_vms/0, - teardown_steps/0, - teardown_steps_for_vms/0, - run_make_dist/1, - start_rabbitmq_nodes/1, - start_rabbitmq_nodes_on_vms/1, - stop_rabbitmq_nodes/1, - stop_rabbitmq_nodes_on_vms/1, - rewrite_node_config_file/2, - cluster_nodes/1, cluster_nodes/2, - - get_node_configs/1, get_node_configs/2, - get_node_config/2, get_node_config/3, set_node_config/3, - nodename_to_index/2, - node_uri/2, node_uri/3, - - control_action/2, control_action/3, control_action/4, - rabbitmqctl/3, rabbitmqctl/4, rabbitmqctl_list/3, - rabbitmq_queues/3, - - add_code_path_to_node/2, - add_code_path_to_all_nodes/2, - rpc/5, rpc/6, - rpc_all/4, rpc_all/5, - - start_node/2, - start_broker/2, - restart_broker/2, - stop_broker/2, - restart_node/2, - stop_node/2, - stop_node_after/3, - kill_node/2, - kill_node_after/3, - - reset_node/2, - force_reset_node/2, - - forget_cluster_node/3, - forget_cluster_node/4, - - cluster_members_online/2, - - is_feature_flag_supported/2, - is_feature_flag_supported/3, - enable_feature_flag/2, - enable_feature_flag/3, - - drain_node/2, - revive_node/2, - mark_as_being_drained/2, - unmark_as_being_drained/2, - is_being_drained_local_read/2, - is_being_drained_local_read/3, - is_being_drained_consistent_read/2, - is_being_drained_consistent_read/3, - - set_partition_handling_mode/3, - set_partition_handling_mode_globally/2, - configure_dist_proxy/1, - block_traffic_between/2, - allow_traffic_between/2, - - get_connection_pids/1, - close_all_connections/3, - - set_policy/6, - set_policy/7, - set_policy_in_vhost/7, - set_policy_in_vhost/8, - - clear_policy/3, - clear_policy/4, - set_operator_policy/6, - clear_operator_policy/3, - set_ha_policy/4, set_ha_policy/5, - set_ha_policy_all/1, - set_ha_policy_all/2, - set_ha_policy_two_pos/1, - set_ha_policy_two_pos_batch_sync/1, - - set_parameter/5, - set_parameter/6, - set_parameter/7, - clear_parameter/4, - clear_parameter/5, - clear_parameter/6, - - set_global_parameter/3, - set_global_parameter/4, - clear_global_parameter/2, - clear_global_parameter/3, - - add_vhost/2, - add_vhost/3, - add_vhost/4, - delete_vhost/2, - delete_vhost/3, - delete_vhost/4, - - force_vhost_failure/2, - force_vhost_failure/3, - - set_alarm/3, - get_alarms/2, - get_local_alarms/2, - clear_alarm/3, - clear_all_alarms/2, - - add_user/2, - add_user/3, - add_user/4, - add_user/5, - set_user_tags/4, - set_user_tags/5, - - delete_user/2, - delete_user/3, - delete_user/4, - - change_password/5, - clear_password/4, - - change_password/3, - - switch_credential_validator/2, - switch_credential_validator/3, - - set_permissions/6, - set_permissions/7, - set_permissions/8, - set_full_permissions/2, - set_full_permissions/3, - set_full_permissions/4, - - clear_permissions/2, - clear_permissions/3, - clear_permissions/4, - clear_permissions/5, - - set_vhost_limit/5, - - set_user_limits/3, - set_user_limits/4, - clear_user_limits/3, - clear_user_limits/4, - - enable_plugin/3, - disable_plugin/3, - - test_channel/0, - test_writer/1, - user/1 - ]). - -%% Internal functions exported to be used by rpc:call/4. --export([ - do_restart_broker/0 - ]). - --define(DEFAULT_USER, "guest"). --define(NODE_START_ATTEMPTS, 10). - --define(TCP_PORTS_BASE, 21000). --define(TCP_PORTS_LIST, [ - tcp_port_amqp, - tcp_port_amqp_tls, - tcp_port_mgmt, - tcp_port_erlang_dist, - tcp_port_erlang_dist_proxy, - tcp_port_mqtt, - tcp_port_mqtt_tls, - tcp_port_web_mqtt, - tcp_port_stomp, - tcp_port_stomp_tls, - tcp_port_web_stomp, - tcp_port_web_stomp_tls, - tcp_port_stream, - tcp_port_stream_tls, - tcp_port_prometheus - ]). - -%% ------------------------------------------------------------------- -%% Broker setup/teardown steps. -%% ------------------------------------------------------------------- - -setup_steps() -> - case os:getenv("RABBITMQ_RUN") of - false -> - [ - fun run_make_dist/1, - fun rabbit_ct_helpers:ensure_rabbitmqctl_cmd/1, - fun rabbit_ct_helpers:ensure_rabbitmqctl_app/1, - fun rabbit_ct_helpers:ensure_rabbitmq_plugins_cmd/1, - fun set_lager_flood_limit/1, - fun start_rabbitmq_nodes/1, - fun share_dist_and_proxy_ports_map/1 - ]; - _ -> - [ - fun rabbit_ct_helpers:ensure_rabbitmqctl_cmd/1, - fun rabbit_ct_helpers:load_rabbitmqctl_app/1, - fun rabbit_ct_helpers:ensure_rabbitmq_plugins_cmd/1, - fun set_lager_flood_limit/1, - fun start_rabbitmq_nodes/1, - fun share_dist_and_proxy_ports_map/1 - ] - end. - -teardown_steps() -> - [ - fun stop_rabbitmq_nodes/1 - ]. - -setup_steps_for_vms() -> - [ - fun rabbit_ct_helpers:ensure_rabbitmqctl_cmd/1, - fun rabbit_ct_helpers:ensure_rabbitmqctl_app/1, - fun rabbit_ct_helpers:ensure_rabbitmq_plugins_cmd/1, - fun start_rabbitmq_nodes_on_vms/1, - fun maybe_cluster_nodes/1 - ]. - -teardown_steps_for_vms() -> - [ - fun stop_rabbitmq_nodes_on_vms/1 - ]. - -run_make_dist(Config) -> - LockId = {make_dist, self()}, - global:set_lock(LockId, [node()]), - case os:getenv("SKIP_MAKE_TEST_DIST") of - false -> - SrcDir = ?config(current_srcdir, Config), - case rabbit_ct_helpers:make(Config, SrcDir, ["test-dist"]) of - {ok, _} -> - %% The caller can set $SKIP_MAKE_TEST_DIST to - %% manually skip this step which can be time - %% consuming. But we also use this variable to - %% record the fact we went through it already so we - %% save redundant calls. - os:putenv("SKIP_MAKE_TEST_DIST", "true"), - global:del_lock(LockId, [node()]), - Config; - _ -> - global:del_lock(LockId, [node()]), - {skip, "Failed to run \"make test-dist\""} - end; - _ -> - global:del_lock(LockId, [node()]), - ct:pal(?LOW_IMPORTANCE, "(skip `$MAKE test-dist`)", []), - Config - end. - -set_lager_flood_limit(Config) -> - rabbit_ct_helpers:merge_app_env(Config, - {lager, [{error_logger_hwm, 10000}]}). - -start_rabbitmq_nodes_on_vms(Config) -> - ConfigsPerVM = configs_per_vm(Config), - start_rabbitmq_nodes_on_vms(Config, ConfigsPerVM, []). - -start_rabbitmq_nodes_on_vms(Config, [{Node, C} | Rest], NodeConfigsList) -> - Config1 = rabbit_ct_helpers:set_config(Config, {rmq_nodes_clustered, false}), - Ret = rabbit_ct_vm_helpers:rpc(Config1, - Node, - ?MODULE, - start_rabbitmq_nodes, - [C]), - case Ret of - {skip, _} = Error -> - Error; - _ -> - NodeConfigs = get_node_configs(Ret), - start_rabbitmq_nodes_on_vms(Config, Rest, - [NodeConfigs | NodeConfigsList]) - end; -start_rabbitmq_nodes_on_vms(Config, [], NodeConfigsList) -> - merge_node_configs(Config, lists:reverse(NodeConfigsList)). - -start_rabbitmq_nodes(Config) -> - Config0 = rabbit_ct_helpers:set_config(Config, [ - {rmq_username, list_to_binary(?DEFAULT_USER)}, - {rmq_password, list_to_binary(?DEFAULT_USER)}, - {rmq_vhost, <<"/">>}, - {rmq_channel_max, 0}]), - Config1 = case rabbit_ct_helpers:get_config(Config0, rmq_hostname) of - undefined -> - rabbit_ct_helpers:set_config( - Config0, {rmq_hostname, "localhost"}); - _ -> - Config0 - end, - NodesCount = get_nodes_count(Config1), - Clustered0 = rabbit_ct_helpers:get_config(Config1, rmq_nodes_clustered), - Clustered = case Clustered0 of - undefined -> true; - C when is_boolean(C) -> C - end, - Master = self(), - Starters = [ - spawn_link(fun() -> start_rabbitmq_node(Master, Config1, [], I) end) - || I <- lists:seq(0, NodesCount - 1) - ], - wait_for_rabbitmq_nodes(Config1, Starters, [], Clustered). - -get_nodes_count(Config) -> - NodesCount = rabbit_ct_helpers:get_config(Config, rmq_nodes_count), - case NodesCount of - undefined -> 1; - N when is_integer(N) andalso N >= 1 -> N; - L when is_list(L) andalso length(L) >= 1 -> length(L) - end. - -set_nodes_count(Config, NodesCount) -> - rabbit_ct_helpers:set_config(Config, {rmq_nodes_count, NodesCount}). - -configs_per_vm(Config) -> - CTPeers = rabbit_ct_vm_helpers:get_ct_peers(Config), - NodesCount = get_nodes_count(Config), - InstanceCount = length(CTPeers), - NodesPerVM = NodesCount div InstanceCount, - Remaining = NodesCount rem InstanceCount, - configs_per_vm(CTPeers, Config, [], NodesPerVM, Remaining). - -configs_per_vm([CTPeer | Rest], Config, ConfigsPerVM, NodesPerVM, Remaining) -> - Hostname = rabbit_ct_helpers:nodename_to_hostname(CTPeer), - Config0 = rabbit_ct_helpers:set_config(Config, {rmq_hostname, Hostname}), - NodesCount = if - Remaining > 0 -> NodesPerVM + 1; - true -> NodesPerVM - end, - if - NodesCount > 0 -> - Config1 = set_nodes_count(Config0, NodesCount), - configs_per_vm(Rest, Config, [{CTPeer, Config1} | ConfigsPerVM], - NodesPerVM, Remaining - 1); - true -> - configs_per_vm(Rest, Config, ConfigsPerVM, - NodesPerVM, Remaining) - end; -configs_per_vm([], _, ConfigsPerVM, _, _) -> - lists:reverse(ConfigsPerVM). - -merge_node_configs(Config, NodeConfigsList) -> - merge_node_configs(Config, NodeConfigsList, []). - -merge_node_configs(Config, [], MergedNodeConfigs) -> - rabbit_ct_helpers:set_config(Config, {rmq_nodes, MergedNodeConfigs}); -merge_node_configs(Config, NodeConfigsList, MergedNodeConfigs) -> - HeadsAndTails = [{H, T} || [H | T] <- NodeConfigsList], - Heads = [H || {H, _} <- HeadsAndTails], - Tails = [T || {_, T} <- HeadsAndTails], - merge_node_configs(Config, Tails, MergedNodeConfigs ++ Heads). - -wait_for_rabbitmq_nodes(Config, [], NodeConfigs, Clustered) -> - NodeConfigs1 = [NC || {_, NC} <- lists:keysort(1, NodeConfigs)], - Config1 = rabbit_ct_helpers:set_config(Config, {rmq_nodes, NodeConfigs1}), - if - Clustered -> cluster_nodes(Config1); - true -> Config1 - end; -wait_for_rabbitmq_nodes(Config, Starting, NodeConfigs, Clustered) -> - receive - {_, {skip, _} = Error} -> - NodeConfigs1 = [NC || {_, NC} <- NodeConfigs], - Config1 = rabbit_ct_helpers:set_config(Config, - {rmq_nodes, NodeConfigs1}), - stop_rabbitmq_nodes(Config1), - Error; - {Pid, I, NodeConfig} when NodeConfigs =:= [] -> - wait_for_rabbitmq_nodes(Config, Starting -- [Pid], - [{I, NodeConfig} | NodeConfigs], Clustered); - {Pid, I, NodeConfig} -> - wait_for_rabbitmq_nodes(Config, Starting -- [Pid], - [{I, NodeConfig} | NodeConfigs], Clustered) - end. - -%% To start a RabbitMQ node, we need to: -%% 1. Pick TCP port numbers -%% 2. Generate a node name -%% 3. Write a configuration file -%% 4. Start the node -%% -%% If this fails (usually because the node name is taken or a TCP port -%% is already in use), we start again with another set of TCP ports. The -%% node name is derived from the AMQP TCP port so a new node name is -%% generated. - -start_rabbitmq_node(Master, Config, NodeConfig, I) -> - Attempts0 = rabbit_ct_helpers:get_config(NodeConfig, failed_boot_attempts), - Attempts = case Attempts0 of - undefined -> 0; - N -> N - end, - NodeConfig1 = init_tcp_port_numbers(Config, NodeConfig, I), - NodeConfig2 = init_nodename(Config, NodeConfig1, I), - NodeConfig3 = init_config_filename(Config, NodeConfig2, I), - Steps = [ - fun write_config_file/3, - fun do_start_rabbitmq_node/3 - ], - case run_node_steps(Config, NodeConfig3, I, Steps) of - {skip, _} = Error - when Attempts >= ?NODE_START_ATTEMPTS -> - %% It's unlikely we'll ever succeed to start RabbitMQ. - Master ! {self(), Error}, - unlink(Master); - {skip, _} -> - %% Try again with another TCP port numbers base. - NodeConfig4 = move_nonworking_nodedir_away(NodeConfig3), - NodeConfig5 = rabbit_ct_helpers:set_config(NodeConfig4, - {failed_boot_attempts, Attempts + 1}), - start_rabbitmq_node(Master, Config, NodeConfig5, I); - NodeConfig4 -> - Master ! {self(), I, NodeConfig4}, - unlink(Master) - end. - -run_node_steps(Config, NodeConfig, I, [Step | Rest]) -> - case Step(Config, NodeConfig, I) of - {skip, _} = Error -> Error; - NodeConfig1 -> run_node_steps(Config, NodeConfig1, I, Rest) - end; -run_node_steps(_, NodeConfig, _, []) -> - NodeConfig. - -init_tcp_port_numbers(Config, NodeConfig, I) -> - %% If there is no TCP port numbers base previously calculated, - %% use the TCP port 21000. If a base was previously calculated, - %% increment it by the number of TCP ports we may open. - %% - %% Port 21000 is an arbitrary choice. We don't want to use the - %% default AMQP port of 5672 so other AMQP clients on the same host - %% do not accidentally use the testsuite broker. There seems to be - %% no registered service around this port in /etc/services. And it - %% should be far enough away from the default ephemeral TCP ports - %% range. - ExtraPorts = case rabbit_ct_helpers:get_config(Config, rmq_extra_tcp_ports) of - undefined -> []; - EP when is_list(EP) -> EP - end, - PortsCount = length(?TCP_PORTS_LIST) + length(ExtraPorts), - Base = case rabbit_ct_helpers:get_config(NodeConfig, tcp_ports_base) of - undefined -> tcp_port_base_for_broker(Config, I, PortsCount); - P -> P + PortsCount - end, - NodeConfig1 = rabbit_ct_helpers:set_config(NodeConfig, - {tcp_ports_base, Base}), - %% Now, compute all TCP port numbers from this base. - {NodeConfig2, _} = lists:foldl( - fun(PortName, {NewConfig, NextPort}) -> - { - rabbit_ct_helpers:set_config(NewConfig, {PortName, NextPort}), - NextPort + 1 - } - end, - {NodeConfig1, Base}, ?TCP_PORTS_LIST ++ ExtraPorts), - %% Finally, update the RabbitMQ configuration with the computed TCP - %% port numbers. Extra TCP ports are not added automatically to the - %% configuration. - update_tcp_ports_in_rmq_config(NodeConfig2, ?TCP_PORTS_LIST). - -tcp_port_base_for_broker(Config, I, PortsCount) -> - Base = case rabbit_ct_helpers:get_config(Config, tcp_ports_base) of - undefined -> - ?TCP_PORTS_BASE; - {skip_n_nodes, N} -> - tcp_port_base_for_broker1(?TCP_PORTS_BASE, N, PortsCount); - B -> - B - end, - tcp_port_base_for_broker1(Base, I, PortsCount). - -tcp_port_base_for_broker1(Base, I, PortsCount) -> - Base + I * PortsCount * ?NODE_START_ATTEMPTS. - -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_amqp = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbit, [{tcp_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_amqp_tls = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbit, [{ssl_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_mgmt = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_management, [{tcp_config, [{port, ?config(Key, NodeConfig)}]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_mqtt = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_mqtt, [{tcp_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_mqtt_tls = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_mqtt, [{ssl_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_web_mqtt = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_web_mqtt, [{tcp_config, [{port, ?config(Key, NodeConfig)}]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_web_stomp = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_web_stomp, [{tcp_config, [{port, ?config(Key, NodeConfig)}]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_web_stomp_tls | Rest]) -> - %% Skip this one, because we need more than just a port to configure - update_tcp_ports_in_rmq_config(NodeConfig, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_stomp = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_stomp, [{tcp_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_stomp_tls = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_stomp, [{ssl_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_stream = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_stream, [{tcp_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_stream_tls = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_stream, [{ssl_listeners, [?config(Key, NodeConfig)]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_erlang_dist | Rest]) -> - %% The Erlang distribution port doesn't appear in the configuration file. - update_tcp_ports_in_rmq_config(NodeConfig, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_erlang_dist_proxy | Rest]) -> - %% inet_proxy_dist port doesn't appear in the configuration file. - update_tcp_ports_in_rmq_config(NodeConfig, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, [tcp_port_prometheus = Key | Rest]) -> - NodeConfig1 = rabbit_ct_helpers:merge_app_env(NodeConfig, - {rabbitmq_prometheus, [{tcp_config, [{port, ?config(Key, NodeConfig)}]}]}), - update_tcp_ports_in_rmq_config(NodeConfig1, Rest); -update_tcp_ports_in_rmq_config(NodeConfig, []) -> - NodeConfig. - -init_nodename(Config, NodeConfig, I) -> - Hostname = ?config(rmq_hostname, Config), - Nodename0 = case rabbit_ct_helpers:get_config(Config, rmq_nodes_count) of - NodesList when is_list(NodesList) -> - Name = lists:nth(I + 1, NodesList), - rabbit_misc:format("~s@~s", [Name, Hostname]); - _ -> - Base = ?config(tcp_ports_base, NodeConfig), - Suffix0 = rabbit_ct_helpers:get_config(Config, - rmq_nodename_suffix), - Suffix = case Suffix0 of - undefined -> ""; - _ when is_atom(Suffix0) -> [$- | atom_to_list(Suffix0)]; - _ -> [$- | Suffix0] - end, - rabbit_misc:format("rmq-ct~s-~b-~b@~s", - [Suffix, I + 1, Base, Hostname]) - end, - Nodename = list_to_atom(Nodename0), - rabbit_ct_helpers:set_config(NodeConfig, [ - {nodename, Nodename}, - {initial_nodename, Nodename} - ]). - -init_config_filename(Config, NodeConfig, _I) -> - PrivDir = ?config(priv_dir, Config), - Nodename = ?config(nodename, NodeConfig), - ConfigDir = filename:join(PrivDir, Nodename), - ConfigFile = filename:join(ConfigDir, Nodename), - rabbit_ct_helpers:set_config(NodeConfig, - {erlang_node_config_filename, ConfigFile}). - -write_config_file(Config, NodeConfig, _I) -> - %% Prepare a RabbitMQ configuration. - ErlangConfigBase = ?config(erlang_node_config, Config), - ErlangConfigOverlay = ?config(erlang_node_config, NodeConfig), - ErlangConfig = rabbit_ct_helpers:merge_app_env_in_erlconf(ErlangConfigBase, - ErlangConfigOverlay), - ConfigFile = ?config(erlang_node_config_filename, NodeConfig), - ConfigDir = filename:dirname(ConfigFile), - Ret1 = file:make_dir(ConfigDir), - Ret2 = file:write_file(ConfigFile ++ ".config", - rabbit_ct_helpers:convert_to_unicode_binary( - io_lib:format("% vim:ft=erlang:~n~n~p.~n", [ErlangConfig]))), - case {Ret1, Ret2} of - {ok, ok} -> - NodeConfig; - {{error, eexist}, ok} -> - NodeConfig; - {{error, Reason}, _} when Reason =/= eexist -> - {skip, "Failed to create Erlang node config directory \"" ++ - ConfigDir ++ "\": " ++ file:format_error(Reason)}; - {_, {error, Reason}} -> - {skip, "Failed to create Erlang node config file \"" ++ - ConfigFile ++ "\": " ++ file:format_error(Reason)} - end. - -do_start_rabbitmq_node(Config, NodeConfig, I) -> - WithPlugins0 = rabbit_ct_helpers:get_config(Config, - broker_with_plugins), - WithPlugins = case is_list(WithPlugins0) of - true -> lists:nth(I + 1, WithPlugins0); - false -> WithPlugins0 - end, - CanUseSecondary = (I + 1) rem 2 =:= 0, - UseSecondaryUmbrella = case ?config(secondary_umbrella, Config) of - false -> false; - _ -> CanUseSecondary - end, - SrcDir = case WithPlugins of - false when UseSecondaryUmbrella -> ?config(secondary_rabbit_srcdir, - Config); - false -> ?config(rabbit_srcdir, Config); - _ when UseSecondaryUmbrella -> ?config(secondary_current_srcdir, - Config); - _ -> ?config(current_srcdir, Config) - end, - PrivDir = ?config(priv_dir, Config), - Nodename = ?config(nodename, NodeConfig), - InitialNodename = ?config(initial_nodename, NodeConfig), - DistPort = ?config(tcp_port_erlang_dist, NodeConfig), - ConfigFile = ?config(erlang_node_config_filename, NodeConfig), - %% Use inet_proxy_dist to handle distribution. This is used by the - %% partitions testsuite. - DistMod = rabbit_ct_helpers:get_config(Config, erlang_dist_module), - StartArgs0 = case DistMod of - undefined -> - ""; - _ -> - DistModS = atom_to_list(DistMod), - DistModPath = filename:absname( - filename:dirname(code:where_is_file(DistModS ++ ".beam"))), - DistArg = re:replace(DistModS, "_dist$", "", [{return, list}]), - "-pa \"" ++ DistModPath ++ "\" -proto_dist " ++ DistArg - end, - %% Set the net_ticktime. - CurrentTicktime = case net_kernel:get_net_ticktime() of - {ongoing_change_to, T} -> T; - T -> T - end, - StartArgs1 = case rabbit_ct_helpers:get_config(Config, net_ticktime) of - undefined -> - case CurrentTicktime of - 60 -> ok; - _ -> net_kernel:set_net_ticktime(60) - end, - StartArgs0; - Ticktime -> - case CurrentTicktime of - Ticktime -> ok; - _ -> net_kernel:set_net_ticktime(Ticktime) - end, - StartArgs0 ++ " -kernel net_ticktime " ++ integer_to_list(Ticktime) - end, - ExtraArgs0 = [], - ExtraArgs1 = case rabbit_ct_helpers:get_config(Config, rmq_plugins_dir) of - undefined -> - ExtraArgs0; - ExtraPluginsDir -> - [{"EXTRA_PLUGINS_DIR=~s", [ExtraPluginsDir]} - | ExtraArgs0] - end, - StartWithPluginsDisabled = rabbit_ct_helpers:get_config( - Config, start_rmq_with_plugins_disabled), - ExtraArgs2 = case StartWithPluginsDisabled of - true -> ["LEAVE_PLUGINS_DISABLED=yes" | ExtraArgs1]; - _ -> ExtraArgs1 - end, - KeepPidFile = rabbit_ct_helpers:get_config( - Config, keep_pid_file_on_exit), - ExtraArgs3 = case KeepPidFile of - true -> ["RABBITMQ_KEEP_PID_FILE_ON_EXIT=yes" | ExtraArgs2]; - _ -> ExtraArgs2 - end, - ExtraArgs4 = case WithPlugins of - false -> ExtraArgs3; - _ -> ["NOBUILD=1" | ExtraArgs3] - end, - ExtraArgs = case UseSecondaryUmbrella of - true -> - DepsDir = ?config(erlang_mk_depsdir, Config), - ErlLibs = os:getenv("ERL_LIBS"), - SecDepsDir = ?config(secondary_erlang_mk_depsdir, - Config), - SecErlLibs = lists:flatten( - string:replace(ErlLibs, - DepsDir, - SecDepsDir, - all)), - SecNewScriptsDir = filename:join([SecDepsDir, - SrcDir, - "sbin"]), - SecOldScriptsDir = filename:join([SecDepsDir, - "rabbit", - "scripts"]), - SecNewScriptsDirExists = filelib:is_dir( - SecNewScriptsDir), - SecScriptsDir = case SecNewScriptsDirExists of - true -> SecNewScriptsDir; - false -> SecOldScriptsDir - end, - [{"DEPS_DIR=~s", [SecDepsDir]}, - {"REBAR_DEPS_DIR=~s", [SecDepsDir]}, - {"ERL_LIBS=~s", [SecErlLibs]}, - {"RABBITMQ_SCRIPTS_DIR=~s", [SecScriptsDir]}, - {"RABBITMQ_SERVER=~s/rabbitmq-server", [SecScriptsDir]}, - {"RABBITMQCTL=~s/rabbitmqctl", [SecScriptsDir]}, - {"RABBITMQ_PLUGINS=~s/rabbitmq-plugins", [SecScriptsDir]} - | ExtraArgs4]; - false -> - ExtraArgs4 - end, - MakeVars = [ - {"RABBITMQ_NODENAME=~s", [Nodename]}, - {"RABBITMQ_NODENAME_FOR_PATHS=~s", [InitialNodename]}, - {"RABBITMQ_DIST_PORT=~b", [DistPort]}, - {"RABBITMQ_CONFIG_FILE=~s", [ConfigFile]}, - {"RABBITMQ_SERVER_START_ARGS=~s", [StartArgs1]}, - "RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=+S 2 +sbwt very_short +A 24", - "RABBITMQ_LOG=debug", - "RMQCTL_WAIT_TIMEOUT=180", - {"TEST_TMPDIR=~s", [PrivDir]} - | ExtraArgs], - Cmd = ["start-background-broker" | MakeVars], - case rabbit_ct_helpers:get_config(Config, rabbitmq_run_cmd) of - undefined -> - case rabbit_ct_helpers:make(Config, SrcDir, Cmd) of - {ok, _} -> - NodeConfig1 = rabbit_ct_helpers:set_config( - NodeConfig, - [{effective_srcdir, SrcDir}, - {make_vars_for_node_startup, MakeVars}]), - query_node(Config, NodeConfig1); - _ -> - AbortCmd = ["stop-node" | MakeVars], - _ = rabbit_ct_helpers:make(Config, SrcDir, AbortCmd), - {skip, "Failed to initialize RabbitMQ"} - end; - RunCmd -> - UseSecondary = CanUseSecondary andalso - rabbit_ct_helpers:get_config(Config, rabbitmq_run_secondary_cmd) =/= undefined, - EnabledPluginsMakeVars = case {UseSecondary, WithPlugins} of - {_, false} -> - ["RABBITMQ_ENABLED_PLUGINS=rabbit"]; - {true, _} -> - [{"RABBITMQ_ENABLED_PLUGINS=~s", [filename:basename(SrcDir)]}]; - _ -> - [] - end, - RmqRun = case CanUseSecondary of - false -> RunCmd; - _ -> rabbit_ct_helpers:get_config(Config, rabbitmq_run_secondary_cmd, RunCmd) - end, - case rabbit_ct_helpers:exec([RmqRun, "-C", SrcDir] ++ EnabledPluginsMakeVars ++ Cmd) of - {ok, _} -> - NodeConfig1 = rabbit_ct_helpers:set_config( - NodeConfig, - [{make_vars_for_node_startup, MakeVars}]), - query_node(Config, NodeConfig1); - _ -> - AbortCmd = ["stop-node" | MakeVars], - _ = rabbit_ct_helpers:exec([RunCmd | AbortCmd]), - {skip, "Failed to initialize RabbitMQ"} - end - end. - -query_node(Config, NodeConfig) -> - Nodename = ?config(nodename, NodeConfig), - PidFile = rpc(Config, Nodename, os, getenv, ["RABBITMQ_PID_FILE"]), - MnesiaDir = rpc(Config, Nodename, mnesia, system_info, [directory]), - {ok, PluginsDir} = rpc(Config, Nodename, application, get_env, - [rabbit, plugins_dir]), - {ok, EnabledPluginsFile} = rpc(Config, Nodename, application, get_env, - [rabbit, enabled_plugins_file]), - Vars0 = [{pid_file, PidFile}, - {mnesia_dir, MnesiaDir}, - {plugins_dir, PluginsDir}, - {enabled_plugins_file, EnabledPluginsFile}], - Vars = try - EnabledFeatureFlagsFile = rpc(Config, Nodename, - rabbit_feature_flags, - enabled_feature_flags_list_file, - []), - [{enabled_feature_flags_list_file, EnabledFeatureFlagsFile} - | Vars0] - catch - exit:{undef, [{rabbit_feature_flags, _, _, _} | _]} -> - %% This happens if the queried node is a RabbitMQ - %% 3.7.x node. If this is the case, we can ignore - %% this and leave the `enabled_plugins_file` config - %% variable unset. - ct:pal("NO RABBITMQ_FEATURE_FLAGS_FILE"), - Vars0 - end, - rabbit_ct_helpers:set_config(NodeConfig, Vars). - -maybe_cluster_nodes(Config) -> - Clustered0 = rabbit_ct_helpers:get_config(Config, rmq_nodes_clustered), - Clustered = case Clustered0 of - undefined -> true; - C when is_boolean(C) -> C - end, - if - Clustered -> cluster_nodes(Config); - true -> Config - end. - -cluster_nodes(Config) -> - [NodeConfig1 | NodeConfigs] = get_node_configs(Config), - cluster_nodes1(Config, NodeConfig1, NodeConfigs). - -cluster_nodes(Config, Nodes) -> - [NodeConfig1 | NodeConfigs] = [ - get_node_config(Config, Node) || Node <- Nodes], - cluster_nodes1(Config, NodeConfig1, NodeConfigs). - -cluster_nodes1(Config, NodeConfig1, [NodeConfig2 | Rest]) -> - case cluster_nodes(Config, NodeConfig2, NodeConfig1) of - ok -> cluster_nodes1(Config, NodeConfig1, Rest); - Error -> Error - end; -cluster_nodes1(Config, _, []) -> - Config. - -cluster_nodes(Config, NodeConfig1, NodeConfig2) -> - Nodename1 = ?config(nodename, NodeConfig1), - Nodename2 = ?config(nodename, NodeConfig2), - Cmds = [ - ["stop_app"], - ["join_cluster", Nodename2], - ["start_app"] - ], - cluster_nodes1(Config, Nodename1, Nodename2, Cmds). - -cluster_nodes1(Config, Nodename1, Nodename2, [Cmd | Rest]) -> - case rabbitmqctl(Config, Nodename1, Cmd) of - {ok, _} -> cluster_nodes1(Config, Nodename1, Nodename2, Rest); - _ -> {skip, - "Failed to cluster nodes \"" ++ atom_to_list(Nodename1) ++ - "\" and \"" ++ atom_to_list(Nodename2) ++ "\""} - end; -cluster_nodes1(_, _, _, []) -> - ok. - -handle_nodes_in_parallel(NodeConfigs, Fun) -> - T0 = erlang:timestamp(), - Parent = self(), - Procs = [ - begin - timer:sleep(rand:uniform(1000)), - spawn_link(fun() -> - T1 = erlang:timestamp(), - Ret = Fun(NodeConfig), - T2 = erlang:timestamp(), - ct:pal( - ?LOW_IMPORTANCE, - "Time to run ~p for node ~s: ~b µs", - [Fun, - ?config(nodename, NodeConfig), - timer:now_diff(T2, T1)]), - Parent ! {parallel_handling_ret, - self(), - NodeConfig, - Ret} - end) end - || NodeConfig <- NodeConfigs - ], - wait_for_node_handling(Procs, Fun, T0, []). - -wait_for_node_handling([], Fun, T0, Results) -> - T3 = erlang:timestamp(), - ct:pal( - ?LOW_IMPORTANCE, - "Time to run ~p for all nodes: ~b µs", - [Fun, timer:now_diff(T3, T0)]), - Results; -wait_for_node_handling(Procs, Fun, T0, Results) -> - receive - {parallel_handling_ret, Proc, NodeConfig, Ret} -> - Results1 = [{NodeConfig, Ret} | Results], - wait_for_node_handling(Procs -- [Proc], Fun, T0, Results1) - end. - -move_nonworking_nodedir_away(NodeConfig) -> - ConfigFile = ?config(erlang_node_config_filename, NodeConfig), - ConfigDir = filename:dirname(ConfigFile), - case os:getenv("RABBITMQ_CT_HELPERS_DELETE_UNUSED_NODES") =/= false - andalso ?OTP_RELEASE >= 23 of - true -> - file:del_dir_r(ConfigDir); - _ -> - NewName = filename:join( - filename:dirname(ConfigDir), - "_unused_nodedir_" ++ filename:basename(ConfigDir)), - file:rename(ConfigDir, NewName) - end, - lists:keydelete(erlang_node_config_filename, 1, NodeConfig). - -share_dist_and_proxy_ports_map(Config) -> - Map = [ - { - ?config(tcp_port_erlang_dist, NodeConfig), - ?config(tcp_port_erlang_dist_proxy, NodeConfig) - } || NodeConfig <- get_node_configs(Config)], - rpc_all(Config, - application, set_env, [kernel, dist_and_proxy_ports_map, Map]), - Config. - -rewrite_node_config_file(Config, Node) -> - NodeConfig = get_node_config(Config, Node), - I = if - is_integer(Node) -> Node; - true -> nodename_to_index(Config, Node) - end, - %% Keep copies of previous config file. - ConfigFile = ?config(erlang_node_config_filename, NodeConfig), - case rotate_config_file(ConfigFile) of - ok -> - ok; - {error, Reason} -> - ct:pal("Failed to rotate config file ~s: ~s", - [ConfigFile, file:format_error(Reason)]) - end, - %% Now we can write the new file. The caller is responsible for - %% restarting the broker/node. - case write_config_file(Config, NodeConfig, I) of - {skip, Error} -> {error, Error}; - _NodeConfig1 -> ok - end. - -rotate_config_file(ConfigFile) -> - rotate_config_file(ConfigFile, ConfigFile ++ ".config", 1). - -rotate_config_file(ConfigFile, OldName, Ext) -> - NewName = rabbit_misc:format("~s.config.~b", [ConfigFile, Ext]), - case filelib:is_file(NewName) of - true -> - case rotate_config_file(ConfigFile, NewName, Ext + 1) of - ok -> file:rename(OldName, NewName); - Error -> Error - end; - false -> - file:rename(OldName, NewName) - end. - -stop_rabbitmq_nodes_on_vms(Config) -> - NodeConfigs = get_node_configs(Config), - NodeConfigsPerCTPeer = [ - { - rabbit_ct_helpers:nodename_to_hostname(CTPeer), - CTPeer, - [] - } - || CTPeer <- - rabbit_ct_vm_helpers:get_ct_peers(Config)], - stop_rabbitmq_nodes_on_vms(Config, NodeConfigs, NodeConfigsPerCTPeer). - -stop_rabbitmq_nodes_on_vms(Config, [NodeConfig | Rest], - NodeConfigsPerCTPeer) -> - RabbitMQNode = ?config(nodename, NodeConfig), - Hostname = rabbit_ct_helpers:nodename_to_hostname(RabbitMQNode), - {H, N, NodeConfigs} = lists:keyfind(Hostname, 1, NodeConfigsPerCTPeer), - NewEntry = {H, N, [NodeConfig | NodeConfigs]}, - NodeConfigsPerCTPeer1 = lists:keystore(Hostname, 1, - NodeConfigsPerCTPeer, - NewEntry), - stop_rabbitmq_nodes_on_vms(Config, Rest, NodeConfigsPerCTPeer1); -stop_rabbitmq_nodes_on_vms(Config, [], NodeConfigsPerCTPeer) -> - lists:foreach( - fun({_, CTPeer, NodeConfigs}) -> - Config1 = rabbit_ct_helpers:set_config(Config, - {rmq_nodes, - NodeConfigs}), - rabbit_ct_vm_helpers:rpc(Config1, - CTPeer, - ?MODULE, - stop_rabbitmq_nodes, - [Config1]) - end, NodeConfigsPerCTPeer), - rabbit_ct_helpers:delete_config(Config, rmq_nodes). - -stop_rabbitmq_nodes(Config) -> - NodeConfigs = get_node_configs(Config), - _ = handle_nodes_in_parallel( - NodeConfigs, - fun(NodeConfig) -> - stop_rabbitmq_node(Config, NodeConfig) - end), - proplists:delete(rmq_nodes, Config). - -stop_rabbitmq_node(Config, NodeConfig) -> - SrcDir = ?config(effective_srcdir, NodeConfig), - InitialMakeVars = ?config(make_vars_for_node_startup, NodeConfig), - Nodename = ?config(nodename, NodeConfig), - InitialNodename = ?config(initial_nodename, NodeConfig), - MakeVars = InitialMakeVars ++ [ - {"RABBITMQ_NODENAME=~s", [Nodename]}, - {"RABBITMQ_NODENAME_FOR_PATHS=~s", [InitialNodename]} - ], - Cmd = ["stop-node" | MakeVars], - case rabbit_ct_helpers:get_config(Config, rabbitmq_run_cmd) of - undefined -> - rabbit_ct_helpers:make(Config, SrcDir, Cmd); - RunCmd -> - rabbit_ct_helpers:exec([RunCmd | Cmd]) - end, - NodeConfig. - -%% ------------------------------------------------------------------- -%% Helpers for partition simulation -%% ------------------------------------------------------------------- - -configure_dist_proxy(Config) -> - rabbit_ct_helpers:set_config(Config, - {erlang_dist_module, inet_tcp_proxy_dist}). - -block_traffic_between(NodeA, NodeB) -> - ct:pal( - ?LOW_IMPORTANCE, - "Blocking traffic between ~s and ~s", - [NodeA, NodeB]), - ?assertEqual(ok, rpc:call(NodeA, inet_tcp_proxy_dist, block, [NodeB])), - ?assertEqual(ok, rpc:call(NodeB, inet_tcp_proxy_dist, block, [NodeA])). - -allow_traffic_between(NodeA, NodeB) -> - ct:pal( - ?LOW_IMPORTANCE, - "Unblocking traffic between ~s and ~s", - [NodeA, NodeB]), - ?assertEqual(ok, rpc:call(NodeA, inet_tcp_proxy_dist, allow, [NodeB])), - ?assertEqual(ok, rpc:call(NodeB, inet_tcp_proxy_dist, allow, [NodeA])). - -set_partition_handling_mode_globally(Config, Mode) -> - rpc_all(Config, - application, set_env, [rabbit, cluster_partition_handling, Mode]). - -set_partition_handling_mode(Config, Nodes, Mode) -> - rpc(Config, Nodes, - application, set_env, [rabbit, cluster_partition_handling, Mode]). - -%% ------------------------------------------------------------------- -%% Calls to rabbitmqctl from Erlang. -%% ------------------------------------------------------------------- - -control_action(Command, Node) -> - control_action(Command, Node, [], []). - -control_action(Command, Node, Args) -> - control_action(Command, Node, Args, []). - -control_action(Command, Node, Args, Opts) -> - rabbit_control_helper:command(Command, Node, Args, Opts). - -%% Use rabbitmqctl(1) instead of using the Erlang API. - -rabbitmqctl(Config, Node, Args) -> - rabbitmqctl(Config, Node, Args, infinity). - -rabbitmqctl(Config, Node, Args, Timeout) -> - Rabbitmqctl = ?config(rabbitmqctl_cmd, Config), - NodeConfig = get_node_config(Config, Node), - Nodename = ?config(nodename, NodeConfig), - Env0 = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(Rabbitmqctl)}, - {"RABBITMQ_PID_FILE", ?config(pid_file, NodeConfig)}, - {"RABBITMQ_MNESIA_DIR", ?config(mnesia_dir, NodeConfig)}, - {"RABBITMQ_PLUGINS_DIR", ?config(plugins_dir, NodeConfig)}, - {"RABBITMQ_ENABLED_PLUGINS_FILE", - ?config(enabled_plugins_file, NodeConfig)} - ], - Ret = rabbit_ct_helpers:get_config( - NodeConfig, enabled_feature_flags_list_file), - Env = case Ret of - undefined -> - Env0; - EnabledFeatureFlagsFile -> - Env0 ++ - [{"RABBITMQ_FEATURE_FLAGS_FILE", EnabledFeatureFlagsFile}] - end, - Cmd = [Rabbitmqctl, "-n", Nodename | Args], - rabbit_ct_helpers:exec(Cmd, [{env, Env}, {timeout, Timeout}]). - -rabbitmqctl_list(Config, Node, Args) -> - {ok, StdOut} = rabbitmqctl(Config, Node, Args), - [<<"Timeout:", _/binary>>, - <<"Listing", _/binary>> - | Rows] = re:split(StdOut, <<"\n">>, [trim]), - [re:split(Row, <<"\t">>) || Row <- Rows]. - -rabbitmq_queues(Config, Node, Args) -> - RabbitmqQueues = ?config(rabbitmq_queues_cmd, Config), - NodeConfig = rabbit_ct_broker_helpers:get_node_config(Config, Node), - Nodename = ?config(nodename, NodeConfig), - Env0 = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(RabbitmqQueues)}, - {"RABBITMQ_PID_FILE", ?config(pid_file, NodeConfig)}, - {"RABBITMQ_MNESIA_DIR", ?config(mnesia_dir, NodeConfig)}, - {"RABBITMQ_PLUGINS_DIR", ?config(plugins_dir, NodeConfig)}, - {"RABBITMQ_ENABLED_PLUGINS_FILE", - ?config(enabled_plugins_file, NodeConfig)} - ], - Ret = rabbit_ct_helpers:get_config( - NodeConfig, enabled_feature_flags_list_file), - Env = case Ret of - undefined -> - Env0; - EnabledFeatureFlagsFile -> - Env0 ++ - [{"RABBITMQ_FEATURE_FLAGS_FILE", EnabledFeatureFlagsFile}] - end, - Cmd = [RabbitmqQueues, "-n", Nodename | Args], - rabbit_ct_helpers:exec(Cmd, [{env, Env}]). - -%% ------------------------------------------------------------------- -%% Other helpers. -%% ------------------------------------------------------------------- - -get_node_configs(Config) -> - ?config(rmq_nodes, Config). - -get_node_configs(Config, Key) -> - NodeConfigs = get_node_configs(Config), - [?config(Key, NodeConfig) || NodeConfig <- NodeConfigs]. - -get_node_config(Config, Node) when is_atom(Node) andalso Node =/= undefined -> - NodeConfigs = get_node_configs(Config), - get_node_config1(NodeConfigs, Node); -get_node_config(Config, I) when is_integer(I) andalso I >= 0 -> - NodeConfigs = get_node_configs(Config), - lists:nth(I + 1, NodeConfigs). - -get_node_config1([NodeConfig | Rest], Node) -> - case ?config(nodename, NodeConfig) of - Node -> NodeConfig; - _ -> case ?config(initial_nodename, NodeConfig) of - Node -> NodeConfig; - _ -> get_node_config1(Rest, Node) - end - end; -get_node_config1([], Node) -> - exit({unknown_node, Node}). - -get_node_config(Config, Node, Key) -> - NodeConfig = get_node_config(Config, Node), - ?config(Key, NodeConfig). - -set_node_config(Config, Node, Tuples) -> - NodeConfig = get_node_config(Config, Node), - NodeConfig1 = rabbit_ct_helpers:set_config(NodeConfig, Tuples), - replace_entire_node_config(Config, Node, NodeConfig1). - -replace_entire_node_config(Config, Node, NewNodeConfig) -> - NodeConfigs = get_node_configs(Config), - NodeConfigs1 = lists:map( - fun(NodeConfig) -> - Match = case ?config(nodename, NodeConfig) of - Node -> true; - _ -> case ?config(initial_nodename, NodeConfig) of - Node -> true; - _ -> false - end - end, - if - Match -> NewNodeConfig; - true -> NodeConfig - end - end, NodeConfigs), - rabbit_ct_helpers:set_config(Config, {rmq_nodes, NodeConfigs1}). - -nodename_to_index(Config, Node) -> - NodeConfigs = get_node_configs(Config), - nodename_to_index1(NodeConfigs, Node, 0). - -nodename_to_index1([NodeConfig | Rest], Node, I) -> - case ?config(nodename, NodeConfig) of - Node -> I; - _ -> case ?config(initial_nodename, NodeConfig) of - Node -> I; - _ -> nodename_to_index1(Rest, Node, I + 1) - end - end; -nodename_to_index1([], Node, _) -> - exit({unknown_node, Node}). - -node_uri(Config, Node) -> - node_uri(Config, Node, []). - -node_uri(Config, Node, amqp) -> - node_uri(Config, Node, []); -node_uri(Config, Node, management) -> - node_uri(Config, Node, [ - {scheme, "http"}, - {tcp_port_name, tcp_port_mgmt} - ]); -node_uri(Config, Node, Options) -> - Scheme = proplists:get_value(scheme, Options, "amqp"), - Hostname = case proplists:get_value(use_ipaddr, Options, false) of - true -> - {ok, Hostent} = inet:gethostbyname(?config(rmq_hostname, Config)), - format_ipaddr_for_uri(Hostent); - Family when Family =:= inet orelse Family =:= inet6 -> - {ok, Hostent} = inet:gethostbyname(?config(rmq_hostname, Config), - Family), - format_ipaddr_for_uri(Hostent); - false -> - ?config(rmq_hostname, Config) - end, - TcpPortName = proplists:get_value(tcp_port_name, Options, tcp_port_amqp), - TcpPort = get_node_config(Config, Node, TcpPortName), - UserPass = case proplists:get_value(with_user, Options, false) of - true -> - User = proplists:get_value(user, Options, "guest"), - Password = proplists:get_value(password, Options, "guest"), - io_lib:format("~s:~s@", [User, Password]); - false -> - "" - end, - list_to_binary( - rabbit_misc:format("~s://~s~s:~b", - [Scheme, UserPass, Hostname, TcpPort])). - -format_ipaddr_for_uri( - #hostent{h_addrtype = inet, h_addr_list = [IPAddr | _]}) -> - {A, B, C, D} = IPAddr, - io_lib:format("~b.~b.~b.~b", [A, B, C, D]); -format_ipaddr_for_uri( - #hostent{h_addrtype = inet6, h_addr_list = [IPAddr | _]}) -> - {A, B, C, D, E, F, G, H} = IPAddr, - Res0 = io_lib:format( - "~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b", - [A, B, C, D, E, F, G, H]), - Res1 = re:replace(Res0, "(^0(:0)+$|^(0:)+|(:0)+$)|:(0:)+", "::"), - "[" ++ Res1 ++ "]". - - -%% Virtual host management - -add_vhost(Config, VHost) -> - add_vhost(Config, 0, VHost). - -add_vhost(Config, Node, VHost) -> - add_vhost(Config, Node, VHost, <<"acting-user">>). - -add_vhost(Config, Node, VHost, Username) -> - catch rpc(Config, Node, rabbit_vhost, add, [VHost, Username]). - -delete_vhost(Config, VHost) -> - delete_vhost(Config, 0, VHost). - -delete_vhost(Config, Node, VHost) -> - delete_vhost(Config, Node, VHost, <<"acting-user">>). - -delete_vhost(Config, Node, VHost, Username) -> - catch rpc(Config, Node, rabbit_vhost, delete, [VHost, Username]). - -force_vhost_failure(Config, VHost) -> force_vhost_failure(Config, 0, VHost). - -force_vhost_failure(Config, Node, VHost) -> - force_vhost_failure(Config, Node, VHost, 100). - -force_vhost_failure(_Config, _Node, VHost, 0) -> - error({failed_to_force_vhost_failure, no_more_attempts_left, VHost}); -force_vhost_failure(Config, Node, VHost, Attempts) -> - case rpc(Config, Node, rabbit_vhost_sup_sup, is_vhost_alive, [VHost]) of - true -> - try - MessageStorePid = get_message_store_pid(Config, Node, VHost), - rpc(Config, Node, - erlang, exit, [MessageStorePid, force_vhost_failure]), - %% Give it a time to fail - timer:sleep(300), - force_vhost_failure(Config, Node, VHost, Attempts - 1) - catch - %% The vhost terminated while we were checking again. - exit:{exception, {shutdown, _}} -> - timer:sleep(300), - force_vhost_failure(Config, Node, VHost, Attempts - 1); - error:{badmatch, - {error, {vhost_supervisor_not_running, VHost}}} -> - %% This badmatch may occur in get_message_store_pid/3 as a - %% result of `{ok, VHostSup} = rpc(...)`. - timer:sleep(300), - force_vhost_failure(Config, Node, VHost, Attempts - 1) - end; - false -> ok - end. - -set_alarm(Config, Node, file_descriptor_limit = Resource) -> - rpc(Config, Node, rabbit_alarm, set_alarm, [{Resource, []}]); -set_alarm(Config, Node, memory = Resource) -> - rpc(Config, Node, rabbit_alarm, set_alarm, [{{resource_limit, Resource, Node}, []}]); -set_alarm(Config, Node, disk = Resource) -> - rpc(Config, Node, rabbit_alarm, set_alarm, [{{resource_limit, Resource, Node}, []}]). - -get_alarms(Config, Node) -> - rpc(Config, Node, rabbit_alarm, get_alarms, []). - -get_local_alarms(Config, Node) -> - rpc(Config, Node, rabbit_alarm, get_local_alarms, []). - -clear_alarm(Config, Node, file_descriptor_limit = Resource) -> - rpc(Config, Node, rabbit_alarm, clear_alarm, [Resource]); -clear_alarm(Config, Node, memory = Resource) -> - rpc(Config, Node, rabbit_alarm, clear_alarm, [{resource_limit, Resource, Node}]); -clear_alarm(Config, Node, disk = Resource) -> - rpc(Config, Node, rabbit_alarm, clear_alarm, [{resource_limit, Resource, Node}]). - -clear_all_alarms(Config, Node) -> - lists:foreach(fun ({file_descriptor_limit, _}) -> - clear_alarm(Config, Node, file_descriptor_limit); - ({{resource_limit, Resource, OnNode}, _}) when OnNode =:= Node -> - clear_alarm(Config, Node, Resource); - (_) -> ok - end, get_alarms(Config, Node)), - ok. - -get_message_store_pid(Config, Node, VHost) -> - {ok, VHostSup} = rpc(Config, Node, - rabbit_vhost_sup_sup, get_vhost_sup, [VHost]), - Children = rpc(Config, Node, supervisor, which_children, [VHostSup]), - [MsgStorePid] = [Pid || {Name, Pid, _, _} <- Children, - Name == msg_store_persistent], - MsgStorePid. - -add_user(Config, Username) -> - %% for many tests it is convenient that - %% the username and password match - add_user(Config, 0, Username, Username). - -add_user(Config, Username, Password) -> - add_user(Config, 0, Username, Password). - -add_user(Config, Node, Username, Password) -> - add_user(Config, Node, Username, Password, <<"acting-user">>). - -add_user(Config, Node, Username, Password, AuditUsername) -> - catch rpc(Config, Node, rabbit_auth_backend_internal, add_user, - [rabbit_data_coercion:to_binary(Username), - rabbit_data_coercion:to_binary(Password), - AuditUsername]). - -set_user_tags(Config, Node, Username, Tags) -> - set_user_tags(Config, Node, Username, Tags, <<"acting-user">>). - -set_user_tags(Config, Node, Username, Tags, AuditUsername) -> - catch rpc(Config, Node, rabbit_auth_backend_internal, set_tags, - [Username, Tags, AuditUsername]). - -delete_user(Config, Username) -> - delete_user(Config, 0, Username). - -delete_user(Config, Node, Username) -> - delete_user(Config, Node, Username, <<"acting-user">>). - -delete_user(Config, Node, Username, AuditUsername) -> - catch rpc(Config, Node, rabbit_auth_backend_internal, delete_user, - [Username, AuditUsername]). - -change_password(Config, Username, Password) -> - change_password(Config, 0, Username, Password, <<"acting-user">>). - -change_password(Config, Node, Username, Password, AuditUsername) -> - rpc(Config, Node, rabbit_auth_backend_internal, change_password, - [Username, Password, AuditUsername]). - -clear_password(Config, Node, Username, AuditUsername) -> - rpc(Config, Node, rabbit_auth_backend_internal, clear_password, - [Username, AuditUsername]). - -switch_credential_validator(Config, accept_everything) -> - rpc(Config, 0, application, set_env, - [rabbit, credential_validator, - [{validation_backend, rabbit_credential_validator_accept_everything}]]); - -switch_credential_validator(Config, min_length) -> - switch_credential_validator(Config, min_length, 5); - -switch_credential_validator(Config, regexp) -> - switch_credential_validator(Config, regexp, <<"^xyz\\d{10,12}$">>). - - -switch_credential_validator(Config, min_length, MinLength) -> - ok = rpc(Config, 0, application, set_env, - [rabbit, credential_validator, - [{validation_backend, rabbit_credential_validator_min_password_length}, - {min_length, MinLength}]]); - -switch_credential_validator(Config, regexp, RegExp) -> - ok = rpc(Config, 0, application, set_env, - [rabbit, credential_validator, - [{validation_backend, rabbit_credential_validator_password_regexp}, - {regexp, RegExp}]]). - -set_full_permissions(Config, VHost) -> - set_permissions(Config, 0, <<"guest">>, VHost, <<".*">>, <<".*">>, <<".*">>). -set_full_permissions(Config, Username, VHost) -> - set_permissions(Config, 0, Username, VHost, <<".*">>, <<".*">>, <<".*">>). -set_full_permissions(Config, Node, Username, VHost) -> - set_permissions(Config, Node, Username, VHost, <<".*">>, <<".*">>, <<".*">>). - -set_permissions(Config, Username, VHost, ConfigurePerm, WritePerm, ReadPerm) -> - set_permissions(Config, 0, Username, VHost, ConfigurePerm, WritePerm, ReadPerm). - -set_permissions(Config, Node, Username, VHost, ConfigurePerm, WritePerm, ReadPerm) -> - set_permissions(Config, Node, Username, VHost, ConfigurePerm, WritePerm, ReadPerm, - <<"acting-user">>). - -set_permissions(Config, Node, Username, VHost, ConfigurePerm, WritePerm, ReadPerm, - ActingUser) -> - rpc(Config, Node, - rabbit_auth_backend_internal, - set_permissions, - [rabbit_data_coercion:to_binary(Username), - rabbit_data_coercion:to_binary(VHost), - rabbit_data_coercion:to_binary(ConfigurePerm), - rabbit_data_coercion:to_binary(WritePerm), - rabbit_data_coercion:to_binary(ReadPerm), - ActingUser]). - -clear_permissions(Config, VHost) -> - clear_permissions(Config, 0, <<"guest">>, VHost). -clear_permissions(Config, Username, VHost) -> - clear_permissions(Config, 0, Username, VHost). - -clear_permissions(Config, Node, Username, VHost) -> - clear_permissions(Config, Node, Username, VHost, <<"acting-user">>). - -clear_permissions(Config, Node, Username, VHost, ActingUser) -> - catch rpc(Config, Node, - rabbit_auth_backend_internal, - clear_permissions, - [rabbit_data_coercion:to_binary(Username), - rabbit_data_coercion:to_binary(VHost), - ActingUser]). - -set_vhost_limit(Config, Node, VHost, Limit0, Value) -> - Limit = case Limit0 of - max_connections -> <<"max-connections">>; - max_queues -> <<"max-queues">>; - Other -> rabbit_data_coercion:to_binary(Other) - end, - Definition = rabbit_json:encode(#{Limit => Value}), - rpc(Config, Node, - rabbit_vhost_limit, - set, - [VHost, Definition, <<"ct-tests">>]). - -set_user_limits(Config, Username, Limits) -> - set_user_limits(Config, 0, Username, Limits). - -set_user_limits(Config, Node, Username, Limits0) when is_map(Limits0) -> - Limits = - maps:fold(fun(Limit0, Val, Acc) -> - Limit = case Limit0 of - max_connections -> <<"max-connections">>; - max_channels -> <<"max-channels">>; - Other -> rabbit_data_coercion:to_binary(Other) - end, - maps:merge(#{Limit => Val}, Acc) - end, #{}, Limits0), - rpc(Config, Node, - rabbit_auth_backend_internal, - set_user_limits, - [Username, Limits, <<"ct-tests">>]). - -clear_user_limits(Config, Username, Limit) -> - clear_user_limits(Config, 0, Username, Limit). - -clear_user_limits(Config, Node, Username, Limit0) -> - Limit = case Limit0 of - all -> <<"all">>; - max_connections -> <<"max-connections">>; - max_channels -> <<"max-channels">>; - Other -> rabbit_data_coercion:to_binary(Other) - end, - rpc(Config, Node, - rabbit_auth_backend_internal, - clear_user_limits, - [Username, Limit, <<"ct-tests">>]). - -%% Functions to execute code on a remote node/broker. - -add_code_path_to_node(Node, Module) -> - Path1 = filename:dirname(code:which(Module)), - Path2 = filename:dirname(code:which(?MODULE)), - Paths = filter_ct_helpers_and_testsuites_paths( - lists:usort([Path1, Path2])), - case Paths of - [] -> - ok; - _ -> - case rpc:call(Node, code, get_path, []) of - ExistingPaths when is_list(ExistingPaths) -> - lists:foreach( - fun(P) -> - case lists:member(P, ExistingPaths) of - true -> - ok; - false -> - case rpc:call( - Node, code, add_pathz, [P]) of - true -> - ok; - Error -> - erlang:error({Error, P}) - end - end - end, Paths); - Error -> - ct:pal(?LOW_IMPORTANCE, - "Failed to retrieve current code path from node ~s: ~p~n", - [Node, Error]), - ok - end - end. - -filter_ct_helpers_and_testsuites_paths(CodePath) -> - lists:filter( - fun(Dir) -> - DirName = filename:basename(Dir), - ParentDirName = filename:basename( - filename:dirname(Dir)), - Dir =/= "." andalso - %% FIXME: This filtering is too naive. How to properly - %% distinguish RabbitMQ-related applications from - %% test-only modules? - ((ParentDirName =:= "rabbitmq_ct_helpers" andalso - DirName =:= "ebin") orelse - (ParentDirName =:= "rabbitmq_ct_client_helpers" andalso - DirName =:= "ebin") orelse - (DirName =:= "test")) - end, CodePath). - -add_code_path_to_all_nodes(Config, Module) -> - Nodenames = get_node_configs(Config, nodename), - [ok = add_code_path_to_node(Nodename, Module) - || Nodename <- Nodenames], - ok. - -rpc(Config, Node, Module, Function, Args) -when is_atom(Node) andalso Node =/= undefined -> - rpc(Config, Node, Module, Function, Args, infinity); -rpc(Config, I, Module, Function, Args) -when is_integer(I) andalso I >= 0 -> - Node = get_node_config(Config, I, nodename), - rpc(Config, Node, Module, Function, Args); -rpc(Config, Nodes, Module, Function, Args) -when is_list(Nodes) -> - [rpc(Config, Node, Module, Function, Args) || Node <- Nodes]. - -rpc(_Config, Node, Module, Function, Args, Timeout) -when is_atom(Node) andalso Node =/= undefined -> - %% We add some directories to the broker node search path. - add_code_path_to_node(Node, Module), - erpc:call(Node, Module, Function, Args, Timeout); -rpc(Config, I, Module, Function, Args, Timeout) -when is_integer(I) andalso I >= 0 -> - Node = get_node_config(Config, I, nodename), - rpc(Config, Node, Module, Function, Args, Timeout); -rpc(Config, Nodes, Module, Function, Args, Timeout) -when is_list(Nodes) -> - [rpc(Config, Node, Module, Function, Args, Timeout) || Node <- Nodes]. - -rpc_all(Config, Module, Function, Args) -> - Nodes = get_node_configs(Config, nodename), - rpc(Config, Nodes, Module, Function, Args). - -rpc_all(Config, Module, Function, Args, Timeout) -> - Nodes = get_node_configs(Config, nodename), - rpc(Config, Nodes, Module, Function, Args, Timeout). - -%% Functions to start/restart/stop only the broker or the full Erlang -%% node. - -start_node(Config, Node) -> - NodeConfig = get_node_config(Config, Node), - I = if - is_atom(Node) -> nodename_to_index(Config, Node); - true -> Node - end, - case do_start_rabbitmq_node(Config, NodeConfig, I) of - {skip, _} = Error -> {error, Error}; - _ -> ok - end. - -start_broker(Config, Node) -> - ok = rpc(Config, Node, rabbit, start, []). - -restart_broker(Config, Node) -> - ok = rpc(Config, Node, ?MODULE, do_restart_broker, []). - -do_restart_broker() -> - ok = rabbit:stop(), - ok = rabbit:start(). - -stop_broker(Config, Node) -> - ok = rpc(Config, Node, rabbit, stop, []). - -restart_node(Config, Node) -> - ok = stop_node(Config, Node), - ok = start_node(Config, Node). - -stop_node(Config, Node) -> - NodeConfig = get_node_config(Config, Node), - case stop_rabbitmq_node(Config, NodeConfig) of - {skip, _} = Error -> Error; - _ -> ok - end. - -stop_node_after(Config, Node, Sleep) -> - timer:sleep(Sleep), - stop_node(Config, Node). - -kill_node(Config, Node) -> - Pid = rpc(Config, Node, os, getpid, []), - %% FIXME maybe_flush_cover(Cfg), - Cmd = case os:type() of - {win32, _} -> - case os:find_executable("taskkill.exe") of - false -> - rabbit_misc:format( - "PowerShell -Command " - "\"Stop-Process -Id ~s -Force\"", - [Pid]); - _ -> - rabbit_misc:format("taskkill /PID ~s /F", [Pid]) - end; - _ -> - rabbit_misc:format("kill -9 ~s", [Pid]) - end, - os:cmd(Cmd), - await_os_pid_death(Pid). - -kill_node_after(Config, Node, Sleep) -> - timer:sleep(Sleep), - kill_node(Config, Node). - -cluster_members_online(Config, Node) -> - rpc(Config, Node, rabbit_nodes, all_running, []). - -await_os_pid_death(Pid) -> - case rabbit_misc:is_os_process_alive(Pid) of - true -> timer:sleep(100), - await_os_pid_death(Pid); - false -> ok - end. - -reset_node(Config, Node) -> - Name = rabbit_ct_broker_helpers:get_node_config(Config, Node, nodename), - rabbit_control_helper:command(reset, Name). - -force_reset_node(Config, Node) -> - Name = rabbit_ct_broker_helpers:get_node_config(Config, Node, nodename), - rabbit_control_helper:command(force_reset, Name). - -forget_cluster_node(Config, Node, NodeToForget) -> - forget_cluster_node(Config, Node, NodeToForget, []). -forget_cluster_node(Config, Node, NodeToForget, Opts) -> - Name = rabbit_ct_broker_helpers:get_node_config(Config, Node, nodename), - NameToForget = - rabbit_ct_broker_helpers:get_node_config(Config, NodeToForget, nodename), - rabbit_control_helper:command(forget_cluster_node, Name, [NameToForget], Opts). - -is_feature_flag_supported(Config, FeatureName) -> - Nodes = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - is_feature_flag_supported(Config, Nodes, FeatureName). - -is_feature_flag_supported(Config, [Node1 | _] = Nodes, FeatureName) -> - rabbit_ct_broker_helpers:rpc( - Config, Node1, - rabbit_feature_flags, is_supported_remotely, - [Nodes, [FeatureName], 60000]). - -enable_feature_flag(Config, FeatureName) -> - Nodes = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - enable_feature_flag(Config, Nodes, FeatureName). - -enable_feature_flag(Config, [Node1 | _] = Nodes, FeatureName) -> - case is_feature_flag_supported(Config, Nodes, FeatureName) of - true -> - rabbit_ct_broker_helpers:rpc( - Config, Node1, rabbit_feature_flags, enable, [FeatureName]); - false -> - {skip, - lists:flatten( - io_lib:format("'~s' feature flag is unsupported", - [FeatureName]))} - end. - -mark_as_being_drained(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, mark_as_being_drained, []). -unmark_as_being_drained(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, unmark_as_being_drained, []). - -drain_node(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, drain, []). -revive_node(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, revive, []). - -is_being_drained_consistent_read(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, is_being_drained_consistent_read, [Node]). -is_being_drained_local_read(Config, Node) -> - rabbit_ct_broker_helpers:rpc(Config, Node, rabbit_maintenance, is_being_drained_local_read, [Node]). - -is_being_drained_consistent_read(Config, TargetNode, NodeToCheck) -> - rabbit_ct_broker_helpers:rpc(Config, TargetNode, rabbit_maintenance, is_being_drained_consistent_read, [NodeToCheck]). -is_being_drained_local_read(Config, TargetNode, NodeToCheck) -> - rabbit_ct_broker_helpers:rpc(Config, TargetNode, rabbit_maintenance, is_being_drained_local_read, [NodeToCheck]). - -%% From a given list of gen_tcp client connections, return the list of -%% connection handler PID in RabbitMQ. -get_connection_pids(Connections) -> - ConnInfos = [ - begin - {ok, {Addr, Port}} = inet:sockname(Connection), - [{peer_host, Addr}, {peer_port, Port}] - end || Connection <- Connections], - lists:filter( - fun(Conn) -> - ConnInfo = rabbit_networking:connection_info(Conn, - [peer_host, peer_port]), - %% On at least Mac OS X, for a connection on localhost, the - %% client side of the connection gives its IPv4 address - %% (127.0.0.1), but the server side gives some kind of - %% non-standard IPv6 address (::ffff:7f00:1, not even the - %% standard ::1). So let's test for this alternate form too. - AltConnInfo = case proplists:get_value(peer_host, ConnInfo) of - {0, 0, 0, 0, 0, 16#ffff, 16#7f00, N} -> - lists:keyreplace(peer_host, 1, ConnInfo, - {peer_host, {127, 0, 0, N}}); - _ -> - ConnInfo - end, - lists:member(ConnInfo, ConnInfos) orelse - lists:member(AltConnInfo, ConnInfos) - end, rabbit_networking:connections()). - -close_all_connections(Config, Node, Reason) -> - rpc(Config, Node, rabbit_networking, close_all_connections, [Reason]), - ok. - -%% ------------------------------------------------------------------- -%% Policy helpers. -%% ------------------------------------------------------------------- - -set_policy(Config, Node, Name, Pattern, ApplyTo, Definition) -> - set_policy(Config, Node, Name, Pattern, ApplyTo, Definition, <<"acting-user">>). - -set_policy(Config, Node, Name, Pattern, ApplyTo, Definition, Username) -> - set_policy_in_vhost(Config, Node, <<"/">>, Name, Pattern, ApplyTo, Definition, Username). - -set_policy_in_vhost(Config, Node, VirtualHost, Name, Pattern, ApplyTo, Definition) -> - ok = rpc(Config, Node, - rabbit_policy, set, [VirtualHost, Name, Pattern, Definition, 0, ApplyTo, - <<"acting-user">>]). -set_policy_in_vhost(Config, Node, VirtualHost, Name, Pattern, ApplyTo, Definition, Username) -> - ok = rpc(Config, Node, - rabbit_policy, set, [VirtualHost, Name, Pattern, Definition, 0, ApplyTo, - Username]). - -clear_policy(Config, Node, Name) -> - clear_policy(Config, Node, Name, <<"acting-user">>). - -clear_policy(Config, Node, Name, Username) -> - rpc(Config, Node, - rabbit_policy, delete, [<<"/">>, Name, Username]). - -set_operator_policy(Config, Node, Name, Pattern, ApplyTo, Definition) -> - ok = rpc(Config, Node, - rabbit_policy, set_op, [<<"/">>, Name, Pattern, Definition, 0, ApplyTo, - <<"acting-user">>]). - -clear_operator_policy(Config, Node, Name) -> - rpc(Config, Node, - rabbit_policy, delete_op, [<<"/">>, Name, <<"acting-user">>]). - -set_ha_policy(Config, Node, Pattern, Policy) -> - set_ha_policy(Config, Node, Pattern, Policy, []). - -set_ha_policy(Config, Node, Pattern, Policy, Extra) -> - set_policy(Config, Node, Pattern, Pattern, <<"queues">>, - ha_policy(Policy) ++ Extra). - -ha_policy(<<"all">>) -> [{<<"ha-mode">>, <<"all">>}]; -ha_policy({Mode, Params}) -> [{<<"ha-mode">>, Mode}, - {<<"ha-params">>, Params}]. - -set_ha_policy_all(Config) -> - set_ha_policy(Config, 0, <<".*">>, <<"all">>), - Config. - -set_ha_policy_all(Config, Extra) -> - set_ha_policy(Config, 0, <<".*">>, <<"all">>, Extra), - Config. - -set_ha_policy_two_pos(Config) -> - Members = [ - rabbit_misc:atom_to_binary(N) - || N <- get_node_configs(Config, nodename)], - TwoNodes = [M || M <- lists:sublist(Members, 2)], - set_ha_policy(Config, 0, <<"^ha.two.">>, {<<"nodes">>, TwoNodes}, - [{<<"ha-promote-on-shutdown">>, <<"always">>}]), - set_ha_policy(Config, 0, <<"^ha.auto.">>, {<<"nodes">>, TwoNodes}, - [{<<"ha-sync-mode">>, <<"automatic">>}, - {<<"ha-promote-on-shutdown">>, <<"always">>}]), - Config. - -set_ha_policy_two_pos_batch_sync(Config) -> - Members = [ - rabbit_misc:atom_to_binary(N) - || N <- get_node_configs(Config, nodename)], - TwoNodes = [M || M <- lists:sublist(Members, 2)], - set_ha_policy(Config, 0, <<"^ha.two.">>, {<<"nodes">>, TwoNodes}, - [{<<"ha-promote-on-shutdown">>, <<"always">>}]), - set_ha_policy(Config, 0, <<"^ha.auto.">>, {<<"nodes">>, TwoNodes}, - [{<<"ha-sync-mode">>, <<"automatic">>}, - {<<"ha-sync-batch-size">>, 200}, - {<<"ha-promote-on-shutdown">>, <<"always">>}]), - Config. - -%% ------------------------------------------------------------------- -%% Parameter helpers. -%% ------------------------------------------------------------------- - -set_parameter(Config, Node, Component, Name, Value) -> - set_parameter(Config, Node, <<"/">>, Component, Name, Value, none). - -set_parameter(Config, Node, VHost, Component, Name, Value) -> - set_parameter(Config, Node, VHost, Component, Name, Value, none). - -set_parameter(Config, Node, VHost, Component, Name, Value, Username) -> - ok = rpc(Config, Node, - rabbit_runtime_parameters, set, [VHost, Component, Name, Value, Username]). - -clear_parameter(Config, Node, Component, Name) -> - clear_parameter(Config, Node, <<"/">>, Component, Name). - -clear_parameter(Config, Node, VHost, Component, Name) -> - clear_parameter(Config, Node, VHost, Component, Name, <<"acting-user">>). - -clear_parameter(Config, Node, VHost, Component, Name, Username) -> - ok = rpc(Config, Node, - rabbit_runtime_parameters, clear, [VHost, Component, Name, Username]). - -set_global_parameter(Config, Name, Value) -> - set_global_parameter(Config, 0, Name, Value). -set_global_parameter(Config, Node, Name, Value) -> - ok = rpc(Config, Node, - rabbit_runtime_parameters, set_global, [Name, Value, <<"acting-user">>]). - -clear_global_parameter(Config, Name) -> - clear_global_parameter(Config, 0, Name). -clear_global_parameter(Config, Node, Name) -> - ok = rpc(Config, Node, - rabbit_runtime_parameters, clear_global, [Name, <<"acting-user">>]). - -%% ------------------------------------------------------------------- -%% Parameter helpers. -%% ------------------------------------------------------------------- - -enable_plugin(Config, Node, Plugin) -> - plugin_action(Config, Node, [enable, Plugin]). - -disable_plugin(Config, Node, Plugin) -> - plugin_action(Config, Node, [disable, Plugin]). - -plugin_action(Config, Node, Args) -> - Rabbitmqplugins = ?config(rabbitmq_plugins_cmd, Config), - NodeConfig = get_node_config(Config, Node), - Nodename = ?config(nodename, NodeConfig), - Env = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(Rabbitmqplugins)}, - {"RABBITMQ_PID_FILE", ?config(pid_file, NodeConfig)}, - {"RABBITMQ_MNESIA_DIR", ?config(mnesia_dir, NodeConfig)}, - {"RABBITMQ_PLUGINS_DIR", ?config(plugins_dir, NodeConfig)}, - {"RABBITMQ_ENABLED_PLUGINS_FILE", - ?config(enabled_plugins_file, NodeConfig)} - ], - Cmd = [Rabbitmqplugins, "-n", Nodename | Args], - {ok, _} = rabbit_ct_helpers:exec(Cmd, [{env, Env}]), - ok. - -%% ------------------------------------------------------------------- - -test_channel() -> - Me = self(), - Writer = spawn(fun () -> test_writer(Me) end), - {ok, Limiter} = rabbit_limiter:start_link(no_id), - {ok, Ch} = rabbit_channel:start_link( - 1, Me, Writer, Me, "", rabbit_framing_amqp_0_9_1, - user(<<"guest">>), <<"/">>, [], Me, Limiter), - {Writer, Limiter, Ch}. - -test_writer(Pid) -> - receive - {'$gen_call', From, flush} -> gen_server:reply(From, ok), - test_writer(Pid); - {send_command, Method} -> Pid ! Method, - test_writer(Pid); - shutdown -> ok - end. - -user(Username) -> - #user{username = Username, - tags = [administrator], - authz_backends = [{rabbit_auth_backend_internal, none}]}. diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_ct_config_schema.erl b/deps/rabbitmq_ct_helpers/src/rabbit_ct_config_schema.erl deleted file mode 100644 index 96d42ba98770..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_ct_config_schema.erl +++ /dev/null @@ -1,107 +0,0 @@ -%% 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) 2017-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_config_schema). --include_lib("common_test/include/ct.hrl"). - --export([init_schemas/2]). --export([run_snippets/1]). - -init_schemas(App, Config) -> - ResultsDir = filename:join(?config(priv_dir, Config), "results"), - Snippets = filename:join(?config(data_dir, Config), - atom_to_list(App) ++ ".snippets"), - ok = file:make_dir(ResultsDir), - rabbit_ct_helpers:set_config(Config, [ - {results_dir, ResultsDir}, - {conf_snippets, Snippets} - ]). - -run_snippets(Config) -> - {ok, [Snippets]} = file:consult(?config(conf_snippets, Config)), - ct:pal("Loaded config schema snippets: ~p", [Snippets]), - lists:map( - fun({N, S, C, P}) -> ok = test_snippet(Config, {snippet_id(N), S, []}, C, P); - ({N, S, A, C, P}) -> ok = test_snippet(Config, {snippet_id(N), S, A}, C, P) - end, - Snippets), - ok. - -snippet_id(N) when is_integer(N) -> - integer_to_list(N); -snippet_id(F) when is_float(F) -> - float_to_list(F); -snippet_id(A) when is_atom(A) -> - atom_to_list(A); -snippet_id(L) when is_list(L) -> - L. - -test_snippet(Config, Snippet, Expected, _Plugins) -> - {ConfFile, AdvancedFile} = write_snippet(Config, Snippet), - %% We ignore the rabbit -> log portion of the config on v3.9+, where the lager - %% dependency has been dropped - Generated = case code:which(lager) of - non_existing -> - without_rabbit_log(generate_config(ConfFile, AdvancedFile)); - _ -> - generate_config(ConfFile, AdvancedFile) - end, - Gen = deepsort(Generated), - Exp = deepsort(Expected), - case Exp of - Gen -> ok; - _ -> - ct:pal("Expected: ~p~ngenerated: ~p", [Expected, Generated]), - ct:pal("Expected (sorted): ~p~ngenerated (sorted): ~p", [Exp, Gen]), - error({config_mismatch, Snippet, Exp, Gen}) - end. - -write_snippet(Config, {Name, Conf, Advanced}) -> - ResultsDir = ?config(results_dir, Config), - file:make_dir(filename:join(ResultsDir, Name)), - ConfFile = filename:join([ResultsDir, Name, "config.conf"]), - AdvancedFile = filename:join([ResultsDir, Name, "advanced.config"]), - - file:write_file(ConfFile, Conf), - rabbit_file:write_term_file(AdvancedFile, [Advanced]), - {ConfFile, AdvancedFile}. - -generate_config(ConfFile, AdvancedFile) -> - Context = rabbit_env:get_context(), - rabbit_prelaunch_conf:generate_config_from_cuttlefish_files( - Context, [ConfFile], AdvancedFile). - -without_rabbit_log(ErlangConfig) -> - case proplists:get_value(rabbit, ErlangConfig) of - undefined -> - ErlangConfig; - RabbitConfig -> - RabbitConfig1 = lists:keydelete(log, 1, RabbitConfig), - case RabbitConfig1 of - [] -> - lists:keydelete(rabbit, 1, ErlangConfig); - _ -> - lists:keystore(rabbit, 1, ErlangConfig, - {rabbit, RabbitConfig1}) - end - end. - -deepsort(List) -> - case is_proplist(List) of - true -> - lists:keysort(1, lists:map(fun({K, V}) -> {K, deepsort(V)}; - (V) -> V end, - List)); - false -> - case is_list(List) of - true -> lists:sort(List); - false -> List - end - end. - -is_proplist([{_Key, _Val}|_] = List) -> lists:all(fun({_K, _V}) -> true; (_) -> false end, List); -is_proplist(_) -> false. diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_ct_helpers.erl b/deps/rabbitmq_ct_helpers/src/rabbit_ct_helpers.erl deleted file mode 100644 index b72f4f244c0b..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_ct_helpers.erl +++ /dev/null @@ -1,1098 +0,0 @@ -%% 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) 2016-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_helpers). - --include_lib("common_test/include/ct.hrl"). - --deprecated({is_mixed_versions,1,"Use is_mixed_versions/0 instead"}). - --export([ - log_environment/0, - run_steps/2, - run_setup_steps/1, run_setup_steps/2, - run_teardown_steps/1, run_teardown_steps/2, - register_teardown_step/2, - register_teardown_steps/2, - guess_tested_erlang_app_name/1, - ensure_application_srcdir/3, - ensure_application_srcdir/4, - ensure_rabbitmqctl_cmd/1, - ensure_rabbitmqctl_app/1, - load_rabbitmqctl_app/1, - ensure_rabbitmq_plugins_cmd/1, - ensure_rabbitmq_queues_cmd/1, - init_skip_as_error_flag/1, - start_long_running_testsuite_monitor/1, - stop_long_running_testsuite_monitor/1, - config_to_testcase_name/2, - testcases/1, - testcase_number/3, - testcase_absname/2, testcase_absname/3, - testcase_started/2, testcase_finished/2, - term_checksum/1, - random_term_checksum/0, - exec/1, exec/2, - make/3, make/4, - get_config/2, get_config/3, set_config/2, delete_config/2, - merge_app_env/2, merge_app_env_in_erlconf/2, - get_app_env/4, - nodename_to_hostname/1, - convert_to_unicode_binary/1, - cover_work_factor/2, - - is_mixed_versions/0, - is_mixed_versions/1, - - await_condition/1, - await_condition/2, - await_condition_with_retries/2, - - eventually/1, eventually/3, - consistently/1, consistently/3 - ]). - --define(SSL_CERT_PASSWORD, "test"). - -%% ------------------------------------------------------------------- -%% Testsuite internal helpers. -%% ------------------------------------------------------------------- - -log_environment() -> - Vars = lists:sort(fun(A, B) -> A =< B end, os:getenv()), - case file:native_name_encoding() of - latin1 -> - ct:pal(?LOW_IMPORTANCE, "Environment variables:~n~s", - [[io_lib:format(" ~s~n", [V]) || V <- Vars]]); - utf8 -> - ct:pal(?LOW_IMPORTANCE, "Environment variables:~n~ts", - [[io_lib:format(" ~ts~n", [V]) || V <- Vars]]) - end. - -run_setup_steps(Config) -> - run_setup_steps(Config, []). - -run_setup_steps(Config, ExtraSteps) -> - Steps = case os:getenv("RABBITMQ_RUN") of - false -> - [ - fun init_skip_as_error_flag/1, - fun guess_tested_erlang_app_name/1, - fun ensure_secondary_umbrella/1, - fun ensure_current_srcdir/1, - fun ensure_rabbitmq_ct_helpers_srcdir/1, - fun ensure_erlang_mk_depsdir/1, - fun ensure_secondary_erlang_mk_depsdir/1, - fun ensure_secondary_current_srcdir/1, - fun ensure_rabbit_common_srcdir/1, - fun ensure_rabbitmq_cli_srcdir/1, - fun ensure_rabbit_srcdir/1, - fun ensure_make_cmd/1, - fun ensure_erl_call_cmd/1, - fun ensure_ssl_certs/1, - fun start_long_running_testsuite_monitor/1, - fun load_elixir/1 - ]; - _ -> - [ - fun init_skip_as_error_flag/1, - fun ensure_secondary_umbrella/1, - fun ensure_current_srcdir/1, - fun ensure_rabbitmq_ct_helpers_srcdir/1, - fun maybe_rabbit_srcdir/1, - fun ensure_make_cmd/1, - fun ensure_rabbitmq_run_cmd/1, - fun ensure_rabbitmq_run_secondary_cmd/1, - fun ensure_ssl_certs/1, - fun start_long_running_testsuite_monitor/1 - ] - end, - run_steps(Config, Steps ++ ExtraSteps). - -run_teardown_steps(Config) -> - run_teardown_steps(Config, []). - -run_teardown_steps(Config, ExtraSteps) -> - RegisteredSteps = get_config(Config, teardown_steps, []), - Steps = [ - fun stop_long_running_testsuite_monitor/1, - fun symlink_priv_dir/1 - ], - run_steps(Config, ExtraSteps ++ RegisteredSteps ++ Steps). - -register_teardown_step(Config, Step) -> - register_teardown_steps(Config, [Step]). - -register_teardown_steps(Config, Steps) -> - RegisteredSteps = get_config(Config, teardown_steps, []), - set_config(Config, {teardown_steps, Steps ++ RegisteredSteps}). - -run_steps(Config, [Step | Rest]) -> - SkipAsError = case get_config(Config, skip_as_error) of - undefined -> false; - Value -> Value - end, - case Step(Config) of - {skip, Reason} when SkipAsError -> - run_teardown_steps(Config), - exit(Reason); - {skip, _} = Error -> - run_teardown_steps(Config), - Error; - Config1 when is_list(Config1) -> - run_steps(Config1, Rest); - Other -> - ct:pal(?LOW_IMPORTANCE, - "~p:~p/~p failed with ~p steps remaining (Config value ~p is not a proplist)", - [?MODULE, ?FUNCTION_NAME, ?FUNCTION_ARITY, length(Rest), Other]), - run_teardown_steps(Config), - exit("A setup step returned a non-proplist") - end; -run_steps(Config, []) -> - Config. - -init_skip_as_error_flag(Config) -> - SkipAsError = case os:getenv("RABBITMQ_CT_SKIP_AS_ERROR") of - false -> false; - Value -> REOpts = [{capture, none}, caseless], - case re:run(Value, "^(1|yes|true)$", REOpts) of - nomatch -> false; - match -> true - end - end, - set_config(Config, {skip_as_error, SkipAsError}). - -guess_tested_erlang_app_name(Config) -> - case os:getenv("DIALYZER_PLT") of - false -> - {skip, - "plt file required, please set DIALYZER_PLT"}; - Filename -> - AppName0 = filename:basename(Filename, ".plt"), - AppName = string:strip(AppName0, left, $.), - set_config(Config, {tested_erlang_app, list_to_atom(AppName)}) - end. - -ensure_secondary_umbrella(Config) -> - Path = case get_config(Config, secondary_umbrella) of - undefined -> os:getenv("SECONDARY_UMBRELLA"); - P -> P - end, - case Path =/= false andalso filelib:is_dir(Path) of - true -> set_config(Config, {secondary_umbrella, Path}); - false -> set_config(Config, {secondary_umbrella, false}) - end. - -ensure_current_srcdir(Config) -> - Path = case get_config(Config, current_srcdir) of - undefined -> os:getenv("PWD"); - P -> P - end, - case filelib:is_dir(Path) of - true -> set_config(Config, {current_srcdir, Path}); - false -> {skip, - "Current source directory required, " ++ - "please set 'current_srcdir' in ct config"} - end. - -ensure_rabbitmq_ct_helpers_srcdir(Config) -> - Path = case get_config(Config, rabbitmq_ct_helpers_srcdir) of - undefined -> - filename:dirname( - filename:dirname( - code:which(?MODULE))); - P -> - P - end, - case filelib:is_dir(Path) of - true -> set_config(Config, {rabbitmq_ct_helpers_srcdir, Path}); - false -> {skip, - "rabbitmq_ct_helpers source directory required, " ++ - "please set 'rabbitmq_ct_helpers_srcdir' in ct config"} - end. - -ensure_erlang_mk_depsdir(Config) -> - Path = case get_config(Config, erlang_mk_depsdir) of - undefined -> - case os:getenv("DEPS_DIR") of - false -> - %% Try the common locations. - SrcDir = ?config(rabbitmq_ct_helpers_srcdir, Config), - Ds = [ - filename:join(SrcDir, "deps"), - filename:join(SrcDir, "../../deps") - ], - case lists:filter(fun filelib:is_dir/1, Ds) of - [P |_] -> P; - [] -> false - end; - P -> - P - end; - P -> - P - end, - case Path =/= false andalso filelib:is_dir(Path) of - true -> set_config(Config, {erlang_mk_depsdir, Path}); - false -> {skip, - "deps directory required, " ++ - "please set DEPS_DIR or 'erlang_mk_depsdir' " ++ - "in ct config"} - end. - -ensure_secondary_erlang_mk_depsdir(Config) -> - Path = case get_config(Config, secondary_erlang_mk_depsdir) of - undefined -> - case ?config(secondary_umbrella, Config) of - false -> ?config(erlang_mk_depsdir, Config); - SecUmbrella -> filename:join(SecUmbrella, "deps") - end; - P -> - P - end, - case filelib:is_dir(Path) of - true -> set_config(Config, {secondary_erlang_mk_depsdir, Path}); - false -> {skip, - "Secondary deps directory required, " ++ - "please set 'secondary_erlang_mk_depsdir' in ct config"} - end. - -ensure_secondary_current_srcdir(Config) -> - Path = case get_config(Config, secondary_current_srcdir) of - undefined -> - case ?config(secondary_umbrella, Config) of - false -> - ?config(current_srcdir, Config); - _ -> - TestedAppName = ?config(tested_erlang_app, Config), - filename:join( - ?config(secondary_erlang_mk_depsdir, Config), - TestedAppName) - end; - P -> - P - end, - case filelib:is_dir(Path) of - true -> set_config(Config, {secondary_current_srcdir, Path}); - false -> {skip, - "Secondary current source directory required, " ++ - "please set 'secondary_current_srcdir' in ct config"} - end. - -ensure_rabbit_common_srcdir(Config) -> - ensure_application_srcdir(Config, rabbit_common, rabbit_misc). - -ensure_rabbitmq_cli_srcdir(Config) -> - ensure_application_srcdir(Config, rabbitmq_cli, elixir, 'Elixir.RabbitMQCtl'). - -ensure_rabbit_srcdir(Config) -> - ensure_application_srcdir(Config, rabbit, rabbit). - -maybe_rabbit_srcdir(Config) -> - % Some tests under bazel use this value, others do not. - % By allowing this config to be optional, we avoid making - % more tests depend on rabbit - case ensure_application_srcdir(Config, rabbit, rabbit) of - {skip, _} -> Config; - Config1 -> Config1 - end. - -ensure_application_srcdir(Config, App, Module) -> - ensure_application_srcdir(Config, App, erlang, Module). - -ensure_application_srcdir(Config, App, Lang, Module) -> - AppS = atom_to_list(App), - Key = list_to_atom(AppS ++ "_srcdir"), - SecondaryKey = list_to_atom("secondary_" ++ AppS ++ "_srcdir"), - Path = case get_config(Config, Key) of - undefined -> - case code:which(Module) of - non_existing -> - filename:join(?config(erlang_mk_depsdir, Config), AppS); - P when Lang =:= erlang -> - %% P is $SRCDIR/ebin/$MODULE.beam. - filename:dirname( - filename:dirname(P)); - P when Lang =:= elixir -> - %% P is $SRCDIR/_build/$MIX_ENV/lib/$APP/ebin/$MODULE.beam. - filename:dirname( - filename:dirname( - filename:dirname( - filename:dirname( - filename:dirname( - filename:dirname(P)))))) - end; - P -> - P - end, - SecondaryPath = case ?config(secondary_umbrella, Config) of - false -> - Path; - _ -> - case get_config(Config, SecondaryKey) of - undefined -> - filename:join( - ?config(secondary_erlang_mk_depsdir, - Config), - AppS); - SP -> - SP - end - end, - case filelib:is_dir(Path) andalso filelib:is_dir(SecondaryPath) of - true -> set_config(Config, - [{Key, Path}, - {SecondaryKey, SecondaryPath}]); - false -> {skip, - AppS ++ " source directory required, " ++ - "please set '" ++ AppS ++ "_srcdir' in ct config"} - end. - -ensure_make_cmd(Config) -> - Make = case get_config(Config, make_cmd) of - undefined -> - case os:getenv("MAKE") of - false -> "make"; - M -> M - end; - M -> - M - end, - Cmd = [Make, "--version"], - case exec(Cmd, [{match_stdout, "GNU Make"}]) of - {ok, _} -> set_config(Config, {make_cmd, Make}); - _ -> {skip, - "GNU Make required, " ++ - "please set MAKE or 'make_cmd' in ct config"} - end. - -ensure_rabbitmq_run_cmd(Config) -> - Path = os:getenv("RABBITMQ_RUN"), - case filelib:is_file(Path) of - true -> set_config(Config, {rabbitmq_run_cmd, Path}); - false -> {skip, - "Bazel helper rabbitmq-run required, " ++ - "please set RABBITMQ_RUN"} - end. - -ensure_rabbitmq_run_secondary_cmd(Config) -> - Path = os:getenv("RABBITMQ_RUN_SECONDARY"), - case filelib:is_file(Path) of - true -> - set_config(Config, {rabbitmq_run_secondary_cmd, Path}); - false -> - Config - end. - -ensure_erl_call_cmd(Config) -> - ErlCallDir = code:lib_dir(erl_interface, bin), - ErlCall = filename:join(ErlCallDir, "erl_call"), - Cmd = [ErlCall], - case exec(Cmd, [{match_stdout, "Usage: "}]) of - {ok, _} -> set_config(Config, {erl_call_cmd, ErlCall}); - _ -> {skip, - "erl_call required, " ++ - "please set ERL_CALL or 'erl_call_cmd' in ct config"} - end. - -ensure_rabbitmqctl_cmd(Config) -> - Rabbitmqctl = case get_config(Config, rabbitmqctl_cmd) of - undefined -> - case os:getenv("RABBITMQCTL") of - false -> - find_script(Config, "rabbitmqctl"); - R -> - ct:pal(?LOW_IMPORTANCE, - "Using rabbitmqctl from RABBITMQCTL: ~p~n", [R]), - R - end; - R -> - ct:pal(?LOW_IMPORTANCE, - "Using rabbitmqctl from rabbitmqctl_cmd: ~p~n", [R]), - R - end, - Error = {skip, "rabbitmqctl required, " ++ - "please set RABBITMQCTL or 'rabbitmqctl_cmd' in ct config"}, - case Rabbitmqctl of - false -> - Error; - _ -> - Cmd = [Rabbitmqctl], - Env = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(Rabbitmqctl)} - ], - case exec(Cmd, [drop_stdout, {env, Env}]) of - {error, 64, _} -> - set_config(Config, {rabbitmqctl_cmd, Rabbitmqctl}); - {error, Code, Reason} -> - ct:pal("Exec failed with exit code ~p: ~p", [Code, Reason]), - Error; - _ -> - Error - end - end. - -find_script(Config, Script) -> - Locations = [File - || File <- [new_script_location(Config, Script), - old_script_location(Config, Script)], - filelib:is_file(File)], - case Locations of - [Location | _] -> - ct:pal(?LOW_IMPORTANCE, "Using ~s at ~p~n", [Script, Location]), - Location; - [] -> - false - end. - -old_script_location(Config, Script) -> - SrcDir = ?config(rabbit_srcdir, Config), - filename:join([SrcDir, "scripts", Script]). - -new_script_location(Config, Script) -> - SrcDir = ?config(current_srcdir, Config), - filename:join([SrcDir, "sbin", Script]). - -ensure_rabbitmqctl_app(Config) -> - SrcDir = ?config(rabbitmq_cli_srcdir, Config), - MixEnv = os:getenv("MIX_ENV", "dev"), - EbinDir = filename:join( - [SrcDir, "_build", MixEnv, "lib", "rabbitmqctl", "ebin"]), - case filelib:is_file(filename:join(EbinDir, "rabbitmqctl.app")) of - true -> - true = code:add_path(EbinDir), - case application:load(rabbitmqctl) of - ok -> - Config; - {error, {already_loaded, rabbitmqctl}} -> - Config; - {error, _} -> - {skip, "Access to rabbitmq_cli ebin dir. required, " ++ - "please build rabbitmq_cli and set MIX_ENV"} - end; - false -> - {skip, "Access to rabbitmq_cli ebin dir. required, " ++ - "please build rabbitmq_cli and set MIX_ENV"} - end. - -load_rabbitmqctl_app(Config) -> - case application:load(rabbitmqctl) of - ok -> - Config; - {error, {already_loaded, rabbitmqctl}} -> - Config; - {error, Reason} -> - ct:pal(?LOW_IMPORTANCE, - "Failed to load rabbitmqctl application: ~p", [Reason]), - {skip, "Application rabbitmqctl could not be loaded, " ++ - "please place compiled rabbitmq_cli on the code path"} - end. - -ensure_rabbitmq_plugins_cmd(Config) -> - Rabbitmqplugins = case get_config(Config, rabbitmq_plugins_cmd) of - undefined -> - case os:getenv("RABBITMQ_PLUGINS") of - false -> find_script(Config, "rabbitmq-plugins"); - R -> R - end; - R -> - R - end, - Error = {skip, "rabbitmq_plugins required, " ++ - "please set RABBITMQ_PLUGINS or 'rabbitmq_plugins_cmd' in ct config"}, - case Rabbitmqplugins of - false -> - Error; - _ -> - Cmd = [Rabbitmqplugins], - Env = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(Rabbitmqplugins)} - ], - case exec(Cmd, [drop_stdout, {env, Env}]) of - {error, 64, _} -> - set_config(Config, {rabbitmq_plugins_cmd, Rabbitmqplugins}); - _ -> - Error - end - end. - -ensure_rabbitmq_queues_cmd(Config) -> - RabbitmqQueues = case get_config(Config, rabbitmq_queues_cmd) of - undefined -> - case os:getenv("RABBITMQ_QUEUES") of - false -> find_script(Config, "rabbitmq-queues"); - R -> R - end; - R -> - ct:pal(?LOW_IMPORTANCE, - "Using rabbitmq-queues from rabbitmq_queues_cmd: ~p~n", [R]), - R - end, - Error = {skip, "rabbitmq-queues required, " ++ - "please set 'rabbitmq_queues_cmd' in ct config"}, - case RabbitmqQueues of - false -> - Error; - _ -> - Cmd = [RabbitmqQueues], - Env = [ - {"RABBITMQ_SCRIPTS_DIR", filename:dirname(RabbitmqQueues)} - ], - case exec(Cmd, [drop_stdout, {env, Env}]) of - {error, 64, _} -> - set_config(Config, - {rabbitmq_queues_cmd, - RabbitmqQueues}); - {error, Code, Reason} -> - ct:pal("Exec failed with exit code ~p: ~p", [Code, Reason]), - Error; - _ -> - Error - end - end. - -ensure_ssl_certs(Config) -> - SrcDir = ?config(rabbitmq_ct_helpers_srcdir, Config), - CertsMakeDir = filename:join([SrcDir, "tools", "tls-certs"]), - PrivDir = ?config(priv_dir, Config), - CertsDir = filename:join(PrivDir, "certs"), - CertsPwd = proplists:get_value(rmq_certspwd, Config, ?SSL_CERT_PASSWORD), - Cmd = [ - "PASSWORD=" ++ CertsPwd, - "DIR=" ++ CertsDir], - case make(Config, CertsMakeDir, Cmd) of - {ok, _} -> - %% Add SSL certs to the broker configuration. - Verify = get_config(Config, rabbitmq_ct_tls_verify, verify_peer), - FailIfNoPeerCert = get_config( - Config, - rabbitmq_ct_tls_fail_if_no_peer_cert, - true) andalso Verify =/= verify_none, - Config1 = merge_app_env(Config, - {rabbit, [ - {ssl_options, [ - {cacertfile, - filename:join([CertsDir, "testca", "cacert.pem"])}, - {certfile, - filename:join([CertsDir, "server", "cert.pem"])}, - {keyfile, - filename:join([CertsDir, "server", "key.pem"])}, - {verify, Verify}, - {fail_if_no_peer_cert, FailIfNoPeerCert} - ]}]}), - set_config(Config1, {rmq_certsdir, CertsDir}); - _ -> - {skip, "Failed to create SSL certificates"} - end. - -link_name(["deps", _ | Tail]) -> - case lists:reverse(Tail) of - ["logs" | Rest] -> - string:join(lists:reverse(["private_log" | Rest]), "."); - _ -> - string:join(Tail, ".") - end; -link_name(X) -> X. - -get_selection_from_tc_logfile(["logs", _, S | _Tail]) -> - {ok, link_name(string:tokens(S, "."))}; -get_selection_from_tc_logfile([_ | Tail]) -> - get_selection_from_tc_logfile(Tail); -get_selection_from_tc_logfile([]) -> not_found. - -get_selection(Config) -> - TcLogFile = ?config(tc_logfile, Config), - get_selection_from_tc_logfile(filename:split(TcLogFile)). - - -symlink_priv_dir(Config) -> - case {os:type(), ?config(rabbitmq_run_cmd, Config)} of - {{win32, _}, _} -> - Config; - {_, Cmd} when Cmd =/= undefined -> - %% skip if bazel - Config; - _ -> - SrcDir = ?config(current_srcdir, Config), - PrivDir = ?config(priv_dir, Config), - case get_selection(Config) of - {ok, Name} -> - Target = filename:join([SrcDir, "logs", Name]), - case exec(["ln", "-snf", PrivDir, Target]) of - {ok, _} -> ok; - _ -> ct:pal(?LOW_IMPORTANCE, - "Failed to symlink private_log directory.") - end, - Config; - not_found -> - ct:pal(?LOW_IMPORTANCE, - "Failed to symlink private_log directory."), - Config - end - end. - -%% ------------------------------------------------------------------- -%% Process to log a message every minute during long testcases. -%% ------------------------------------------------------------------- - --define(PING_CT_INTERVAL, 60 * 1000). %% In milliseconds. - -start_long_running_testsuite_monitor(Config) -> - Pid = spawn( - fun() -> - {ok, TimerRef} = timer:send_interval(?PING_CT_INTERVAL, ping_ct), - long_running_testsuite_monitor(TimerRef, []) - end), - set_config(Config, {long_running_testsuite_monitor, Pid}). - -load_elixir(Config) -> - case find_elixir_home() of - {skip, _} = Skip -> - Skip; - ElixirLibDir -> - ct:pal(?LOW_IMPORTANCE, "Elixir lib dir: ~s~n", [ElixirLibDir]), - true = code:add_pathz(ElixirLibDir), - application:load(elixir), - {ok, _} = application:ensure_all_started(elixir), - Config - end. - -find_elixir_home() -> - ElixirExe = case os:type() of - {unix, _} -> "elixir"; - {win32, _} -> "elixir.bat" - end, - case os:find_executable(ElixirExe) of - false -> {skip, "Failed to locate Elixir executable"}; - ExePath -> - {ok, ElixirLibDir} = exec([ExePath, "--eval", "IO.write(:code.lib_dir(:elixir, :ebin))"], []), - ElixirLibDir - end. - -stop_long_running_testsuite_monitor(Config) -> - case get_config(Config, long_running_testsuite_monitor) of - undefined -> ok; - Pid -> Pid ! stop - end, - Config. - -long_running_testsuite_monitor(TimerRef, Testcases) -> - receive - {started, Testcase} -> - Testcases1 = [{Testcase, erlang:monotonic_time(seconds)} - | Testcases], - long_running_testsuite_monitor(TimerRef, Testcases1); - {finished, Testcase} -> - Testcases1 = proplists:delete(Testcase, Testcases), - long_running_testsuite_monitor(TimerRef, Testcases1); - ping_ct -> - T1 = erlang:monotonic_time(seconds), - ct:pal(?STD_IMPORTANCE, "Testcases still in progress:~s", - [[ - begin - TDiff = format_time_diff(T1, T0), - rabbit_misc:format("~n - ~s (~s)", [TC, TDiff]) - end - || {TC, T0} <- Testcases - ]]), - long_running_testsuite_monitor(TimerRef, Testcases); - stop -> - timer:cancel(TimerRef) - end. - -format_time_diff(T1, T0) -> - Diff = T1 - T0, - Hours = Diff div 3600, - Diff1 = Diff rem 3600, - Minutes = Diff1 div 60, - Seconds = Diff1 rem 60, - rabbit_misc:format("~b:~2..0b:~2..0b", [Hours, Minutes, Seconds]). - -testcase_started(Config, Testcase) -> - Testcase1 = config_to_testcase_name(Config, Testcase), - ?config(long_running_testsuite_monitor, Config) ! {started, Testcase1}, - Config. - -testcase_finished(Config, Testcase) -> - Testcase1 = config_to_testcase_name(Config, Testcase), - ?config(long_running_testsuite_monitor, Config) ! {finished, Testcase1}, - Config. - -config_to_testcase_name(Config, Testcase) -> - testcase_absname(Config, Testcase). - -testcase_absname(Config, Testcase) -> - testcase_absname(Config, Testcase, "/"). - -testcase_absname(Config, Testcase, Sep) -> - Name = rabbit_misc:format("~s", [Testcase]), - case get_config(Config, tc_group_properties) of - [] -> - Name; - Props -> - Name1 = case Name of - "" -> - rabbit_misc:format("~s", - [proplists:get_value(name, Props)]); - _ -> - rabbit_misc:format("~s~s~s", - [proplists:get_value(name, Props), Sep, Name]) - end, - testcase_absname1(Name1, - get_config(Config, tc_group_path), Sep) - end. - -testcase_absname1(Name, [Props | Rest], Sep) -> - Name1 = rabbit_misc:format("~s~s~s", - [proplists:get_value(name, Props), Sep, Name]), - testcase_absname1(Name1, Rest, Sep); -testcase_absname1(Name, [], _) -> - lists:flatten(Name). - -testcases(Testsuite) -> - All = Testsuite:all(), - testcases1(Testsuite, All, [], []). - -testcases1(Testsuite, [{group, GroupName} | Rest], CurrentPath, Testcases) -> - Group = {GroupName, _, _} = lists:keyfind(GroupName, 1, Testsuite:groups()), - testcases1(Testsuite, [Group | Rest], CurrentPath, Testcases); -testcases1(Testsuite, [{GroupName, _, Children} | Rest], - CurrentPath, Testcases) -> - Testcases1 = testcases1(Testsuite, Children, - [[{name, GroupName}] | CurrentPath], Testcases), - testcases1(Testsuite, Rest, CurrentPath, Testcases1); -testcases1(Testsuite, [Testcase | Rest], CurrentPath, Testcases) -when is_atom(Testcase) -> - {Props, Path} = case CurrentPath of - [] -> {[], []}; - [H | T] -> {H, T} - end, - Name = config_to_testcase_name([ - {tc_group_properties, Props}, - {tc_group_path, Path} - ], Testcase), - testcases1(Testsuite, Rest, CurrentPath, [Name | Testcases]); -testcases1(_, [], [], Testcases) -> - lists:reverse(Testcases); -testcases1(_, [], _, Testcases) -> - Testcases. - -testcase_number(Config, TestSuite, TestName) -> - Testcase = config_to_testcase_name(Config, TestName), - Testcases = testcases(TestSuite), - testcase_number1(Testcases, Testcase, 0). - -testcase_number1([Testcase | _], Testcase, N) -> - N; -testcase_number1([_ | Rest], Testcase, N) -> - testcase_number1(Rest, Testcase, N + 1); -testcase_number1([], _, N) -> - N. - -%% ------------------------------------------------------------------- -%% Helpers for helpers. -%% ------------------------------------------------------------------- - -term_checksum(Term) -> - Bin = term_to_binary(Term), - <> = erlang:md5(Bin), - rabbit_misc:format("~32.16.0b", [Checksum]). - -random_term_checksum() -> - term_checksum(rabbit_misc:random(1000000)). - -exec(Cmd) -> - exec(Cmd, []). - -exec([Cmd | Args], Options) when is_list(Cmd) orelse is_binary(Cmd) -> - Cmd0 = case (lists:member($/, Cmd) orelse lists:member($\\, Cmd)) of - true -> - Cmd; - false -> - case os:find_executable(Cmd) of - false -> Cmd; - Path -> Path - end - end, - Cmd1 = convert_to_unicode_binary( - string:trim( - rabbit_data_coercion:to_list(Cmd0))), - Args1 = [convert_to_unicode_binary(format_arg(Arg)) || Arg <- Args], - {LocalOptions, PortOptions} = lists:partition( - fun - ({match_stdout, _}) -> true; - ({timeout, _}) -> true; - (drop_stdout) -> true; - (_) -> false - end, Options), - PortOptions1 = case lists:member(nouse_stdio, PortOptions) of - true -> PortOptions; - false -> [use_stdio, stderr_to_stdout | PortOptions] - end, - Log = "+ ~s (pid ~p)", - ExportedEnvVars = ["ERL_INETRC"], - ExportedEnv = lists:foldl( - fun(Var, Env) -> - case os:getenv(Var) of - false -> Env; - Value -> [{Var, Value} | Env] - end - end, [], ExportedEnvVars), - {PortOptions2, Log1} = case proplists:get_value(env, PortOptions1) of - undefined -> - {[{env, ExportedEnv} | PortOptions1], Log}; - Env -> - Env1 = [ - begin - Key1 = format_arg(Key), - Value1 = format_arg(Value), - Value2 = case is_binary(Value1) of - true -> binary_to_list(Value1); - false -> Value1 - end, - {Key1, Value2} - end - || {Key, Value} <- Env - ], - { - [{env, Env1 ++ ExportedEnv} - | proplists:delete(env, PortOptions1)], - Log ++ "~n~nEnvironment variables:~n" ++ - string:join( - [rabbit_misc:format(" ~s=~s", [K, V]) || {K, V} <- Env1], - "~n") - } - end, - %% Because Args1 may contain binaries, we don't use string:join(). - %% Instead we do a list comprehension. - ArgsIoList = [Cmd1, [[$\s, Arg] || Arg <- Args1]], - ct:pal(?LOW_IMPORTANCE, Log1, [ArgsIoList, self()]), - try - Port = erlang:open_port( - {spawn_executable, Cmd1}, [ - {args, Args1}, - exit_status - | PortOptions2]), - - case lists:keytake(timeout, 1, LocalOptions) of - false -> - port_receive_loop(Port, "", LocalOptions, infinity); - {value, {timeout, infinity}, LocalOptions1} -> - port_receive_loop(Port, "", LocalOptions1, infinity); - {value, {timeout, Timeout}, LocalOptions1} -> - Until = erlang:system_time(millisecond) + Timeout, - port_receive_loop(Port, "", LocalOptions1, Until) - end - catch - error:Reason -> - ct:pal(?LOW_IMPORTANCE, "~s: ~s", - [Cmd1, file:format_error(Reason)]), - {error, Reason, file:format_error(Reason)} - end. - -format_arg({Format, FormatArgs}) -> - rabbit_misc:format(Format, FormatArgs); -format_arg(Arg) when is_atom(Arg) -> - atom_to_list(Arg); -format_arg(Arg) -> - Arg. - -port_receive_loop(Port, Stdout, Options, Until) -> - port_receive_loop(Port, Stdout, Options, Until, stdout_dump_timer()). - -port_receive_loop(Port, Stdout, Options, Until, DumpTimer) -> - Timeout = case Until of - infinity -> infinity; - _ -> max(0, Until - erlang:system_time(millisecond)) - end, - receive - {Port, {exit_status, X}} -> - timer:cancel(DumpTimer), - DropStdout = lists:member(drop_stdout, Options) orelse - Stdout =:= "", - if - DropStdout -> - ct:pal(?LOW_IMPORTANCE, "Exit code: ~p (pid ~p)", - [X, self()]); - true -> - ct:pal(?LOW_IMPORTANCE, "~ts~nExit code: ~p (pid ~p)", - [Stdout, X, self()]) - end, - case proplists:get_value(match_stdout, Options) of - undefined -> - case X of - 0 -> {ok, Stdout}; - _ -> {error, X, Stdout} - end; - RE -> - case re:run(Stdout, RE, [{capture, none}]) of - match -> {ok, Stdout}; - nomatch -> {error, X, Stdout} - end - end; - dump_output -> - DropStdout = lists:member(drop_stdout, Options) orelse - Stdout =:= "", - if - DropStdout -> - ok; - true -> - ct:pal(?LOW_IMPORTANCE, "~ts~n[Command still in progress] (pid ~p)", - [Stdout, self()]) - end, - port_receive_loop(Port, Stdout, Options, Until, stdout_dump_timer()); - {Port, {data, Out}} -> - port_receive_loop(Port, Stdout ++ Out, Options, Until, DumpTimer) - after - Timeout -> - {error, timeout, Stdout} - end. - -stdout_dump_timer() -> - {ok, TRef} = timer:send_after(30000, dump_output), - TRef. - -make(Config, Dir, Args) -> - make(Config, Dir, Args, []). - -make(Config, Dir, Args, Options) -> - Make = rabbit_ct_vm_helpers:get_current_vm_config(Config, make_cmd), - Verbosity = case os:getenv("V") of - false -> []; - V -> ["V=" ++ V] - end, - Cmd = [Make, "-C", Dir] ++ Verbosity ++ Args, - exec(Cmd, Options). - -%% This is the same as ?config(), except this one doesn't log a warning -%% if the key is missing. -get_config(Config, Key) -> - proplists:get_value(Key, Config). - -get_config(Config, Key, Default) -> - proplists:get_value(Key, Config, Default). - -set_config(Config, Tuple) when is_tuple(Tuple) -> - Key = element(1, Tuple), - lists:keystore(Key, 1, Config, Tuple); -set_config(Config, [Tuple | Rest]) -> - Config1 = set_config(Config, Tuple), - set_config(Config1, Rest); -set_config(Config, []) -> - Config. - -delete_config(Config, Key) -> - proplists:delete(Key, Config). - -get_app_env(Config, App, Key, Default) -> - ErlangConfig = proplists:get_value(erlang_node_config, Config, []), - AppConfig = proplists:get_value(App, ErlangConfig, []), - proplists:get_value(Key, AppConfig, Default). - -merge_app_env(Config, Env) -> - ErlangConfig = proplists:get_value(erlang_node_config, Config, []), - ErlangConfig1 = merge_app_env_in_erlconf(ErlangConfig, Env), - set_config(Config, {erlang_node_config, ErlangConfig1}). - -merge_app_env_in_erlconf(ErlangConfig, {App, Env}) -> - AppConfig = proplists:get_value(App, ErlangConfig, []), - AppConfig1 = lists:foldl( - fun({Key, _} = Tuple, AC) -> - lists:keystore(Key, 1, AC, Tuple) - end, AppConfig, Env), - lists:keystore(App, 1, ErlangConfig, {App, AppConfig1}); -merge_app_env_in_erlconf(ErlangConfig, [Env | Rest]) -> - ErlangConfig1 = merge_app_env_in_erlconf(ErlangConfig, Env), - merge_app_env_in_erlconf(ErlangConfig1, Rest); -merge_app_env_in_erlconf(ErlangConfig, []) -> - ErlangConfig. - -nodename_to_hostname(Nodename) when is_atom(Nodename) -> - [_, Hostname] = string:tokens(atom_to_list(Nodename), "@"), - Hostname. - -convert_to_unicode_binary(Arg) when is_list(Arg) -> - unicode:characters_to_binary(Arg); -convert_to_unicode_binary(Arg) when is_binary(Arg) -> - Arg. - -is_mixed_versions() -> - os:getenv("SECONDARY_UMBRELLA") =/= false - orelse os:getenv("RABBITMQ_RUN_SECONDARY") =/= false. - -is_mixed_versions(Config) -> - get_config(Config, secondary_umbrella, false) =/= false - orelse get_config(Config, rabbitmq_run_secondary_cmd, false) =/= false. - -%% ------------------------------------------------------------------- -%% Assertions that retry -%% ------------------------------------------------------------------- - -await_condition(ConditionFun) -> - await_condition(ConditionFun, 10_000). - -await_condition(ConditionFun, Timeout) -> - Retries = ceil(Timeout / 50), - await_condition_with_retries(ConditionFun, Retries). - -await_condition_with_retries(_ConditionFun, 0) -> - ct:fail("Condition did not materialize in the expected period of time"); -await_condition_with_retries(ConditionFun, RetriesLeft) -> - case ConditionFun() of - false -> - timer:sleep(50), - await_condition_with_retries(ConditionFun, RetriesLeft - 1); - true -> - ok - end. - -%% Pass in any EUnit test object. Example: -%% eventually(?_assertEqual(1, Actual)) -eventually({Line, Assertion} = TestObj) - when is_integer(Line), Line >= 0, is_function(Assertion, 0) -> - eventually(TestObj, 200, 5). - -eventually({Line, _}, _, 0) -> - erlang:error({assert_timeout_line, Line}); -eventually({Line, Assertion} = TestObj, PollInterval, PollCount) - when is_integer(Line), Line >= 0, is_function(Assertion, 0), - is_integer(PollInterval), PollInterval >= 0, - is_integer(PollCount), PollCount >= 0 -> - case catch Assertion() of - ok -> - ok; - Err -> - ct:pal(?LOW_IMPORTANCE, - "Retrying in ~bms for ~b more times due to failed assertion in line ~b: ~p", - [PollInterval, PollCount - 1, Line, Err]), - timer:sleep(PollInterval), - eventually(TestObj, PollInterval, PollCount - 1) - end. - -%% Pass in any EUnit test object. Example: -%% consistently(?_assertEqual(1, Actual)) -consistently({Line, Assertion} = TestObj) - when is_integer(Line), Line >= 0, is_function(Assertion, 0) -> - consistently(TestObj, 200, 5). - -consistently(_, _, 0) -> - ok; -consistently({Line, Assertion} = TestObj, PollInterval, PollCount) - when is_integer(Line), Line >= 0, is_function(Assertion, 0), - is_integer(PollInterval), PollInterval >= 0, - is_integer(PollCount), PollCount >= 0 -> - Assertion(), - timer:sleep(PollInterval), - consistently(TestObj, PollInterval, PollCount - 1). - -%% ------------------------------------------------------------------- -%% Cover-related functions. -%% ------------------------------------------------------------------- - -%% TODO. -cover_work_factor(_Config, Without) -> - Without. diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_ct_proper_helpers.erl b/deps/rabbitmq_ct_helpers/src/rabbit_ct_proper_helpers.erl deleted file mode 100644 index aed1eff84aed..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_ct_proper_helpers.erl +++ /dev/null @@ -1,21 +0,0 @@ -%% 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) 2016-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_proper_helpers). - --include_lib("common_test/include/ct.hrl"). --include_lib("proper/include/proper.hrl"). --include_lib("eunit/include/eunit.hrl"). - --export([run_proper/3]). - -run_proper(Fun, Args, NumTests) -> - ?assert( - proper:counterexample(erlang:apply(Fun, Args), - [{numtests, NumTests}, - {on_output, fun(".", _) -> ok; % don't print the '.'s on new lines - (F, A) -> ct:pal(?LOW_IMPORTANCE, F, A) end}])). diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_ct_vm_helpers.erl b/deps/rabbitmq_ct_helpers/src/rabbit_ct_vm_helpers.erl deleted file mode 100644 index d6ac3855f15a..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_ct_vm_helpers.erl +++ /dev/null @@ -1,1140 +0,0 @@ -%% 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) 2018-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_ct_vm_helpers). - --include_lib("common_test/include/ct.hrl"). - --export([setup_steps/0, - teardown_steps/0, - - get_ct_peers/1, - get_ct_peer/2, - get_ct_peer_configs/2, - get_ct_peer_config/2, get_ct_peer_config/3, - get_current_vm_config/2, - rpc/4, rpc/5, - rpc_all/3, rpc_all/4, - - ensure_terraform_cmd/1, - determine_erlang_version/1, - determine_erlang_git_ref/1, - determine_elixir_version/1, - compute_code_path/1, - find_terraform_ssh_key/1, - set_terraform_files_suffix/1, - set_terraform_config_dirs/1, - set_terraform_state/1, - set_terraform_aws_ec2_region/1, - init_terraform/1, - compute_vpc_cidr_block/1, - find_erlang_mk/1, - find_rabbitmq_components/1, - list_dirs_to_upload/1, - list_dirs_to_download/1, - maybe_prepare_dirs_to_upload_archive/1, - spawn_terraform_vms/1, destroy_terraform_vms/1, - query_terraform_uuid/1, - query_ct_peer_nodenames_and_ipaddrs/1, - set_inet_hosts/1, - write_inetrc/1, - wait_for_ct_peers/1, - set_ct_peers_code_path/1, - start_ct_logs_proxies/1, - configure_ct_peers_environment/1, - download_dirs/1, - stop_ct_peers/1, - - aws_direct_vms_module/1, - aws_autoscaling_group_module/1, - vms_query_module/1, - - do_setup_proxy/2, proxy_loop/1, - prepare_dirs_to_download_archives/1 - ]). - --define(UPLOAD_DIRS_ARCHIVE_PREFIX, "dirs-archive-"). --define(ERLANG_REMOTE_NODENAME, "control"). - -setup_steps() -> - [ - fun ensure_terraform_cmd/1, - fun determine_erlang_version/1, - fun determine_erlang_git_ref/1, - fun determine_elixir_version/1, - fun compute_code_path/1, - fun find_terraform_ssh_key/1, - fun set_terraform_files_suffix/1, - fun set_terraform_config_dirs/1, - fun set_terraform_state/1, - fun set_terraform_aws_ec2_region/1, - fun init_terraform/1, - fun compute_vpc_cidr_block/1, - fun find_erlang_mk/1, - fun find_rabbitmq_components/1, - fun list_dirs_to_upload/1, - fun list_dirs_to_download/1, - fun maybe_prepare_dirs_to_upload_archive/1, - fun spawn_terraform_vms/1, - fun query_terraform_uuid/1, - fun query_ct_peer_nodenames_and_ipaddrs/1, - fun set_inet_hosts/1, - fun write_inetrc/1, - fun wait_for_ct_peers/1, - fun set_ct_peers_code_path/1, - fun start_ct_logs_proxies/1, - fun configure_ct_peers_environment/1 - ]. - -teardown_steps() -> - [ - fun download_dirs/1, - fun stop_ct_peers/1, - fun destroy_terraform_vms/1 - ]. - -ensure_terraform_cmd(Config) -> - Terraform = case rabbit_ct_helpers:get_config(Config, terraform_cmd) of - undefined -> - case os:getenv("TERRAFORM") of - false -> "terraform"; - T -> T - end; - T -> - T - end, - Cmd = [Terraform, "--version"], - case rabbit_ct_helpers:exec(Cmd, [{match_stdout, "Terraform"}]) of - {ok, _} -> - rabbit_ct_helpers:set_config(Config, {terraform_cmd, Terraform}); - _ -> - {skip, "terraform(1) required, " ++ - "please set TERRAFORM or 'terraform_cmd' in ct config"} - end. - -determine_erlang_version(Config) -> - Version = case rabbit_ct_helpers:get_config(Config, erlang_version) of - undefined -> - case os:getenv("ERLANG_VERSION") of - false -> rabbit_misc:otp_release(); - V -> V - end; - V -> - V - end, - Regex = "([0-9]+\.[0-9]+|R[0-9]+(?:[AB])[0-9]+).*", - ErlangVersion = re:replace(Version, Regex, "\\1"), - ct:pal(?LOW_IMPORTANCE, "Erlang version: ~s", [ErlangVersion]), - rabbit_ct_helpers:set_config( - Config, {erlang_version, ErlangVersion}). - -determine_erlang_git_ref(Config) -> - GitRef = case rabbit_ct_helpers:get_config(Config, erlang_git_ref) of - undefined -> - case os:getenv("ERLANG_GIT_REF") of - false -> - Version = erlang:system_info(system_version), - ReOpts = [{capture, all_but_first, list}], - Match = re:run(Version, - "source-([0-9a-fA-F]+)", - ReOpts), - case Match of - {match, [V]} -> V; - _ -> "" - end; - V -> - V - end; - V -> - V - end, - ct:pal(?LOW_IMPORTANCE, "Erlang Git reference: ~s", [GitRef]), - rabbit_ct_helpers:set_config( - Config, {erlang_git_ref, GitRef}). - -determine_elixir_version(Config) -> - Version = case rabbit_ct_helpers:get_config(Config, elixir_version) of - undefined -> - case os:getenv("ELIXIR_VERSION") of - false -> - Cmd = ["elixir", "-e", "IO.puts System.version"], - case rabbit_ct_helpers:exec(Cmd) of - {ok, Output} -> - string:strip(Output, right, $\n); - _ -> - "" - end; - V -> - V - end; - V -> - V - end, - ct:pal(?LOW_IMPORTANCE, "Elixir version: ~s", [Version]), - rabbit_ct_helpers:set_config(Config, {elixir_version, Version}). - -compute_code_path(Config) -> - EntireCodePath = code:get_path(), - CodePath = filter_out_erlang_code_path(EntireCodePath), - ct:pal(?LOW_IMPORTANCE, "Code path: ~p", [CodePath]), - rabbit_ct_helpers:set_config(Config, {erlang_code_path, CodePath}). - -filter_out_erlang_code_path(CodePath) -> - ErlangRoot = code:root_dir(), - ErlangRootLen = string:len(ErlangRoot), - lists:filter( - fun(Dir) -> - Dir =/= "." andalso - string:substr(Dir, 1, ErlangRootLen) =/= ErlangRoot - end, CodePath). - -find_terraform_ssh_key(Config) -> - Config1 = - case rabbit_ct_helpers:get_config(Config, terraform_ssh_key) of - undefined -> - case os:getenv("SSH_KEY") of - false -> - HomeDir = os:getenv("HOME"), - Glob = filename:join([HomeDir, ".ssh", "*terraform*"]), - Filenames = lists:sort(filelib:wildcard(Glob)), - PrivKeys = lists:filter( - fun(Filename) -> - filename:extension(Filename) =:= "" - andalso - test_ssh_key(Filename) - end, Filenames), - case PrivKeys of - [PrivKey | _] -> - rabbit_ct_helpers:set_config( - Config, {terraform_ssh_key, PrivKey}); - _ -> - Config - end; - PrivKey -> - case test_ssh_key(PrivKey) of - true -> - rabbit_ct_helpers:set_config( - Config, {terraform_ssh_key, PrivKey}); - false -> - Config - end - end; - PrivKey -> - case test_ssh_key(PrivKey) of - true -> - rabbit_ct_helpers:delete_config( - Config, terraform_ssh_key); - false -> - Config - end - end, - case rabbit_ct_helpers:get_config(Config1, terraform_ssh_key) of - undefined -> - {skip, "Private SSH key required, " ++ - "please set SSH_KEY or terraform_ssh_key in ct config"}; - _ -> - Config1 - end. - -test_ssh_key(PrivKey) -> - filelib:is_regular(PrivKey) - andalso - filelib:is_regular(PrivKey ++ ".pub"). - -set_terraform_files_suffix(Config) -> - case rabbit_ct_helpers:get_config(Config, terraform_files_suffix) of - undefined -> - Suffix = rabbit_ct_helpers:random_term_checksum(), - rabbit_ct_helpers:set_config( - Config, {terraform_files_suffix, Suffix}); - _ -> - Config - end. - -aws_direct_vms_module(Config) -> - SrcDir = ?config(rabbitmq_ct_helpers_srcdir, Config), - filename:join([SrcDir, "tools", "terraform", "direct-vms"]). - -aws_autoscaling_group_module(Config) -> - SrcDir = ?config(rabbitmq_ct_helpers_srcdir, Config), - filename:join([SrcDir, "tools", "terraform", "autoscaling-group"]). - -vms_query_module(Config) -> - SrcDir = ?config(rabbitmq_ct_helpers_srcdir, Config), - filename:join([SrcDir, "tools", "terraform", "vms-query"]). - -set_terraform_config_dirs(Config) -> - SpawnTfConfigDir = aws_direct_vms_module(Config), - PollTfConfigDir = vms_query_module(Config), - Config1 = rabbit_ct_helpers:set_config( - Config, {terraform_poll_config_dir, PollTfConfigDir}), - SpawnTfConfigDir0 = rabbit_ct_helpers:get_config( - Config, terraform_config_dir), - case SpawnTfConfigDir0 of - undefined -> - rabbit_ct_helpers:set_config( - Config1, {terraform_config_dir, SpawnTfConfigDir}); - _ -> - Config1 - end. - -set_terraform_state(Config) -> - PrivDir = ?config(priv_dir, Config), - Suffix = ?config(terraform_files_suffix, Config), - SpawnDataDir = rabbit_misc:format(".terraform-~s", [Suffix]), - SpawnStateFilename = rabbit_misc:format("terraform-~s.tfstate", - [Suffix]), - PollDataDir = rabbit_misc:format(".terraform-query-~s", [Suffix]), - PollStateFilename = rabbit_misc:format("terraform-query-~s.tfstate", - [Suffix]), - SpawnTfState = filename:join(PrivDir, SpawnStateFilename), - PollTfState = filename:join(PrivDir, PollStateFilename), - ct:pal(?LOW_IMPORTANCE, "Terraform state: ~s", [SpawnTfState]), - rabbit_ct_helpers:set_config( - Config, [{terraform_state, SpawnTfState}, - {terraform_data_dir, SpawnDataDir}, - {terraform_poll_state, PollTfState}, - {terraform_poll_data_dir, PollDataDir}]). - -set_terraform_aws_ec2_region(Config) -> - case rabbit_ct_helpers:get_config(Config, terraform_aws_ec2_region) of - undefined -> - EC2Region = "eu-west-1", - rabbit_ct_helpers:set_config( - Config, {terraform_aws_ec2_region, EC2Region}); - _ -> - Config - end. - -init_terraform(Config) -> - SpawnDataDir = ?config(terraform_data_dir, Config), - SpawnTfConfigDir = ?config(terraform_config_dir, Config), - PollDataDir = ?config(terraform_poll_data_dir, Config), - PollTfConfigDir = ?config(terraform_poll_config_dir, Config), - init_terraform_dirs(Config, [{SpawnTfConfigDir, SpawnDataDir}, - {PollTfConfigDir, PollDataDir}]). - -init_terraform_dirs(Config, [{ConfigDir, DataDir} | Rest]) -> - Terraform = ?config(terraform_cmd, Config), - Env = [ - {"TF_DATA_DIR", DataDir} - ], - Cmd = [ - Terraform, - "init", - ConfigDir - ], - case rabbit_ct_helpers:exec(Cmd, [{env, Env}]) of - {ok, _} -> init_terraform_dirs(Config, Rest); - _ -> {skip, "Failed to init Terraform"} - end; -init_terraform_dirs(Config, []) -> - Config. - -compute_vpc_cidr_block(Config) -> - LockId = {compute_vpc_cidr_block, self()}, - LockNodes = [node()], - global:set_lock(LockId, LockNodes), - Seq = case os:getenv("NEXT_VPC_CIDR_BLOCK_SEQ") of - false -> 1; - V -> erlang:list_to_integer(V) - end, - os:putenv("NEXT_VPC_CIDR_BLOCK_SEQ", integer_to_list(Seq + 1)), - global:del_lock(LockId, LockNodes), - CidrBlock = rabbit_misc:format("10.~b.0.0/16", [Seq]), - rabbit_ct_helpers:set_config(Config, {terraform_vpc_cidr_block, CidrBlock}). - -find_in_srcdir_or_grandparent(Config, Name, ConfigKey) when is_atom(ConfigKey) -> - SrcDir = ?config(current_srcdir, Config), - SrcDirChild = filename:join([SrcDir, Name]), - SrcDirAncestor = filename:join([SrcDir, "..", "..", Name]), - case {filelib:is_regular(SrcDirChild), filelib:is_regular(SrcDirAncestor)} of - {true, _} -> rabbit_ct_helpers:set_config(Config, {ConfigKey, SrcDirChild}); - {false, true} -> rabbit_ct_helpers:set_config(Config, {ConfigKey, SrcDirAncestor}); - _ -> {skip, "Failed to find " ++ Name} - end. - -find_erlang_mk(Config) -> - find_in_srcdir_or_grandparent(Config, "erlang.mk", erlang_mk_path). - -find_rabbitmq_components(Config) -> - find_in_srcdir_or_grandparent(Config, "rabbitmq-components.mk", rabbitmq_components_path). - -list_dirs_to_upload(Config) -> - SrcDir = ?config(current_srcdir, Config), - LockId = {make_list_test_deps, self()}, - LockNodes = [node()], - % `make list-test-deps` writes to a central file, a file we read - % later. Therefore we protect that write+read with a lock. - global:set_lock(LockId, LockNodes), - Ret = rabbit_ct_helpers:make(Config, SrcDir, ["list-test-deps"]), - case Ret of - {ok, _} -> - ListFile = filename:join([SrcDir, - ".erlang.mk", - "recursive-test-deps-list.log"]), - {ok, Content} = file:read_file(ListFile), - global:del_lock(LockId, LockNodes), - DepsDirs0 = string:tokens(binary_to_list(Content), "\n"), - DepsDirs = filter_out_subdirs(SrcDir, DepsDirs0), - ErlangMkPath = ?config(erlang_mk_path, Config), - RabbitmqComponentsPath = ?config(rabbitmq_components_path, Config), - AllDirs = lists:sort( - [SrcDir, ErlangMkPath, RabbitmqComponentsPath] ++ DepsDirs - ), - ct:pal(?LOW_IMPORTANCE, "Directories to upload: ~p", [AllDirs]), - rabbit_ct_helpers:set_config(Config, {dirs_to_upload, AllDirs}); - _ -> - global:del_lock(LockId, LockNodes), - {skip, "Failed to get the list of test dependencies"} - end. - -list_dirs_to_download(Config) -> - PrivDir = ?config(priv_dir, Config), - PrivDirParent = filename:dirname(string:strip(PrivDir, right, $/)), - Dirs1 = case rabbit_ct_helpers:get_config(Config, dirs_to_download) of - undefined -> [PrivDirParent]; - Dirs0 -> [PrivDirParent - | filter_out_subdirs(PrivDirParent, Dirs0)] - end, - Dirs = lists:sort(Dirs1), - ct:pal(?LOW_IMPORTANCE, "Directories to download: ~p", [Dirs]), - rabbit_ct_helpers:set_config(Config, {dirs_to_download, Dirs}). - -filter_out_subdirs(RootDir, Dirs) -> - RootDirLen = length(RootDir), - lists:filter( - fun(Dir) -> - Dir =/= RootDir andalso - string:sub_string(Dir, 1, RootDirLen + 1) - =/= - RootDir ++ "/" - end, Dirs). - -maybe_prepare_dirs_to_upload_archive(Config) -> - PrivDir = ?config(priv_dir, Config), - Dirs = lists:sort(?config(dirs_to_upload, Config)), - Checksum = rabbit_ct_helpers:term_checksum(Dirs), - Archive = filename:join( - PrivDir, - rabbit_misc:format( - ?UPLOAD_DIRS_ARCHIVE_PREFIX "~s.tar.xz", [Checksum])), - Config1 = rabbit_ct_helpers:set_config( - Config, {upload_dirs_archive, Archive}), - LockId = {{dirs_to_upload, Archive}, self()}, - LockNodes = [node()], - % The upload dirs archive is unique per set of directories. - % Therefore it can be shared by multiple setups. We want to create - % the archive once and certainly don't want to create it multiple - % times in parallel. Thus the lock. - global:set_lock(LockId, LockNodes), - case filelib:is_regular(Archive) of - true -> - global:del_lock(LockId, LockNodes), - Config1; - false -> - Config2 = prepare_dirs_to_upload_archive(Config1, Archive, Dirs), - global:del_lock(LockId, LockNodes), - Config2 - end. - -prepare_dirs_to_upload_archive(Config, Archive, Dirs) -> - DirsList = string:join( - [rabbit_misc:format("~p", [Dir]) - || Dir <- Dirs, - filelib:is_dir(Dir) orelse filelib:is_regular(Dir)], - " "), - Cmd = rabbit_misc:format( - "tar cf - -P" - " --exclude '.terraform*'" - " --exclude '" ?UPLOAD_DIRS_ARCHIVE_PREFIX "*'" - " --exclude '" ?ERLANG_REMOTE_NODENAME "@*'" - " ~s" - " | xz --threads=0 > ~p", - [DirsList, Archive]), - ct:pal( - ?LOW_IMPORTANCE, - "Creating upload dirs archive `~s`:~n ~s", - [filename:basename(Archive), Cmd]), - case os:cmd(Cmd) of - "" -> - Config; - Output -> - ct:pal( - ?LOW_IMPORTANCE, - "Failed to create upload dirs archive:~n~s", - [Output]), - {skip, "Failed to create upload dirs archive"} - end. - -spawn_terraform_vms(Config) -> - TfConfigDir = ?config(terraform_config_dir, Config), - TfDataDir = ?config(terraform_data_dir, Config), - TfState = ?config(terraform_state, Config), - TfVarFlags = terraform_var_flags(Config), - Terraform = ?config(terraform_cmd, Config), - Env = [ - {"TF_DATA_DIR", TfDataDir} - ], - Cmd = [ - Terraform, - "apply", - "-auto-approve=true", - {"-state=~s", [TfState]} - ] ++ TfVarFlags ++ [ - TfConfigDir - ], - case rabbit_ct_helpers:exec(Cmd, [{env, Env}]) of - {ok, _} -> - Config1 = rabbit_ct_helpers:set_config( - Config, {terraform_query_mode, direct}), - % FIXME: This `register_teardown_steps()` function is just - % wrong currently: when run_steps() is used at the end of - % e.g. a testcase to run testcase-specific teardown steps, - % the registered steps are not executed. - rabbit_ct_helpers:register_teardown_steps( - Config1, teardown_steps()); - _ -> - destroy_terraform_vms(Config), - {skip, "Terraform failed to spawn VM"} - end. - -destroy_terraform_vms(Config) -> - TfConfigDir = ?config(terraform_config_dir, Config), - TfDataDir = ?config(terraform_data_dir, Config), - TfState = ?config(terraform_state, Config), - TfVarFlags = terraform_var_flags(Config), - Terraform = ?config(terraform_cmd, Config), - Env = [ - {"TF_DATA_DIR", TfDataDir} - ], - Cmd = [ - Terraform, - "destroy", - "-auto-approve=true", - {"-state=~s", [TfState]} - ] ++ TfVarFlags ++ [ - TfConfigDir - ], - rabbit_ct_helpers:exec(Cmd, [{env, Env}]), - Config. - -terraform_var_flags(Config) -> - ErlangVersion = ?config(erlang_version, Config), - GitRef = ?config(erlang_git_ref, Config), - ElixirVersion = ?config(elixir_version, Config), - SshKey = ?config(terraform_ssh_key, Config), - Suffix = ?config(terraform_files_suffix, Config), - EC2Region = ?config(terraform_aws_ec2_region, Config), - InstanceCount = instance_count(Config), - InstanceName0 = rabbit_ct_helpers:get_config(Config, terraform_instance_name), - InstanceName = case InstanceName0 of - undefined -> Suffix; - _ -> InstanceName0 - end, - CidrBlock = ?config(terraform_vpc_cidr_block, Config), - ErlangApp = rabbit_ct_helpers:get_config(Config, tested_erlang_app), - InstanceNamePrefix = case ErlangApp of - undefined -> - "RabbitMQ testing: "; - _ -> - rabbit_misc:format("~s: ", [ErlangApp]) - end, - TestedApp = ?config(tested_erlang_app, Config), - _ = application:load(TestedApp), - InstanceNameSuffix = case application:get_key(TestedApp, vsn) of - {ok, AppVer} -> " - " ++ AppVer; - undefined -> "" - end, - ct:pal(?LOW_IMPORTANCE, "Number of VMs requested: ~b", [InstanceCount]), - Archive = ?config(upload_dirs_archive, Config), - [ - {"-var=erlang_version=~s", [ErlangVersion]}, - {"-var=erlang_git_ref=~s", [GitRef]}, - {"-var=elixir_version=~s", [ElixirVersion]}, - {"-var=erlang_cookie=~s", [erlang:get_cookie()]}, - {"-var=erlang_nodename=~s", [?ERLANG_REMOTE_NODENAME]}, - {"-var=ssh_key=~s", [SshKey]}, - {"-var=instance_count=~b", [InstanceCount]}, - {"-var=instance_name=~s", [InstanceName]}, - {"-var=upload_dirs_archive=~s", [Archive]}, - {"-var=vpc_cidr_block=~s", [CidrBlock]}, - {"-var=files_suffix=~s", [Suffix]}, - {"-var=aws_ec2_region=~s", [EC2Region]}, - {"-var=instance_name_prefix=~s", [InstanceNamePrefix]}, - {"-var=instance_name_suffix=~s", [InstanceNameSuffix]} - ]. - -instance_count(Config) -> - InstanceCount0 = rabbit_ct_helpers:get_config( - Config, terraform_instance_count), - case InstanceCount0 of - undefined -> 1; - N when is_integer(N) andalso N >= 1 -> N - end. - -query_terraform_uuid(Config) -> - Terraform = ?config(terraform_cmd, Config), - TfState = ?config(terraform_state, Config), - Cmd = [ - Terraform, - "output", - "-no-color", - {"-state=~s", [TfState]}, - "uuid" - ], - case rabbit_ct_helpers:exec(Cmd) of - {ok, Output} -> - Uuid = string:strip(string:strip(Output, right, $\n)), - rabbit_ct_helpers:set_config(Config, {terraform_uuid, Uuid}); - _ -> - {skip, "Terraform failed to query unique ID"} - end. - -query_ct_peer_nodenames_and_ipaddrs(Config) -> - case query_terraform_map(Config, "ct_peer_nodenames") of - {ok, NodenamesMap} -> - case query_terraform_map(Config, "ct_peer_ipaddrs") of - {ok, IPAddrsMap} -> - initialize_ct_peers(Config, NodenamesMap, IPAddrsMap); - Error -> - Error - end; - Error -> - Error - end. - -query_terraform_map(Config, Var) -> - QueryMode = ?config(terraform_query_mode, Config), - case QueryMode of - direct -> - query_terraform_map_directly(Config, Var); - polling -> - poll_terraform_map(Config, Var) - end. - -query_terraform_map_directly(Config, Var) -> - TfState = ?config(terraform_state, Config), - case do_query_terraform_map(Config, TfState, Var) of - {skip, _} -> - Config1 = rabbit_ct_helpers:set_config( - Config, {terraform_query_mode, polling}), - query_terraform_map(Config1, Var); - Ret -> - Ret - end. - -poll_terraform_map(Config, Var) -> - case poll_vms(Config) of - {skip, _} = Error -> - Error; - Config1 -> - query_terraform_map_from_poll_state(Config1, Var) - end. - -poll_vms(Config) -> - case rabbit_ct_helpers:get_config(Config, terraform_poll_done) of - undefined -> - Timeout = 5 * 60 * 1000, - {ok, TRef} = timer:send_after(Timeout, terraform_poll_timeout), - do_poll_vms(Config, TRef); - true -> - Config - end. - -do_poll_vms(Config, TRef) -> - TfConfigDir = ?config(terraform_poll_config_dir, Config), - TfDataDir = ?config(terraform_poll_data_dir, Config), - TfState = ?config(terraform_poll_state, Config), - Uuid = ?config(terraform_uuid, Config), - Terraform = ?config(terraform_cmd, Config), - Env = [ - {"TF_DATA_DIR", TfDataDir} - ], - Cmd = [ - Terraform, - "apply", - "-auto-approve=true", - {"-state=~s", [TfState]}, - {"-var=uuid=~s", [Uuid]}, - {"-var=erlang_nodename=~s", [?ERLANG_REMOTE_NODENAME]}, - TfConfigDir - ], - case rabbit_ct_helpers:exec(Cmd, [{env, Env}]) of - {ok, _} -> ensure_instance_count(Config, TRef); - _ -> {skip, "Terraform failed to query VMs"} - end. - -ensure_instance_count(Config, TRef) -> - Terraform = ?config(terraform_cmd, Config), - TfState = ?config(terraform_poll_state, Config), - Cmd = [ - Terraform, - "output", - "-no-color", - {"-state=~s", [TfState]}, - "instance_count" - ], - case rabbit_ct_helpers:exec(Cmd) of - {ok, Output} -> - CountStr = string:strip(string:strip(Output, right, $\n)), - Current = erlang:list_to_integer(CountStr), - Requested = instance_count(Config), - ct:pal(?LOW_IMPORTANCE, - "Number of VMs ready: ~b (at least ~b requested)", - [Current, Requested]), - if - Current < Requested -> - receive - terraform_poll_timeout -> - {skip, "Terraform failed to query VMs (timeout)"} - after 5000 -> - poll_vms(Config) - end; - true -> - timer:cancel(TRef), - rabbit_ct_helpers:set_config(Config, - {terraform_poll_done, true}) - end; - _ -> - {skip, "Terraform failed to query VMs"} - end. - -query_terraform_map_from_poll_state(Config, Var) -> - TfState = ?config(terraform_poll_state, Config), - do_query_terraform_map(Config, TfState, Var). - -do_query_terraform_map(Config, TfState, Var) -> - Terraform = ?config(terraform_cmd, Config), - Cmd = [ - Terraform, - "output", - "-no-color", - {"-state=~s", [TfState]}, - Var - ], - case rabbit_ct_helpers:exec(Cmd) of - {ok, Output} -> - Map = parse_terraform_map(Output), - ct:pal(?LOW_IMPORTANCE, "Terraform map: ~p", [Map]), - {ok, Map}; - _ -> - {skip, "Terraform failed to query VMs"} - end. - -parse_terraform_map(Output) -> - Lines = [string:strip(L, right, $,) - || L <- string:tokens( - string:strip(Output, right, $\n), - "\n"), - string:find(L, "=") =/= nomatch], - [begin - [K0, V0] = string:tokens(L, "="), - K = string:strip(string:strip(K0), both, $"), - V = string:strip(string:strip(V0), both, $"), - {K, V} - end || L <- Lines]. - -initialize_ct_peers(Config, NodenamesMap, IPAddrsMap) -> - CTPeers = lists:map( - fun({Hostname, NodenameStr}) -> - Nodename = list_to_atom(NodenameStr), - IPAddrStr = proplists:get_value(Hostname, IPAddrsMap), - {ok, IPAddr} = inet:parse_strict_address(IPAddrStr), - {Nodename, - [ - {hostname, Hostname}, - {ipaddr, IPAddr}, - % FIXME: We assume some kind of Linux - % distribution here. - {make_cmd, "make"} - ]} - end, NodenamesMap), - ct:pal(?LOW_IMPORTANCE, "Remote Erlang nodes: ~p", [CTPeers]), - rabbit_ct_helpers:set_config(Config, {ct_peers, CTPeers}). - -set_inet_hosts(Config) -> - CTPeers = get_ct_peer_entries(Config), - inet_db:set_lookup([file, native]), - [begin - Hostname = ?config(hostname, CTPeerConfig), - IPAddr = ?config(ipaddr, CTPeerConfig), - inet_db:add_host(IPAddr, [Hostname]), - rabbit_misc:format("{host, ~p, [~p]}.~n", - [IPAddr, Hostname]) - end || {_, CTPeerConfig} <- CTPeers], - Config. - -write_inetrc(Config) -> - PrivDir = ?config(priv_dir, Config), - Suffix = ?config(terraform_files_suffix, Config), - Filename = filename:join( - PrivDir, - rabbit_misc:format("inetrc-~s", [Suffix])), - LockId = {erlang_inetrc, self()}, - LockNodes = [node()], - % We write an `inetrc` file per setup so there is no risk of - % conflict here. However, we want to set the `$ERL_INETRC` - % environment variable (i.e. something global) because it's exported - % later by rabbit_ct_helpers:exec() to sub-processes. The lock here - % ensures we query inetrc, write the file and set `$ERL_INETRC` - % atomically: we don't want to point the environment variable to an - % old copy of `inetrc`. - global:set_lock(LockId, LockNodes), - Inetrc = inet:get_rc(), - Lines0 = lists:filter( - fun - ({host, _, _}) -> true; - ({lookup, _}) -> true; - (_) -> false - end, Inetrc), - Lines = [io_lib:format("~p.~n", [Line]) || Line <- Lines0], - ct:pal( - ?LOW_IMPORTANCE, - "Erlang inetrc:~n~s", - [string:strip([" " ++ Line || Line <- Lines], right, $\n)]), - case file:write_file(Filename, Lines) of - ok -> - os:putenv("ERL_INETRC", Filename), - global:del_lock(LockId, LockNodes), - Config; - {error, Reason} -> - global:del_lock(LockId, LockNodes), - ct:pal(?LOW_IMPORTANCE, "Failed to write inetrc: ~p~n", [Reason]), - {skip, "Failed to write inetrc"} - end. - -wait_for_ct_peers(Config) -> - CTPeers = get_ct_peers(Config), - Timeout = 40 * 60 * 1000, - {ok, TRef} = timer:send_after(Timeout, ct_peers_timeout), - wait_for_ct_peers(Config, CTPeers, TRef). - -wait_for_ct_peers(Config, [CTPeer | Rest] = CTPeers, TRef) -> - case net_adm:ping(CTPeer) of - pong -> - ct:pal(?LOW_IMPORTANCE, "Remote Erlang node ~p ready", [CTPeer]), - wait_for_ct_peers(Config, Rest, TRef); - pang -> - receive - ct_peers_timeout -> - ct:pal(?LOW_IMPORTANCE, - "Remote Erlang node ~p didn't respond to pings", - [CTPeer]), - {skip, "Failed to ping remote Erlang nodes (timeout)"} - after 5000 -> - wait_for_ct_peers(Config, CTPeers, TRef) - end - end; -wait_for_ct_peers(Config, [], TRef) -> - timer:cancel(TRef), - Config. - -set_ct_peers_code_path(Config) -> - CodePath = ?config(erlang_code_path, Config), - rpc_all(Config, code, add_pathsa, [lists:reverse(CodePath)]), - Config. - -start_ct_logs_proxies(Config) -> - CTPeers = get_ct_peers(Config), - do_setup_ct_logs_proxies(CTPeers), - Config. - -configure_ct_peers_environment(Config) -> - Vars = ["DEPS_DIR"], - Values = [{Var, Value} - || Var <- Vars, - Value <- [os:getenv(Var)], - Value =/= false], - ct:pal(?LOW_IMPORTANCE, - "Env. variables to set on remote VMs: ~p~n", [Values]), - lists:foreach( - fun({Var, Value}) -> - rpc_all(Config, os, putenv, [Var, Value]) - end, Values), - Config. - -download_dirs(Config) -> - ConfigsPerCTPeer = rpc_all( - Config, - ?MODULE, - prepare_dirs_to_download_archives, - [Config]), - inets:start(), - download_dirs(Config, ConfigsPerCTPeer). - -download_dirs(_, [{skip, _} = Error | _]) -> - Error; -download_dirs(Config, [ConfigPerCTPeer | Rest]) -> - Urls = ?config(download_dirs_archive_urls, ConfigPerCTPeer), - case download_urls(Config, Urls) of - {skip, _} = Error -> Error; - Config1 -> download_dirs(Config1, Rest) - end; -download_dirs(Config, []) -> - Config. - -download_urls(Config, [Url | Rest]) -> - PrivDir = ?config(priv_dir, Config), - Headers = [{"connection", "close"}], - Options = [{body_format, binary}], - ct:pal(?LOW_IMPORTANCE, "Fetching download dirs archive at `~s`", [Url]), - Ret = httpc:request(get, {Url, Headers}, [], Options), - case Ret of - {ok, {{_, 200, _}, _, Body}} -> - Archive = filename:join(PrivDir, filename:basename(Url)), - case file:write_file(Archive, Body) of - ok -> - download_urls(Config, Rest); - {error, Reason} -> - ct:pal( - ?LOW_IMPORTANCE, - "Failed to write download dirs archive `~s` " - "to `~s`: ~p", - [Url, Archive, Reason]), - {skip, "Failed to write download dirs archive"} - end; - _ -> - ct:pal( - ?LOW_IMPORTANCE, - "Failed to download dirs archive `~s`: ~p", - [Url, Ret]), - {skip, "Failed to download dirs archive"} - end; -download_urls(Config, []) -> - Config. - -prepare_dirs_to_download_archives(Config) -> - CTPeer = node(), - Dirs = ?config(dirs_to_download, Config), - prepare_dirs_to_download_archives(Config, CTPeer, Dirs, 1). - -prepare_dirs_to_download_archives(Config, CTPeer, [Dir | Rest], I) -> - Config1 = case filelib:is_dir(Dir) of - true -> - prepare_dirs_to_download_archive( - Config, CTPeer, Dir, I); - false -> - Config - end, - case Config1 of - {skip, _} = Error -> - Error; - _ -> - prepare_dirs_to_download_archives(Config1, CTPeer, Rest, I + 1) - end; -prepare_dirs_to_download_archives(Config, _, [], _) -> - start_http_server(Config). - -prepare_dirs_to_download_archive(Config, CTPeer, Dir, I) -> - PrivDir = ?config(priv_dir, Config), - Archive = rabbit_misc:format( - "~s-~b-~s.tar.gz", [CTPeer, I, filename:basename(Dir)]), - FilesList = [File || File <- filelib:wildcard("**", Dir), - not filelib:is_dir(filename:join(Dir, File))], - ct:pal(?LOW_IMPORTANCE, "Creating download dirs archive `~s`", [Archive]), - Ret = erl_tar:create( - filename:join(PrivDir, Archive), - [{File, filename:join(Dir, File)} || File <- FilesList], - [compressed]), - case Ret of - ok -> - add_archive_to_list(Config, Archive); - {error, Reason} -> - ct:pal( - ?LOW_IMPORTANCE, - "Failed to create download dirs archive `~s` for dir `~s`: ~p", - [Archive, Dir, Reason]), - {skip, "Failed to create download dirs archive"} - end. - -add_archive_to_list(Config, Archive) -> - AL = rabbit_ct_helpers:get_config(Config, download_dir_archives), - ArchivesList = case AL of - undefined -> []; - _ -> AL - end, - rabbit_ct_helpers:set_config( - Config, {download_dir_archives, [Archive | ArchivesList]}). - -start_http_server(Config) -> - PrivDir = ?config(priv_dir, Config), - {ok, Hostname} = inet:gethostname(), - inets:start(), - Options = [{port, 0}, - {server_name, Hostname}, - {server_root, PrivDir}, - {document_root, PrivDir}, - {keep_alive, false}], - case inets:start(httpd, Options) of - {ok, Pid} -> - HttpInfo = httpd:info(Pid), - ct:pal( - ?LOW_IMPORTANCE, - "Ready to serve download dirs archive at `~s`", - [archive_name_to_url(HttpInfo, "")]), - archive_names_to_urls(Config, HttpInfo); - {error, Reason} -> - ct:pal( - ?LOW_IMPORTANCE, - "Failed to start HTTP server to serve download dirs " - "archives: ~p", - [Reason]), - {skiip, "Failed to start dirs archive HTTP server"} - end. - -archive_names_to_urls(Config, HttpInfo) -> - ArchivesList = ?config(download_dir_archives, Config), - UrlsList = [archive_name_to_url(HttpInfo, Archive) - || Archive <- ArchivesList], - rabbit_ct_helpers:set_config( - Config, {download_dirs_archive_urls, UrlsList}). - -archive_name_to_url(HttpInfo, Archive) -> - Hostname = proplists:get_value(server_name, HttpInfo), - Port = proplists:get_value(port, HttpInfo), - rabbit_misc:format("http://~s:~b/~s", [Hostname, Port, Archive]). - -stop_ct_peers(Config) -> - CTPeers = get_ct_peers(Config), - stop_ct_peers(Config, CTPeers). - -stop_ct_peers(Config, [CTPeer | Rest]) -> - erlang:monitor_node(CTPeer, true), - rpc(Config, CTPeer, init, stop), - receive - {nodedown, CTPeer} -> ok - end, - stop_ct_peers(Config, Rest); -stop_ct_peers(Config, []) -> - Config. - -%% ------------------------------------------------------------------- -%% CT logs + user I/O proxying. -%% ------------------------------------------------------------------- - -do_setup_ct_logs_proxies(Nodes) -> - [begin - user_io_proxy(Node), - ct_logs_proxy(Node) - end || Node <- Nodes]. - -user_io_proxy(Node) -> - ok = setup_proxy(Node, user). - -ct_logs_proxy(Node) -> - ok = setup_proxy(Node, ct_logs). - -setup_proxy(Node, RegName) -> - case whereis(RegName) of - undefined -> - ok; - Pid -> - ok = rpc:call(Node, ?MODULE, do_setup_proxy, [RegName, Pid]) - end. - -do_setup_proxy(RegName, Pid) -> - case whereis(RegName) of - undefined -> - ok; - OldProxy -> - erlang:unregister(RegName), - erlang:exit(OldProxy, normal) - end, - ProxyPid = erlang:spawn(?MODULE, proxy_loop, [Pid]), - true = erlang:register(RegName, ProxyPid), - ok. - -proxy_loop(UpstreamPid) -> - receive - Msg -> - UpstreamPid ! Msg, - proxy_loop(UpstreamPid) - end. - -%% ------------------------------------------------------------------- -%% Other helpers. -%% ------------------------------------------------------------------- - -get_ct_peer_entries(Config) -> - case rabbit_ct_helpers:get_config(Config, ct_peers) of - undefined -> []; - CTPeers -> CTPeers - end. - -get_ct_peer_entry(Config, VM) when is_integer(VM) andalso VM >= 0 -> - CTPeers = get_ct_peer_entries(Config), - case VM < length(CTPeers) of - true -> lists:nth(VM + 1, CTPeers); - false -> throw({out_of_bound_ct_peer, VM, CTPeers}) - end; -get_ct_peer_entry(Config, VM) when is_atom(VM) -> - CTPeers = get_ct_peer_entries(Config), - case proplists:lookup(VM, CTPeers) of - none -> throw({unknown_ct_peer, VM, CTPeers}); - CTPeer -> CTPeer - end. - -get_ct_peers(Config) -> - [CTPeer || {CTPeer, _} <- get_ct_peer_entries(Config)]. - -get_ct_peer(Config, VM) -> - {CTPeer, _} = get_ct_peer_entry(Config, VM), - CTPeer. - -get_ct_peer_configs(Config, Key) -> - CTPeerEntries = get_ct_peer_entries(Config), - [?config(Key, CTPeerConfig) || {_, CTPeerConfig} <- CTPeerEntries]. - -get_ct_peer_config(Config, VM) -> - {_, CTPeerConfig} = get_ct_peer_entry(Config, VM), - CTPeerConfig. - -get_ct_peer_config(Config, VM, Key) -> - CTPeerConfig = get_ct_peer_config(Config, VM), - ?config(Key, CTPeerConfig). - -get_current_vm_config(Config, Key) -> - try - CTPeerConfig = get_ct_peer_config(Config, node()), - case rabbit_ct_helpers:get_config(CTPeerConfig, Key) of - undefined -> - ?config(Key, Config); - Value -> - Value - end - catch - throw:{Reason, _, _} when - Reason =:= out_of_bound_ct_peer orelse - Reason =:= unknown_ct_peer -> - ?config(Key, Config) - end. - -rpc(Config, VM, Module, Function) -> - rpc(Config, VM, Module, Function, []). - -rpc(Config, VM, Module, Function, Args) - when is_integer(VM) orelse is_atom(VM) -> - CTPeer = get_ct_peer(Config, VM), - %% We add some directories to the remote node search path. - rabbit_ct_broker_helpers:add_code_path_to_node(CTPeer, Module), - Ret = rpc:call(CTPeer, Module, Function, Args), - case Ret of - {badrpc, {'EXIT', Reason}} -> exit(Reason); - {badrpc, Reason} -> exit(Reason); - Ret -> Ret - end; -rpc(Config, VMs, Module, Function, Args) - when is_list(VMs) -> - [rpc(Config, VM, Module, Function, Args) || VM <- VMs]. - -rpc_all(Config, Module, Function) -> - rpc_all(Config, Module, Function, []). - -rpc_all(Config, Module, Function, Args) -> - CTPeers = get_ct_peers(Config), - rpc(Config, CTPeers, Module, Function, Args). diff --git a/deps/rabbitmq_ct_helpers/src/rabbit_mgmt_test_util.erl b/deps/rabbitmq_ct_helpers/src/rabbit_mgmt_test_util.erl deleted file mode 100644 index 7424108d4e5a..000000000000 --- a/deps/rabbitmq_ct_helpers/src/rabbit_mgmt_test_util.erl +++ /dev/null @@ -1,323 +0,0 @@ -%% 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) 2010-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_mgmt_test_util). - --include("rabbit_mgmt_test.hrl"). --include_lib("eunit/include/eunit.hrl"). - --compile([nowarn_export_all, export_all]). - -reset_management_settings(Config) -> - rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env, - [rabbit, collect_statistics_interval, 5000]), - Config. - -merge_stats_app_env(Config, Interval, SampleInterval) -> - Config1 = rabbit_ct_helpers:merge_app_env( - Config, {rabbit, [{collect_statistics_interval, Interval}]}), - rabbit_ct_helpers:merge_app_env( - Config1, {rabbitmq_management_agent, [{sample_retention_policies, - [{global, [{605, SampleInterval}]}, - {basic, [{605, SampleInterval}]}, - {detailed, [{10, SampleInterval}]}] }]}). -http_get_from_node(Config, Node, Path) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, Node, get, Path, [auth_header("guest", "guest")]), - assert_code(?OK, CodeAct, "GET", Path, ResBody), - decode(?OK, Headers, ResBody). - -http_get(Config, Path) -> - http_get(Config, Path, ?OK). - -http_get(Config, Path, CodeExp) -> - http_get(Config, Path, "guest", "guest", CodeExp). - -http_get(Config, Path, User, Pass, CodeExp) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, 0, get, Path, [auth_header(User, Pass)]), - assert_code(CodeExp, CodeAct, "GET", Path, ResBody), - decode(CodeExp, Headers, ResBody). - -http_get_as_proplist(Config, Path) -> - {ok, {{_HTTP, CodeAct, _}, _Headers, ResBody}} = - req(Config, get, Path, [auth_header("guest", "guest")]), - assert_code(?OK, CodeAct, "GET", Path, ResBody), - JSON = rabbit_data_coercion:to_binary(ResBody), - cleanup(rabbit_json:decode(JSON, [{return_maps, false}])). - -http_get_no_map(Config, Path) -> - http_get_as_proplist(Config, Path). - -http_get_no_auth(Config, Path, CodeExp) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, 0, get, Path, []), - assert_code(CodeExp, CodeAct, "GET", Path, ResBody), - decode(CodeExp, Headers, ResBody). - -http_put(Config, Path, List, CodeExp) -> - http_put_raw(Config, Path, format_for_upload(List), CodeExp). - -http_put(Config, Path, List, User, Pass, CodeExp) -> - http_put_raw(Config, Path, format_for_upload(List), User, Pass, CodeExp). - -http_post(Config, Path, List, CodeExp) -> - http_post_raw(Config, Path, format_for_upload(List), CodeExp). - -http_post(Config, Path, List, User, Pass, CodeExp) -> - http_post_raw(Config, Path, format_for_upload(List), User, Pass, CodeExp). - -http_post_accept_json(Config, Path, List, CodeExp) -> - http_post_accept_json(Config, Path, List, "guest", "guest", CodeExp). - -http_post_accept_json(Config, Path, List, User, Pass, CodeExp) -> - http_post_raw(Config, Path, format_for_upload(List), User, Pass, CodeExp, - [{"Accept", "application/json"}]). - -assert_permanent_redirect(Config, Path, ExpectedLocation) -> - Node = 0, - Uri = uri_base_from(Config, Node, Path), - ExpectedResponseCode = 301, - {ok, {{_, ExpectedResponseCode, _}, Headers, _}} = - httpc:request(get, {Uri, []}, ?HTTPC_OPTS, []), - Prefix = get_uri_prefix(Config), - ?assertEqual(Prefix ++ ExpectedLocation, - proplists:get_value("location", Headers)). - -req(Config, Type, Path, Headers) -> - req(Config, 0, Type, Path, Headers). - -req(Config, Node, get_static, Path, Headers) -> - httpc:request(get, {uri_base_from(Config, Node, "") ++ Path, Headers}, ?HTTPC_OPTS, []); -req(Config, Node, Type, Path, Headers) -> - httpc:request(Type, {uri_base_from(Config, Node) ++ Path, Headers}, ?HTTPC_OPTS, []). - -req(Config, Node, Type, Path, Headers, Body) -> - ContentType = case proplists:get_value("content-type", Headers) of - undefined -> - "application/json"; - CT -> - CT - end, - httpc:request(Type, {uri_base_from(Config, Node) ++ Path, Headers, ContentType, Body}, ?HTTPC_OPTS, []). - -uri_base_from(Config, Node) -> - uri_base_from(Config, Node, "api"). -uri_base_from(Config, Node, Base) -> - Port = mgmt_port(Config, Node), - Prefix = get_uri_prefix(Config), - Uri = rabbit_mgmt_format:print("http://localhost:~w~s/~s", [Port, Prefix, Base]), - binary_to_list(Uri). - -get_uri_prefix(Config) -> - ErlNodeCnf = proplists:get_value(erlang_node_config, Config, []), - MgmtCnf = proplists:get_value(rabbitmq_management, ErlNodeCnf, []), - proplists:get_value(path_prefix, MgmtCnf, ""). - -auth_header(Username, Password) when is_binary(Username) -> - auth_header(binary_to_list(Username), Password); -auth_header(Username, Password) when is_binary(Password) -> - auth_header(Username, binary_to_list(Password)); -auth_header(Username, Password) -> - {"Authorization", - "Basic " ++ binary_to_list(base64:encode(Username ++ ":" ++ Password))}. - -amqp_port(Config) -> - config_port(Config, tcp_port_amqp). - -mgmt_port(Config, Node) -> - config_port(Config, Node, tcp_port_mgmt). - -config_port(Config, PortKey) -> - config_port(Config, 0, PortKey). - -config_port(Config, Node, PortKey) -> - rabbit_ct_broker_helpers:get_node_config(Config, Node, PortKey). - -http_put_raw(Config, Path, Body, CodeExp) -> - http_upload_raw(Config, put, Path, Body, "guest", "guest", CodeExp, []). - -http_put_raw(Config, Path, Body, User, Pass, CodeExp) -> - http_upload_raw(Config, put, Path, Body, User, Pass, CodeExp, []). - - -http_post_raw(Config, Path, Body, CodeExp) -> - http_upload_raw(Config, post, Path, Body, "guest", "guest", CodeExp, []). - -http_post_raw(Config, Path, Body, User, Pass, CodeExp) -> - http_upload_raw(Config, post, Path, Body, User, Pass, CodeExp, []). - -http_post_raw(Config, Path, Body, User, Pass, CodeExp, MoreHeaders) -> - http_upload_raw(Config, post, Path, Body, User, Pass, CodeExp, MoreHeaders). - - -http_upload_raw(Config, Type, Path, Body, User, Pass, CodeExp, MoreHeaders) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, 0, Type, Path, [auth_header(User, Pass)] ++ MoreHeaders, Body), - assert_code(CodeExp, CodeAct, Type, Path, ResBody), - decode(CodeExp, Headers, ResBody). - -http_delete(Config, Path, CodeExp) -> - http_delete(Config, Path, "guest", "guest", CodeExp). - -http_delete(Config, Path, CodeExp, Body) -> - http_delete(Config, Path, "guest", "guest", CodeExp, Body). - -http_delete(Config, Path, User, Pass, CodeExp, Body) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, 0, delete, Path, [auth_header(User, Pass)], Body), - assert_code(CodeExp, CodeAct, "DELETE", Path, ResBody), - decode(CodeExp, Headers, ResBody). - -http_delete(Config, Path, User, Pass, CodeExp) -> - {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = - req(Config, 0, delete, Path, [auth_header(User, Pass)]), - assert_code(CodeExp, CodeAct, "DELETE", Path, ResBody), - decode(CodeExp, Headers, ResBody). - -format_for_upload(none) -> - <<"">>; -format_for_upload(List) -> - iolist_to_binary(rabbit_json:encode(List)). - -assert_code({one_of, CodesExpected}, CodeAct, Type, Path, Body) when is_list(CodesExpected) -> - case lists:member(CodeAct, CodesExpected) of - true -> - ok; - false -> - error({expected, CodesExpected, got, CodeAct, type, Type, - path, Path, body, Body}) - end; -assert_code({group, '2xx'} = CodeExp, CodeAct, Type, Path, Body) -> - case CodeAct of - 200 -> ok; - 201 -> ok; - 202 -> ok; - 203 -> ok; - 204 -> ok; - 205 -> ok; - 206 -> ok; - _ -> error({expected, CodeExp, got, CodeAct, type, Type, - path, Path, body, Body}) - end; -assert_code({group, '3xx'} = CodeExp, CodeAct, Type, Path, Body) -> - case CodeAct of - 300 -> ok; - 301 -> ok; - 302 -> ok; - 303 -> ok; - 304 -> ok; - 305 -> ok; - 306 -> ok; - 307 -> ok; - _ -> error({expected, CodeExp, got, CodeAct, type, Type, - path, Path, body, Body}) - end; -assert_code({group, '4xx'} = CodeExp, CodeAct, Type, Path, Body) -> - case CodeAct of - 400 -> ok; - 401 -> ok; - 402 -> ok; - 403 -> ok; - 404 -> ok; - 405 -> ok; - 406 -> ok; - 407 -> ok; - 408 -> ok; - 409 -> ok; - 410 -> ok; - 411 -> ok; - 412 -> ok; - 413 -> ok; - 414 -> ok; - 415 -> ok; - 416 -> ok; - 417 -> ok; - _ -> error({expected, CodeExp, got, CodeAct, type, Type, - path, Path, body, Body}) - end; -assert_code(CodeExp, CodeAct, Type, Path, Body) when is_list(CodeExp) -> - assert_code({one_of, CodeExp}, CodeAct, Type, Path, Body); -assert_code(CodeExp, CodeAct, Type, Path, Body) -> - case CodeExp of - CodeAct -> ok; - _ -> error({expected, CodeExp, got, CodeAct, type, Type, - path, Path, body, Body}) - end. - -decode(?OK, _Headers, ResBody) -> - JSON = rabbit_data_coercion:to_binary(ResBody), - cleanup(rabbit_json:decode(JSON)); -decode(_, Headers, _ResBody) -> Headers. - -cleanup(L) when is_list(L) -> - [cleanup(I) || I <- L]; -cleanup(M) when is_map(M) -> - maps:fold(fun(K, V, Acc) -> - Acc#{binary_to_atom(K, latin1) => cleanup(V)} - end, #{}, M); -cleanup(I) -> - I. - -%% @todo There wasn't a specific order before; now there is; maybe we shouldn't have one? -assert_list(Exp, Act) -> - case length(Exp) == length(Act) of - true -> ok; - false -> error({expected, Exp, actual, Act}) - end, - [case length(lists:filter(fun(ActI) -> test_item(ExpI, ActI) end, Act)) of - 1 -> ok; - N -> error({found, N, ExpI, in, Act}) - end || ExpI <- Exp]. - %_ = [assert_item(ExpI, ActI) || {ExpI, ActI} <- lists:zip(Exp, Act)], - -assert_item(ExpI, [H | _] = ActI) when is_list(ActI) -> - %% just check first item of the list - assert_item(ExpI, H), - ok; -assert_item(ExpI, ActI) -> - ?assertEqual(ExpI, maps:with(maps:keys(ExpI), ActI)), - ok. - -assert_item_kv(Exp, Act) when is_list(Exp) -> - case test_item0_kv(Exp, Act) of - [] -> ok; - Or -> error(Or) - end. - -test_item(Exp, Act) -> - case test_item0(Exp, Act) of - [] -> true; - _ -> false - end. - -test_item0(Exp, Act) -> - [{did_not_find, KeyExpI, in, Act} || KeyExpI <- maps:keys(Exp), - maps:get(KeyExpI, Exp) =/= maps:get(KeyExpI, Act, null)]. - -test_item0_kv(Exp, Act) -> - [{did_not_find, ExpI, in, Act} || ExpI <- Exp, - not lists:member(ExpI, Act)]. - -assert_keys(Exp, Act) -> - case test_key0(Exp, Act) of - [] -> ok; - Or -> error(Or) - end. - -test_key0(Exp, Act) -> - [{did_not_find, ExpI, in, Act} || ExpI <- Exp, - not maps:is_key(ExpI, Act)]. -assert_no_keys(NotExp, Act) -> - case test_no_key0(NotExp, Act) of - [] -> ok; - Or -> error(Or) - end. - -test_no_key0(Exp, Act) -> - [{invalid_key, ExpI, in, Act} || ExpI <- Exp, - maps:is_key(ExpI, Act)]. diff --git a/deps/rabbitmq_ct_helpers/test/terraform_SUITE.erl b/deps/rabbitmq_ct_helpers/test/terraform_SUITE.erl deleted file mode 100644 index 461eaf31251b..000000000000 --- a/deps/rabbitmq_ct_helpers/test/terraform_SUITE.erl +++ /dev/null @@ -1,166 +0,0 @@ -%% 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) 2018-2022 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(terraform_SUITE). - --include_lib("common_test/include/ct.hrl"). --include_lib("eunit/include/eunit.hrl"). - --export([all/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, - - run_code_on_one_vm/1, do_run_code_on_one_vm/1, - run_code_on_three_vms/1, do_run_code_on_three_vms/1, - run_one_rabbitmq_node/1, - run_four_rabbitmq_nodes/1 - ]). - -all() -> - [ - {group, direct_vms}, - {group, autoscaling_group} - ]. - -groups() -> - [ - {direct_vms, [parallel], [{group, run_code}, - {group, run_rabbitmq}]}, - {autoscaling_group, [parallel], [{group, run_code}, - {group, run_rabbitmq}]}, - - {run_code, [parallel], [run_code_on_one_vm, - run_code_on_three_vms]}, - {run_rabbitmq, [parallel], [run_one_rabbitmq_node, - run_four_rabbitmq_nodes]} - ]. - -init_per_suite(Config) -> - rabbit_ct_helpers:log_environment(), - rabbit_ct_helpers:run_setup_steps(Config). - -end_per_suite(Config) -> - rabbit_ct_helpers:run_teardown_steps(Config). - -init_per_group(autoscaling_group, Config) -> - TfConfigDir = rabbit_ct_vm_helpers:aws_autoscaling_group_module(Config), - rabbit_ct_helpers:set_config( - Config, {terraform_config_dir, TfConfigDir}); -init_per_group(Group, Config) -> - rabbit_ct_helpers:set_config( - Config, {run_rabbitmq, Group =:= run_rabbitmq}). - -end_per_group(_Group, Config) -> - Config. - -init_per_testcase(Testcase, Config) -> - rabbit_ct_helpers:testcase_started(Config, Testcase), - RunRabbitMQ = ?config(run_rabbitmq, Config), - InstanceCount = case Testcase of - run_code_on_three_vms -> 3; - run_three_rabbitmq_nodes -> 3; - % We want more RabbitMQs than VMs. - run_four_rabbitmq_nodes -> 3; - _ -> 1 - end, - InstanceName = rabbit_ct_helpers:testcase_absname(Config, Testcase), - ClusterSize = case Testcase of - run_one_rabbitmq_node -> 1; - run_three_rabbitmq_nodes -> 3; - % We want more RabbitMQs than VMs. - run_four_rabbitmq_nodes -> 4; - _ -> 0 - end, - Config1 = rabbit_ct_helpers:set_config( - Config, - [{terraform_instance_count, InstanceCount}, - {terraform_instance_name, InstanceName}, - {rmq_nodename_suffix, Testcase}, - {rmq_nodes_count, ClusterSize}]), - case RunRabbitMQ of - false -> - rabbit_ct_helpers:run_steps( - Config1, - rabbit_ct_vm_helpers:setup_steps()); - true -> - rabbit_ct_helpers:run_steps( - Config1, - [fun rabbit_ct_broker_helpers:run_make_dist/1] ++ - rabbit_ct_vm_helpers:setup_steps() ++ - rabbit_ct_broker_helpers:setup_steps_for_vms()) - end. - -end_per_testcase(Testcase, Config) -> - RunRabbitMQ = ?config(run_rabbitmq, Config), - Config1 = case RunRabbitMQ of - false -> - rabbit_ct_helpers:run_steps( - Config, - rabbit_ct_vm_helpers:teardown_steps()); - true -> - rabbit_ct_helpers:run_steps( - Config, - rabbit_ct_broker_helpers:teardown_steps_for_vms() ++ - rabbit_ct_vm_helpers:teardown_steps()) - end, - rabbit_ct_helpers:testcase_finished(Config1, Testcase). - -%% ------------------------------------------------------------------- -%% Run arbitrary code. -%% ------------------------------------------------------------------- - -run_code_on_one_vm(Config) -> - rabbit_ct_vm_helpers:rpc_all(Config, - ?MODULE, do_run_code_on_one_vm, [node()]). - -do_run_code_on_one_vm(CTMaster) -> - CTPeer = node(), - ct:pal("Testcase running on ~s", [CTPeer]), - ?assertNotEqual(CTMaster, CTPeer), - ?assertEqual(pong, net_adm:ping(CTMaster)). - -run_code_on_three_vms(Config) -> - rabbit_ct_vm_helpers:rpc_all(Config, - ?MODULE, do_run_code_on_three_vms, [node()]). - -do_run_code_on_three_vms(CTMaster) -> - CTPeer = node(), - ct:pal("Testcase running on ~s", [CTPeer]), - ?assertNotEqual(CTMaster, CTPeer), - ?assertEqual(pong, net_adm:ping(CTMaster)). - -%% ------------------------------------------------------------------- -%% Run RabbitMQ node. -%% ------------------------------------------------------------------- - -run_one_rabbitmq_node(Config) -> - CTPeers = rabbit_ct_vm_helpers:get_ct_peers(Config), - ?assertEqual([false], - [rabbit:is_running(CTPeer) || CTPeer <- CTPeers]), - RabbitMQNodes = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - ?assertEqual([true], - [rabbit:is_running(RabbitMQNode) || RabbitMQNode <- RabbitMQNodes]). - -run_four_rabbitmq_nodes(Config) -> - CTPeers = rabbit_ct_vm_helpers:get_ct_peers(Config), - ?assertEqual([false, false, false], - [rabbit:is_running(CTPeer) || CTPeer <- CTPeers]), - RabbitMQNodes = lists:sort( - rabbit_ct_broker_helpers:get_node_configs( - Config, nodename)), - ?assertEqual([true, true, true, true], - [rabbit:is_running(Node) || Node <- RabbitMQNodes]), - - ?assertEqual([true, true, true, true], - rabbit_ct_broker_helpers:rpc_all( - Config, rabbit_mnesia, is_clustered, [])), - ClusteredNodes = lists:sort( - rabbit_ct_broker_helpers:rpc( - Config, 0, rabbit_mnesia, cluster_nodes, [running])), - ?assertEqual(ClusteredNodes, RabbitMQNodes). diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/main.tf b/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/main.tf deleted file mode 100644 index d9aad6bf6b7f..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/main.tf +++ /dev/null @@ -1,78 +0,0 @@ -# vim:sw=2:et: - -provider "aws" { - region = "eu-west-1" -} - -module "direct_vms" { - source = "../direct-vms" - - instance_count = 0 - - erlang_version = var.erlang_version - erlang_git_ref = var.erlang_git_ref - elixir_version = var.elixir_version - erlang_cookie = var.erlang_cookie - erlang_nodename = var.erlang_nodename - ssh_key = var.ssh_key - upload_dirs_archive = var.upload_dirs_archive - instance_name_prefix = var.instance_name_prefix - instance_name = var.instance_name - instance_name_suffix = var.instance_name_suffix - vpc_cidr_block = var.vpc_cidr_block - files_suffix = var.files_suffix - aws_ec2_region = var.aws_ec2_region -} - -resource "aws_launch_configuration" "lc" { - name_prefix = module.direct_vms.resource_prefix - - image_id = module.direct_vms.instance_ami - instance_type = module.direct_vms.instance_type - key_name = module.direct_vms.ssh_key_name - - security_groups = module.direct_vms.security_groups - - user_data = module.direct_vms.instance_user_data - - lifecycle { - create_before_destroy = true - } -} - -resource "aws_autoscaling_group" "asg" { - name_prefix = module.direct_vms.resource_prefix - launch_configuration = aws_launch_configuration.lc.name - min_size = var.instance_count - max_size = var.instance_count - desired_capacity = var.instance_count - - vpc_zone_identifier = [module.direct_vms.subnet_id] - - tags = [ - { - key = "Name" - value = "${module.direct_vms.instance_name} (ASG)" - propagate_at_launch = true - }, - { - key = "rabbitmq-testing" - value = true - propagate_at_launch = true - }, - { - key = "rabbitmq-testing-id" - value = module.direct_vms.uuid - propagate_at_launch = true - }, - { - key = "rabbitmq-testing-suffix" - value = var.files_suffix - propagate_at_launch = true - } - ] - - lifecycle { - create_before_destroy = true - } -} diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/outputs.tf b/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/outputs.tf deleted file mode 100644 index 375f5974f371..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/outputs.tf +++ /dev/null @@ -1,5 +0,0 @@ -# vim:sw=2:et: - -output "uuid" { - value = module.direct_vms.uuid -} diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/setup-vms.sh b/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/setup-vms.sh deleted file mode 100755 index 6147c3f0f41c..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/setup-vms.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/bin/sh -# vim:sw=2:et: - -set -e - -usage() { - echo "Syntax: $(basename "$0") [-Dh] [-c ] [-e ] [-s ] [ ...]" -} - -instance_count=1 - -while getopts "c:e:Dhs:" opt; do - case $opt in - h) - usage - exit - ;; - c) - instance_count=$OPTARG - ;; - e) - elixir_version=$OPTARG - ;; - D) - destroy=yes - ;; - s) - ssh_key=$OPTARG - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - usage 1>&2 - exit 64 - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - usage 1>&2 - exit 64 - ;; - esac -done -shift $((OPTIND - 1)) - -erlang_version=$1 -if test -z "$erlang_version"; then - echo "Erlang version is required" 1>&2 - echo 1>&2 - usage - exit 64 -fi -shift - -terraform_dir=$(cd "$(dirname "$0")" && pwd) - -erlang_nodename=control -dirs_archive=dirs-archive.tar.xz -instance_name_prefix="[$(basename "$0")/$USER] " - -canonicalize_erlang_version() { - version=$1 - - case "$version" in - R[0-9]*) - echo "$version" | sed -E 's/(R[0-9]+(:?A|B)[0-9]+).*/\1/' - ;; - [0-9]*) - echo "$version" | sed -E 's/([0-9]+\.[0-9]+).*/\1/' - ;; - esac -} - -find_ssh_key() { - for file in ~/.ssh/*terraform* ~/.ssh/id_rsa ~/.ssh/id_ed25519; do - if test -f "$file" && test -f "$file.pub"; then - echo "$file" - return - fi - done -} - -list_dirs_to_upload() { - if test -z "$MAKE"; then - if gmake --version 2>&1 | grep -q "GNU Make"; then - MAKE='gmake' - elif make --version 2>&1 | grep -q "GNU Make"; then - MAKE='make' - fi - fi - - template='dirs-to-upload.XXXX' - manifest=$(mktemp -t "$template") - for dir in "$@"; do - (cd "$dir" && pwd) >> "$manifest" - "$MAKE" --no-print-directory -C "$dir" fetch-test-deps >/dev/null - cat "$dir/.erlang.mk/recursive-test-deps-list.log" >> "$manifest" - done - - sorted_manifest=$(mktemp -t "$template") - sort -u < "$manifest" > "$sorted_manifest" - - # shellcheck disable=SC2094 - while read -r dir; do - grep -q "^$dir/" "$sorted_manifest" || echo "$dir" - done < "$sorted_manifest" > "$manifest" - - tar cf - -P \ - --exclude '.terraform*' \ - --exclude 'dirs-archive-*' \ - --exclude "$erlang_nodename@*" \ - -T "$manifest" \ - | xz --threads=0 > "$dirs_archive" - - rm "$manifest" "$sorted_manifest" -} - -init_terraform() { - terraform init "$terraform_dir" -} - -start_vms() { - terraform apply \ - -auto-approve=true \ - -var="erlang_version=$erlang_branch" \ - -var="elixir_version=$elixir_version" \ - -var="erlang_cookie=$erlang_cookie" \ - -var="erlang_nodename=$erlang_nodename" \ - -var="ssh_key=$ssh_key" \ - -var="instance_count=$instance_count" \ - -var="instance_name_prefix=\"$instance_name_prefix\"" \ - -var="upload_dirs_archive=$dirs_archive" \ - "$terraform_dir" -} - -destroy_vms() { - terraform destroy \ - -auto-approve=true \ - -var="erlang_version=$erlang_branch" \ - -var="elixir_version=$elixir_version" \ - -var="erlang_cookie=$erlang_cookie" \ - -var="erlang_nodename=$erlang_nodename" \ - -var="ssh_key=$ssh_key" \ - -var="instance_count=$instance_count" \ - -var="instance_name_prefix=\"$instance_name_prefix\"" \ - -var="upload_dirs_archive=$dirs_archive" \ - "$terraform_dir" -} - -erlang_branch=$(canonicalize_erlang_version "$erlang_version") -if test -z "$erlang_branch"; then - echo "Erlang version '$erlang_version' malformed or unrecognized" 1>&2 - echo 1>&2 - usage - exit 65 -fi - -if test -z "$ssh_key"; then - ssh_key=$(find_ssh_key) -fi -if test -z "$ssh_key" || ! test -f "$ssh_key" || ! test -f "$ssh_key.pub"; then - echo "Please specify a private SSH key using '-s'" 1>&2 - echo 1>&2 - usage - exit 65 -fi - -erlang_cookie=$(cat ~/.erlang.cookie) - -list_dirs_to_upload "$@" -init_terraform - -case "$destroy" in - yes) - destroy_vms - ;; - *) - start_vms - ;; -esac diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/variables.tf b/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/variables.tf deleted file mode 100644 index 9ed1ee68fb19..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/autoscaling-group/variables.tf +++ /dev/null @@ -1,80 +0,0 @@ -# vim:sw=2:et: - -variable "erlang_version" { - description = <] [-e ] [-s ] [ ...]" -} - -instance_count=1 - -while getopts "c:e:Dhs:" opt; do - case $opt in - h) - usage - exit - ;; - c) - instance_count=$OPTARG - ;; - e) - elixir_version=$OPTARG - ;; - D) - destroy=yes - ;; - s) - ssh_key=$OPTARG - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - usage 1>&2 - exit 64 - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - usage 1>&2 - exit 64 - ;; - esac -done -shift $((OPTIND - 1)) - -erlang_version=$1 -if test -z "$erlang_version"; then - echo "Erlang version is required" 1>&2 - echo 1>&2 - usage - exit 64 -fi -shift - -terraform_dir=$(cd "$(dirname "$0")" && pwd) - -erlang_nodename=control -dirs_archive=dirs-archive.tar.xz -instance_name_prefix="[$(basename "$0")/$USER] " - -canonicalize_erlang_version() { - version=$1 - - case "$version" in - R[0-9]*) - echo "$version" | sed -E 's/(R[0-9]+(:?A|B)[0-9]+).*/\1/' - ;; - [0-9]*) - echo "$version" | sed -E 's/([0-9]+\.[0-9]+).*/\1/' - ;; - esac -} - -find_ssh_key() { - for file in ~/.ssh/*terraform* ~/.ssh/id_rsa ~/.ssh/id_ed25519; do - if test -f "$file" && test -f "$file.pub"; then - echo "$file" - return - fi - done -} - -list_dirs_to_upload() { - if test -z "$MAKE"; then - if gmake --version 2>&1 | grep -q "GNU Make"; then - MAKE='gmake' - elif make --version 2>&1 | grep -q "GNU Make"; then - MAKE='make' - fi - fi - - template='dirs-to-upload.XXXX' - manifest=$(mktemp -t "$template") - for dir in "$@"; do - (cd "$dir" && pwd) >> "$manifest" - "$MAKE" --no-print-directory -C "$dir" fetch-test-deps >/dev/null - cat "$dir/.erlang.mk/recursive-test-deps-list.log" >> "$manifest" - done - - sorted_manifest=$(mktemp -t "$template") - sort -u < "$manifest" > "$sorted_manifest" - - # shellcheck disable=SC2094 - while read -r dir; do - grep -q "^$dir/" "$sorted_manifest" || echo "$dir" - done < "$sorted_manifest" > "$manifest" - - tar cf - -P \ - --exclude '.terraform*' \ - --exclude 'dirs-archive-*' \ - --exclude "$erlang_nodename@*" \ - -T "$manifest" \ - | xz --threads=0 > "$dirs_archive" - - rm "$manifest" "$sorted_manifest" -} - -init_terraform() { - terraform init "$terraform_dir" -} - -start_vms() { - terraform apply \ - -auto-approve=true \ - -var="erlang_version=$erlang_branch" \ - -var="elixir_version=$elixir_version" \ - -var="erlang_git_ref=$erlang_git_ref" \ - -var="erlang_cookie=$erlang_cookie" \ - -var="erlang_nodename=$erlang_nodename" \ - -var="ssh_key=$ssh_key" \ - -var="instance_count=$instance_count" \ - -var="instance_name_prefix=\"$instance_name_prefix\"" \ - -var="upload_dirs_archive=$dirs_archive" \ - "$terraform_dir" -} - -destroy_vms() { - terraform destroy \ - -auto-approve=true \ - -var="erlang_version=$erlang_branch" \ - -var="elixir_version=$elixir_version" \ - -var="erlang_git_ref=$erlang_git_ref" \ - -var="erlang_cookie=$erlang_cookie" \ - -var="erlang_nodename=$erlang_nodename" \ - -var="ssh_key=$ssh_key" \ - -var="instance_count=$instance_count" \ - -var="instance_name_prefix=\"$instance_name_prefix\"" \ - -var="upload_dirs_archive=$dirs_archive" \ - "$terraform_dir" -} - -case "$erlang_version" in - *@*) - erlang_git_ref=${erlang_version#*@} - erlang_version=${erlang_version%@*} - ;; -esac - -erlang_branch=$(canonicalize_erlang_version "$erlang_version") -if test -z "$erlang_branch"; then - echo "Erlang version '$erlang_version' malformed or unrecognized" 1>&2 - echo 1>&2 - usage - exit 65 -fi - -if test -z "$ssh_key"; then - ssh_key=$(find_ssh_key) -fi -if test -z "$ssh_key" || ! test -f "$ssh_key" || ! test -f "$ssh_key.pub"; then - echo "Please specify a private SSH key using '-s'" 1>&2 - echo 1>&2 - usage - exit 65 -fi - -erlang_cookie=$(cat ~/.erlang.cookie) - -list_dirs_to_upload "$@" -init_terraform - -case "$destroy" in - yes) - destroy_vms - ;; - *) - start_vms - ;; -esac diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/templates/setup-erlang.sh b/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/templates/setup-erlang.sh deleted file mode 100644 index 8fb5a4d7088b..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/templates/setup-erlang.sh +++ /dev/null @@ -1,264 +0,0 @@ -#!/bin/sh -# vim:sw=2:et: - -set -ex - -# Execute ourselves as root if we are an unprivileged user. -if test "$(id -u)" != '0'; then - exec sudo -i "$0" "$@" -fi - -HOME=/root -export HOME - -DEBIAN_FRONTEND=noninteractive -export DEBIAN_FRONTEND - -# shellcheck disable=SC2016 -readonly erlang_version='${erlang_version}' -# shellcheck disable=SC2016 -erlang_git_ref='${erlang_git_ref}' -# shellcheck disable=SC2016 -readonly elixir_version='${elixir_version}' -# shellcheck disable=SC2016 -readonly erlang_nodename='${erlang_nodename}' -# shellcheck disable=SC2016 -readonly default_user='${default_user}' -# shellcheck disable=SC2016 -readonly dirs_archive_url='${dirs_archive_url}' -# shellcheck disable=SC2016 -readonly distribution='${distribution}' -# shellcheck disable=SC2016 -readonly erlang_cookie='${erlang_cookie}' - -readonly debian_codename="$${distribution#debian-*}" - -case "$erlang_version" in - 24.*) - if test -z "$erlang_git_ref"; then - erlang_git_ref='master' - fi - ;; - 23.*|22.*|21.*|20.*|19.3) - readonly erlang_package_version="1:$erlang_version-1" - ;; - R16B03) - readonly erlang_package_version='1:16.b.3-3' - ;; - *) - echo "[ERROR] unknown erlang version: $erlang_version" 1>&2 - exit 69 # EX_UNAVAILABLE; see sysexists(3) - ;; -esac - -install_essentials() { - apt-get -qq update - apt-get -qq install wget curl gnupg -} - -setup_backports() { - # Enable backports. - cat >/etc/apt/sources.list.d/backports.list << EOF -deb http://cdn-fastly.deb.debian.org/debian $debian_codename-backports main -EOF - apt-get -qq update -} - -# -------------------------------------------------------------------- -# Functions to take Erlang and Elixir from Debian packages. -# -------------------------------------------------------------------- - -determine_version_to_pin() { - package=$1 - min_version=$2 - - apt-cache policy "$package" | \ - awk ' -BEGIN { - version_to_pin = ""; -} -/^ ( |\*\*\*) [^ ]/ { - if ($1 == "***") { - version = $2; - } else { - version = $1; - } - - if (version_to_pin) { - exit; - } else if (match(version, /^'$min_version'([-.]|$)/)) { - version_to_pin = version; - } -} -END { - if (version_to_pin) { - print version_to_pin; - exit; - } else { - exit 1; - } -}' -} - -setup_erlang_deb_repository() { - # Setup repository to get Erlang. - wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | apt-key add - - wget -O- https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/gpg.E495BB49CC4BBE5B.key | apt-key add - - cat >/etc/apt/sources.list.d/rabbitmq-erlang.list </etc/apt/preferences.d/erlang </etc/apt/preferences.d/elixir < /etc/profile.d/erlang.sh -} - -install_kiex() { - curl -sSL https://raw.githubusercontent.com/taylor/kiex/master/install | bash -s - - mv "$HOME/.kiex" /usr/local/kiex - sed -E \ - -e 's,\\\$HOME/\.kiex,/usr/local/kiex,' \ - -e 's,\$HOME/\.kiex,/usr/local/kiex,' \ - < /usr/local/kiex/bin/kiex \ - > /usr/local/kiex/bin/kiex.patched - mv /usr/local/kiex/bin/kiex.patched /usr/local/kiex/bin/kiex - chmod a+x /usr/local/kiex/bin/kiex -} - -kiex_install_elixir() { - case "$erlang_version" in - 22.*|23.*|24.*) - url="https://github.com/elixir-lang/elixir/releases/download/v$elixir_version/Precompiled.zip" - wget -q -O/tmp/elixir.zip "$url" - - apt-get -qq install -y --no-install-recommends unzip - - mkdir -p /usr/local/elixir - (cd /usr/local/elixir && unzip -q /tmp/elixir.zip) - export PATH=/usr/local/elixir/bin:$PATH - ;; - *) - export PATH=/usr/local/kiex/bin:$PATH - latest_elixir_version=$(kiex list releases | tail -n 1 | awk '{print $1}') - kiex install $latest_elixir_version - - . /usr/local/kiex/elixirs/elixir-$latest_elixir_version.env - cat >> /etc/profile.d/erlang.sh < "$file" - chmod 400 "$file" -done -chown "$default_user" "/home/$default_user/.erlang.cookie" - -# Fetch and extract the dirs archive. -dirs_archive="/tmp/$(basename "$dirs_archive_url")" -wget -q -O"$dirs_archive" "$dirs_archive_url" -if test -s "$dirs_archive"; then - xzcat "$dirs_archive" | tar xf - -P -fi -rm -f "$dirs_archive" - -# Start an Erlang node to control the VM from Erlang. -erl -noinput -sname "$erlang_nodename" -hidden -detached diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/variables.tf b/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/variables.tf deleted file mode 100644 index d77b67228b5d..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/direct-vms/variables.tf +++ /dev/null @@ -1,147 +0,0 @@ -# vim:sw=2:et: - -variable "erlang_version" { - description = <" -} - -while getopts "h" opt; do - case $opt in - h) - usage - exit - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - usage 1>&2 - exit 64 - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - usage 1>&2 - exit 64 - ;; - esac -done -shift $((OPTIND - 1)) - -uuid=$1 -if test -z "$uuid"; then - echo "Unique ID is required" 1>&2 - echo 1>&2 - usage - exit 64 -fi -shift - -terraform_dir=$(cd "$(dirname "$0")" && pwd) - -init_terraform() { - terraform init "$terraform_dir" -} - -query_vms() { - terraform apply \ - -auto-approve=true \ - -var="uuid=$uuid" \ - -var="erlang_nodename=control" \ - "$terraform_dir" -} - -init_terraform - -query_vms diff --git a/deps/rabbitmq_ct_helpers/tools/terraform/vms-query/variables.tf b/deps/rabbitmq_ct_helpers/tools/terraform/vms-query/variables.tf deleted file mode 100644 index 422ce6d0438e..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/terraform/vms-query/variables.tf +++ /dev/null @@ -1,14 +0,0 @@ -# vim:sw=2:et: - -variable "uuid" { - description = </dev/null -openssl_output = $(openssl_output_$(V)) - -.PRECIOUS: %/testca/cacert.pem -.PHONY: all testca server client clean - -all: server client - @: - -testca: $(DIR)/testca/cacert.pem - -server: TARGET = server -server: $(DIR)/server/cert.pem - @: - -client: TARGET = client -client: $(DIR)/client/cert.pem - @: - -$(DIR)/testca/cacert.pem: - $(gen_verbose) mkdir -p $(dir $@) - $(verbose) { ( cd $(dir $@) && \ - mkdir -p certs private && \ - chmod 700 private && \ - echo 01 > serial && \ - :> index.txt && \ - sed -e 's/@HOSTNAME@/$(HOSTNAME)/g' $(CURDIR)/openssl.cnf.in > $(CURDIR)/openssl.cnf && \ - openssl req -x509 -config $(CURDIR)/openssl.cnf -newkey rsa:2048 -days 365 \ - -out cacert.pem -outform PEM -subj /CN=MyTestCA/L=$$$$/ -nodes && \ - openssl x509 -in cacert.pem -out cacert.cer -outform DER ) $(openssl_output) \ - || (rm -rf $(dir $@) && false); } - -$(DIR)/%/cert.pem: $(DIR)/testca/cacert.pem - $(gen_verbose) mkdir -p $(DIR)/$(TARGET) - $(verbose) { ( cd $(DIR)/$(TARGET) && \ - openssl genrsa -out key.pem 2048 && \ - openssl req -new -key key.pem -out req.pem -outform PEM \ - -subj /C=UK/ST=England/CN=$(HOSTNAME)/O=$(TARGET)/L=$$$$/ -nodes && \ - cd ../testca && \ - sed -e 's/@HOSTNAME@/$(HOSTNAME)/g' $(CURDIR)/openssl.cnf.in > $(CURDIR)/openssl.cnf && \ - openssl ca -config $(CURDIR)/openssl.cnf -in ../$(TARGET)/req.pem -out \ - ../$(TARGET)/cert.pem -notext -batch -extensions \ - $(TARGET)_ca_extensions && \ - cd ../$(TARGET) && \ - openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem \ - -passout pass:$(PASSWORD) ) $(openssl_output) || (rm -rf $(DIR)/$(TARGET) && false); } - -clean: - rm -rf $(DIR)/testca - rm -rf $(DIR)/server - rm -rf $(DIR)/client diff --git a/deps/rabbitmq_ct_helpers/tools/tls-certs/openssl.cnf.in b/deps/rabbitmq_ct_helpers/tools/tls-certs/openssl.cnf.in deleted file mode 100644 index ecce78ca0602..000000000000 --- a/deps/rabbitmq_ct_helpers/tools/tls-certs/openssl.cnf.in +++ /dev/null @@ -1,62 +0,0 @@ -[ ca ] -default_ca = testca - -[ testca ] -dir = . -certificate = $dir/cacert.pem -database = $dir/index.txt -new_certs_dir = $dir/certs -private_key = $dir/private/cakey.pem -serial = $dir/serial - -default_crl_days = 7 -default_days = 365 -default_md = sha256 - -policy = testca_policy -x509_extensions = certificate_extensions - -[ testca_policy ] -commonName = supplied -stateOrProvinceName = optional -countryName = optional -emailAddress = optional -organizationName = optional -organizationalUnitName = optional -domainComponent = optional - -[ certificate_extensions ] -basicConstraints = CA:false - -[ req ] -default_bits = 2048 -default_keyfile = ./private/cakey.pem -default_md = sha256 -prompt = yes -distinguished_name = root_ca_distinguished_name -x509_extensions = root_ca_extensions - -[ root_ca_distinguished_name ] -commonName = hostname -countryName_default = UK -stateOrProvinceName_default = London -organizationName_default = RabbitMQ - -[ root_ca_extensions ] -basicConstraints = CA:true -keyUsage = keyCertSign, cRLSign - -[ client_ca_extensions ] -basicConstraints = CA:false -keyUsage = digitalSignature,keyEncipherment -extendedKeyUsage = 1.3.6.1.5.5.7.3.2 - -[ server_ca_extensions ] -basicConstraints = CA:false -keyUsage = digitalSignature,keyEncipherment -extendedKeyUsage = 1.3.6.1.5.5.7.3.1 -subjectAltName = @server_alt_names - -[ server_alt_names ] -DNS.1 = @HOSTNAME@ -DNS.2 = localhost diff --git a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cacert.pem b/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cacert.pem deleted file mode 100644 index eaf6b67806ce..000000000000 --- a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cacert.pem +++ /dev/null @@ -1 +0,0 @@ -I'm not a certificate diff --git a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cert.pem b/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cert.pem deleted file mode 100644 index eaf6b67806ce..000000000000 --- a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/cert.pem +++ /dev/null @@ -1 +0,0 @@ -I'm not a certificate diff --git a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/key.pem b/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/key.pem deleted file mode 100644 index eaf6b67806ce..000000000000 --- a/deps/rabbitmq_management/test/config_schema_SUITE_data/certs/key.pem +++ /dev/null @@ -1 +0,0 @@ -I'm not a certificate diff --git a/deps/rabbitmq_management/test/config_schema_SUITE_data/rabbit-mgmt/access.log b/deps/rabbitmq_management/test/config_schema_SUITE_data/rabbit-mgmt/access.log deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/deps/rabbitmq_mqtt/test/java_SUITE_data/mvnw.cmd b/deps/rabbitmq_mqtt/test/java_SUITE_data/mvnw.cmd index a5284c79395d..fef5a8f7f988 100755 --- a/deps/rabbitmq_mqtt/test/java_SUITE_data/mvnw.cmd +++ b/deps/rabbitmq_mqtt/test/java_SUITE_data/mvnw.cmd @@ -1,161 +1,161 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management.schema b/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management.schema deleted file mode 100644 index e05da0a00106..000000000000 --- a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management.schema +++ /dev/null @@ -1,436 +0,0 @@ -%% ---------------------------------------------------------------------------- -%% RabbitMQ Management Plugin -%% -%% See https://www.rabbitmq.com/management.html for details -%% ---------------------------------------------------------------------------- - -%% Load definitions from a JSON file or directory of files. See -%% https://www.rabbitmq.com/management.html#load-definitions -%% -%% {load_definitions, "/path/to/schema.json"}, -%% {load_definitions, "/path/to/schemas"}, -{mapping, "management.load_definitions", "rabbitmq_management.load_definitions", - [{datatype, string}, - {validators, ["file_accessible"]}]}. - -%% Log all requests to the management HTTP API to a file. -%% -%% {http_log_dir, "/path/to/access.log"}, - -{mapping, "management.http_log_dir", "rabbitmq_management.http_log_dir", - [{datatype, string}]}. - -%% HTTP (TCP) listener options ======================================================== - -%% HTTP listener consistent with Web STOMP and Web MQTT. -%% -%% {tcp_config, [{port, 15672}, -%% {ip, "127.0.0.1"}]} - -{mapping, "management.tcp.port", "rabbitmq_management.tcp_config.port", - [{datatype, integer}]}. -{mapping, "management.tcp.ip", "rabbitmq_management.tcp_config.ip", - [{datatype, string}, - {validators, ["is_ip"]}]}. - -{mapping, "management.tcp.compress", "rabbitmq_management.tcp_config.cowboy_opts.compress", - [{datatype, {enum, [true, false]}}]}. -{mapping, "management.tcp.idle_timeout", "rabbitmq_management.tcp_config.cowboy_opts.idle_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.tcp.inactivity_timeout", "rabbitmq_management.tcp_config.cowboy_opts.inactivity_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.tcp.request_timeout", "rabbitmq_management.tcp_config.cowboy_opts.request_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.tcp.shutdown_timeout", "rabbitmq_management.tcp_config.cowboy_opts.shutdown_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.tcp.max_keepalive", "rabbitmq_management.tcp_config.cowboy_opts.max_keepalive", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - - -%% HTTPS (TLS) listener options ======================================================== - -%% HTTPS listener consistent with Web STOMP and Web MQTT. -%% -%% {ssl_config, [{port, 15671}, -%% {ip, "127.0.0.1"}, -%% {cacertfile, "/path/to/cacert.pem"}, -%% {certfile, "/path/to/cert.pem"}, -%% {keyfile, "/path/to/key.pem"}]} - -{mapping, "management.ssl.port", "rabbitmq_management.ssl_config.port", - [{datatype, integer}]}. -{mapping, "management.ssl.backlog", "rabbitmq_management.ssl_config.backlog", - [{datatype, integer}]}. -{mapping, "management.ssl.ip", "rabbitmq_management.ssl_config.ip", - [{datatype, string}, {validators, ["is_ip"]}]}. -{mapping, "management.ssl.certfile", "rabbitmq_management.ssl_config.certfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "management.ssl.keyfile", "rabbitmq_management.ssl_config.keyfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "management.ssl.cacertfile", "rabbitmq_management.ssl_config.cacertfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "management.ssl.password", "rabbitmq_management.ssl_config.password", - [{datatype, string}]}. - -{mapping, "management.ssl.verify", "rabbitmq_management.ssl_config.verify", [ - {datatype, {enum, [verify_peer, verify_none]}}]}. - -{mapping, "management.ssl.fail_if_no_peer_cert", "rabbitmq_management.ssl_config.fail_if_no_peer_cert", [ - {datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.honor_cipher_order", "rabbitmq_management.ssl_config.honor_cipher_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.honor_ecc_order", "rabbitmq_management.ssl_config.honor_ecc_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.reuse_sessions", "rabbitmq_management.ssl_config.reuse_sessions", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.secure_renegotiate", "rabbitmq_management.ssl_config.secure_renegotiate", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.client_renegotiation", "rabbitmq_management.ssl_config.client_renegotiation", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.ssl.depth", "rabbitmq_management.ssl_config.depth", - [{datatype, integer}, {validators, ["byte"]}]}. - -{mapping, "management.ssl.versions.$version", "rabbitmq_management.ssl_config.versions", - [{datatype, atom}]}. - -{translation, "rabbitmq_management.ssl_config.versions", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("management.ssl.versions", Conf), - [V || {_, V} <- Settings] -end}. - -{mapping, "management.ssl.ciphers.$cipher", "rabbitmq_management.ssl_config.ciphers", - [{datatype, string}]}. - -{translation, "rabbitmq_management.ssl_config.ciphers", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("management.ssl.ciphers", Conf), - lists:reverse([V || {_, V} <- Settings]) -end}. - -{mapping, "management.ssl.compress", "rabbitmq_management.ssl_config.cowboy_opts.compress", - [{datatype, {enum, [true, false]}}]}. -{mapping, "management.ssl.idle_timeout", "rabbitmq_management.ssl_config.cowboy_opts.idle_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.ssl.inactivity_timeout", "rabbitmq_management.ssl_config.cowboy_opts.inactivity_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.ssl.request_timeout", "rabbitmq_management.ssl_config.cowboy_opts.request_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.ssl.shutdown_timeout", "rabbitmq_management.ssl_config.cowboy_opts.shutdown_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "management.ssl.max_keepalive", "rabbitmq_management.ssl_config.cowboy_opts.max_keepalive", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - - - -%% Legacy listener options ======================================================== - -%% Legacy (pre-3.7.9) TCP listener format. -%% -%% {listener, [{port, 12345}, -%% {ip, "127.0.0.1"}, -%% {ssl, true}, -%% {ssl_opts, [{cacertfile, "/path/to/cacert.pem"}, -%% {certfile, "/path/to/cert.pem"}, -%% {keyfile, "/path/to/key.pem"}]}]}, - -{mapping, "management.listener.port", "rabbitmq_management.listener.port", - [{datatype, integer}]}. - -{mapping, "management.listener.ip", "rabbitmq_management.listener.ip", - [{datatype, string}, - {validators, ["is_ip"]}]}. - -{mapping, "management.listener.ssl", "rabbitmq_management.listener.ssl", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.server.compress", "rabbitmq_management.listener.cowboy_opts.compress", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.server.idle_timeout", "rabbitmq_management.listener.cowboy_opts.idle_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - -{mapping, "management.listener.server.inactivity_timeout", "rabbitmq_management.listener.cowboy_opts.inactivity_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - -{mapping, "management.listener.server.request_timeout", "rabbitmq_management.listener.cowboy_opts.request_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - -{mapping, "management.listener.server.shutdown_timeout", "rabbitmq_management.listener.cowboy_opts.shutdown_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - -{mapping, "management.listener.server.max_keepalive", "rabbitmq_management.listener.cowboy_opts.max_keepalive", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - -%% Legacy HTTPS listener options ======================================================== - -{mapping, "management.listener.ssl_opts", "rabbitmq_management.listener.ssl_opts", [ - {datatype, {enum, [none]}} -]}. - -{translation, "rabbitmq_management.listener.ssl_opts", -fun(Conf) -> - case cuttlefish:conf_get("management.listener.ssl_opts", Conf, undefined) of - none -> []; - _ -> cuttlefish:invalid("Invalid management.listener.ssl_opts") - end -end}. - -{mapping, "management.listener.ssl_opts.verify", "rabbitmq_management.listener.ssl_opts.verify", [ - {datatype, {enum, [verify_peer, verify_none]}}]}. - -{mapping, "management.listener.ssl_opts.fail_if_no_peer_cert", "rabbitmq_management.listener.ssl_opts.fail_if_no_peer_cert", [ - {datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.cacertfile", "rabbitmq_management.listener.ssl_opts.cacertfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. - -{mapping, "management.listener.ssl_opts.certfile", "rabbitmq_management.listener.ssl_opts.certfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. - -{mapping, "management.listener.ssl_opts.cacerts.$name", "rabbitmq_management.listener.ssl_opts.cacerts", - [{datatype, string}]}. - -{translation, "rabbitmq_management.listener.ssl_opts.cacerts", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.cacerts", Conf), - [ list_to_binary(V) || {_, V} <- Settings ] -end}. - -{mapping, "management.listener.ssl_opts.honor_cipher_order", "rabbitmq_management.listener.ssl_opts.honor_cipher_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.honor_ecc_order", "rabbitmq_management.listener.ssl_opts.honor_ecc_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.reuse_sessions", "rabbitmq_management.listener.ssl_opts.reuse_sessions", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.secure_renegotiate", "rabbitmq_management.listener.ssl_opts.secure_renegotiate", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.client_renegotiation", "rabbitmq_management.listener.ssl_opts.client_renegotiation", - [{datatype, {enum, [true, false]}}]}. - - -{mapping, "management.listener.ssl_opts.versions.$version", "rabbitmq_management.listener.ssl_opts.versions", - [{datatype, atom}]}. - -{translation, "rabbitmq_management.listener.ssl_opts.versions", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.versions", Conf), - [ V || {_, V} <- Settings ] -end}. - - -{mapping, "management.listener.ssl_opts.cert", "rabbitmq_management.listener.ssl_opts.cert", - [{datatype, string}]}. - -{translation, "rabbitmq_management.listener.ssl_opts.cert", -fun(Conf) -> - list_to_binary(cuttlefish:conf_get("management.listener.ssl_opts.cert", Conf)) -end}. - -{mapping, "management.listener.ssl_opts.crl_check", "rabbitmq_management.listener.ssl_opts.crl_check", - [{datatype, [{enum, [true, false, peer, best_effort]}]}]}. - -{mapping, "management.listener.ssl_opts.depth", "rabbitmq_management.listener.ssl_opts.depth", - [{datatype, integer}, {validators, ["byte"]}]}. - -{mapping, "management.listener.ssl_opts.dh", "rabbitmq_management.listener.ssl_opts.dh", - [{datatype, string}]}. - -{translation, "rabbitmq_management.listener.ssl_opts.dh", -fun(Conf) -> - list_to_binary(cuttlefish:conf_get("management.listener.ssl_opts.dh", Conf)) -end}. - -{mapping, "management.listener.ssl_opts.dhfile", "rabbitmq_management.listener.ssl_opts.dhfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. - -{mapping, "management.listener.ssl_opts.key.RSAPrivateKey", "rabbitmq_management.listener.ssl_opts.key", - [{datatype, string}]}. - -{mapping, "management.listener.ssl_opts.key.DSAPrivateKey", "rabbitmq_management.listener.ssl_opts.key", - [{datatype, string}]}. - -{mapping, "management.listener.ssl_opts.key.PrivateKeyInfo", "rabbitmq_management.listener.ssl_opts.key", - [{datatype, string}]}. - -{translation, "rabbitmq_management.listener.ssl_opts.key", -fun(Conf) -> - case cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.key", Conf) of - [{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)}; - _ -> undefined - end -end}. - -{mapping, "management.listener.ssl_opts.keyfile", "rabbitmq_management.listener.ssl_opts.keyfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. - -{mapping, "management.listener.ssl_opts.log_alert", "rabbitmq_management.listener.ssl_opts.log_alert", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.listener.ssl_opts.password", "rabbitmq_management.listener.ssl_opts.password", - [{datatype, string}]}. - -{mapping, "management.listener.ssl_opts.psk_identity", "rabbitmq_management.listener.ssl_opts.psk_identity", - [{datatype, string}]}. - - -%% A custom path prefix for all HTTP request handlers. -%% -%% {path_prefix, "/a/prefix"}, - -{mapping, "management.path_prefix", "rabbitmq_management.path_prefix", - [{datatype, string}]}. - -%% Login session timeout in minutes - -{mapping, "management.login_session_timeout", "rabbitmq_management.login_session_timeout", [ - {datatype, integer}, {validators, ["non_negative_integer"]} -]}. - -%% CORS - -{mapping, "management.cors.allow_origins", "rabbitmq_management.cors_allow_origins", [ - {datatype, {enum, [none]}} -]}. - -{mapping, "management.cors.allow_origins.$name", "rabbitmq_management.cors_allow_origins", [ - {datatype, string} -]}. - -{translation, "rabbitmq_management.cors_allow_origins", -fun(Conf) -> - case cuttlefish:conf_get("management.cors.allow_origins", Conf, undefined) of - none -> []; - _ -> - Settings = cuttlefish_variable:filter_by_prefix("management.cors.allow_origins", Conf), - [V || {_, V} <- Settings] - end -end}. - - -{mapping, "management.cors.max_age", "rabbitmq_management.cors_max_age", [ - {datatype, integer}, {validators, ["non_negative_integer"]} -]}. - -{translation, "rabbitmq_management.cors_max_age", -fun(Conf) -> - case cuttlefish:conf_get("management.cors.max_age", Conf, undefined) of - undefined -> cuttlefish:unset(); - Value -> Value - end -end}. - - -%% CSP (https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) - -{mapping, "management.csp.policy", "rabbitmq_management.content_security_policy", [ - {datatype, string} -]}. - -{translation, "rabbitmq_management.content_security_policy", -fun(Conf) -> - case cuttlefish:conf_get("management.csp.policy", Conf, undefined) of - undefined -> cuttlefish:unset(); - Value -> Value - end -end}. - - -%% HSTS (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) - -{mapping, "management.hsts.policy", "rabbitmq_management.strict_transport_security", [ - {datatype, string} -]}. - -{translation, "rabbitmq_management.strict_transport_security", -fun(Conf) -> - case cuttlefish:conf_get("management.hsts.policy", Conf, undefined) of - undefined -> cuttlefish:unset(); - Value -> Value - end -end}. - -%% OAuth 2/SSO access only - -{mapping, "management.disable_basic_auth", "rabbitmq_management.disable_basic_auth", - [{datatype, {enum, [true, false]}}]}. - -%% Management only - -{mapping, "management.disable_stats", "rabbitmq_management.disable_management_stats", [ - {datatype, {enum, [true, false]}} -]}. - -{mapping, "management.enable_queue_totals", "rabbitmq_management.enable_queue_totals", [ - {datatype, {enum, [true, false]}}]}. - -%% =========================================================================== -%% Authorization - -{mapping, "management.enable_uaa", "rabbitmq_management.enable_uaa", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "management.uaa_client_id", "rabbitmq_management.uaa_client_id", - [{datatype, string}]}. - -{mapping, "management.uaa_location", "rabbitmq_management.uaa_location", - [{datatype, string}]}. - -%% =========================================================================== - - -%% One of 'basic', 'detailed' or 'none'. See -%% https://www.rabbitmq.com/management.html#fine-stats for more details. -%% {rates_mode, basic}, -{mapping, "management.rates_mode", "rabbitmq_management.rates_mode", - [{datatype, {enum, [basic, detailed, none]}}]}. - -%% Configure how long aggregated data (such as message rates and queue -%% lengths) is retained. Please read the plugin's documentation in -%% https://www.rabbitmq.com/management.html#configuration for more -%% details. -%% -%% {sample_retention_policies, -%% [{global, [{60, 5}, {3600, 60}, {86400, 1200}]}, -%% {basic, [{60, 5}, {3600, 60}]}, -%% {detailed, [{10, 5}]}]} -% ]}, - -{mapping, "management.sample_retention_policies.$section.$interval", - "rabbitmq_management.sample_retention_policies", - [{datatype, integer}]}. - -{translation, "rabbitmq_management.sample_retention_policies", -fun(Conf) -> - Global = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.global", Conf), - Basic = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.basic", Conf), - Detailed = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.detailed", Conf), - TranslateKey = fun("minute") -> 60; - ("hour") -> 3600; - ("day") -> 86400; - (Other) -> list_to_integer(Other) - end, - TranslatePolicy = fun(Section) -> - [ {TranslateKey(Key), Val} || {[_,_,_,Key], Val} <- Section ] - end, - [{global, TranslatePolicy(Global)}, - {basic, TranslatePolicy(Basic)}, - {detailed, TranslatePolicy(Detailed)}] -end}. - - -{validator, "is_dir", "is not directory", -fun(File) -> - ReadFile = file:list_dir(File), - element(1, ReadFile) == ok -end}. diff --git a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management_agent.schema b/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management_agent.schema deleted file mode 100644 index fa8a76725a47..000000000000 --- a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_management_agent.schema +++ /dev/null @@ -1,4 +0,0 @@ -%% Agent collectors won't start if metrics collection is disabled, only external stats are enabled. -%% Also the management application will refuse to start if metrics collection is disabled -{mapping, "management_agent.disable_metrics_collector", "rabbitmq_management_agent.disable_metrics_collector", - [{datatype, {enum, [true, false]}}]}. diff --git a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_prometheus.schema b/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_prometheus.schema deleted file mode 100644 index 4f1028a2a6bb..000000000000 --- a/deps/rabbitmq_prometheus/test/config_schema_SUITE_data/schema/rabbitmq_prometheus.schema +++ /dev/null @@ -1,116 +0,0 @@ -%% ---------------------------------------------------------------------------- -%% RabbitMQ Prometheus Plugin -%% -%% See https://rabbitmq.com/prometheus.html for details -%% ---------------------------------------------------------------------------- - -%% Endpoint path -{mapping, "prometheus.path", "rabbitmq_prometheus.path", - [{datatype, string}]}. - -%% HTTP (TCP) listener options ======================================================== - -%% HTTP listener consistent with the management plugin, Web STOMP and Web MQTT. -%% -%% {tcp_config, [{port, 15692}, -%% {ip, "127.0.0.1"}]} - -{mapping, "prometheus.tcp.port", "rabbitmq_prometheus.tcp_config.port", - [{datatype, integer}]}. -{mapping, "prometheus.tcp.ip", "rabbitmq_prometheus.tcp_config.ip", - [{datatype, string}, - {validators, ["is_ip"]}]}. - -{mapping, "prometheus.tcp.compress", "rabbitmq_prometheus.tcp_config.cowboy_opts.compress", - [{datatype, {enum, [true, false]}}]}. -{mapping, "prometheus.tcp.idle_timeout", "rabbitmq_prometheus.tcp_config.cowboy_opts.idle_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.tcp.inactivity_timeout", "rabbitmq_prometheus.tcp_config.cowboy_opts.inactivity_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.tcp.request_timeout", "rabbitmq_prometheus.tcp_config.cowboy_opts.request_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.tcp.shutdown_timeout", "rabbitmq_prometheus.tcp_config.cowboy_opts.shutdown_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.tcp.max_keepalive", "rabbitmq_prometheus.tcp_config.cowboy_opts.max_keepalive", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. - - -%% HTTPS (TLS) listener options ======================================================== - -%% HTTPS listener consistent with the management plugin, Web STOMP and Web MQTT. -%% -%% {ssl_config, [{port, 15691}, -%% {ip, "127.0.0.1"}, -%% {cacertfile, "/path/to/cacert.pem"}, -%% {certfile, "/path/to/cert.pem"}, -%% {keyfile, "/path/to/key.pem"}]} - -{mapping, "prometheus.ssl.port", "rabbitmq_prometheus.ssl_config.port", - [{datatype, integer}]}. -{mapping, "prometheus.ssl.backlog", "rabbitmq_prometheus.ssl_config.backlog", - [{datatype, integer}]}. -{mapping, "prometheus.ssl.ip", "rabbitmq_prometheus.ssl_config.ip", - [{datatype, string}, {validators, ["is_ip"]}]}. -{mapping, "prometheus.ssl.certfile", "rabbitmq_prometheus.ssl_config.certfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "prometheus.ssl.keyfile", "rabbitmq_prometheus.ssl_config.keyfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "prometheus.ssl.cacertfile", "rabbitmq_prometheus.ssl_config.cacertfile", - [{datatype, string}, {validators, ["file_accessible"]}]}. -{mapping, "prometheus.ssl.password", "rabbitmq_prometheus.ssl_config.password", - [{datatype, string}]}. - -{mapping, "prometheus.ssl.verify", "rabbitmq_prometheus.ssl_config.verify", [ - {datatype, {enum, [verify_peer, verify_none]}}]}. - -{mapping, "prometheus.ssl.fail_if_no_peer_cert", "rabbitmq_prometheus.ssl_config.fail_if_no_peer_cert", [ - {datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.honor_cipher_order", "rabbitmq_prometheus.ssl_config.honor_cipher_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.honor_ecc_order", "rabbitmq_prometheus.ssl_config.honor_ecc_order", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.reuse_sessions", "rabbitmq_prometheus.ssl_config.reuse_sessions", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.secure_renegotiate", "rabbitmq_prometheus.ssl_config.secure_renegotiate", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.client_renegotiation", "rabbitmq_prometheus.ssl_config.client_renegotiation", - [{datatype, {enum, [true, false]}}]}. - -{mapping, "prometheus.ssl.depth", "rabbitmq_prometheus.ssl_config.depth", - [{datatype, integer}, {validators, ["byte"]}]}. - -{mapping, "prometheus.ssl.versions.$version", "rabbitmq_prometheus.ssl_config.versions", - [{datatype, atom}]}. - -{translation, "rabbitmq_prometheus.ssl_config.versions", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("prometheus.ssl.versions", Conf), - [V || {_, V} <- Settings] -end}. - -{mapping, "prometheus.ssl.ciphers.$cipher", "rabbitmq_prometheus.ssl_config.ciphers", - [{datatype, string}]}. - -{translation, "rabbitmq_prometheus.ssl_config.ciphers", -fun(Conf) -> - Settings = cuttlefish_variable:filter_by_prefix("prometheus.ssl.ciphers", Conf), - lists:reverse([V || {_, V} <- Settings]) -end}. - -{mapping, "prometheus.ssl.compress", "rabbitmq_prometheus.ssl_config.cowboy_opts.compress", - [{datatype, {enum, [true, false]}}]}. -{mapping, "prometheus.ssl.idle_timeout", "rabbitmq_prometheus.ssl_config.cowboy_opts.idle_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.ssl.inactivity_timeout", "rabbitmq_prometheus.ssl_config.cowboy_opts.inactivity_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.ssl.request_timeout", "rabbitmq_prometheus.ssl_config.cowboy_opts.request_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.ssl.shutdown_timeout", "rabbitmq_prometheus.ssl_config.cowboy_opts.shutdown_timeout", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. -{mapping, "prometheus.ssl.max_keepalive", "rabbitmq_prometheus.ssl_config.cowboy_opts.max_keepalive", - [{datatype, integer}, {validators, ["non_negative_integer"]}]}. diff --git a/deps/rabbitmq_stream/test/rabbit_stream_SUITE_data/.mvn/wrapper/maven-wrapper.jar b/deps/rabbitmq_stream/test/rabbit_stream_SUITE_data/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 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 EfAhh=DF6Tf diff --git a/deps/rabbitmq_stream_management/test/http_SUITE_data/.mvn/wrapper/maven-wrapper.jar b/deps/rabbitmq_stream_management/test/http_SUITE_data/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 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 EfAhh=DF6Tf diff --git a/deps/rabbitmq_tracing/priv/www/js/tmpl/traces.ejs b/deps/rabbitmq_tracing/priv/www/js/tmpl/traces.ejs deleted file mode 100644 index 4c1244c6ddd5..000000000000 --- a/deps/rabbitmq_tracing/priv/www/js/tmpl/traces.ejs +++ /dev/null @@ -1,174 +0,0 @@ -

Traces: <%= node.name %>

-

- Node: - -

- -
-

All traces

-
- - - - - -
-

Currently running traces

- <% if (traces.length > 0) { %> - - - - <% if (vhosts_interesting) { %> - - <% } %> - - - - - - - - - - - - <% - for (var i = 0; i < traces.length; i++) { - var trace = traces[i]; - %> - > - <% if (vhosts_interesting) { %> - - <% } %> - - - - - <% if (trace.queue) { %> - - - <% } else { %> - - <% } %> - - - - <% } %> - -
Virtual hostNamePatternFormatPayload limitRateQueuedTracer connection username
<%= fmt_string(trace.vhost) %><%= fmt_string(trace.name) %><%= fmt_string(trace.pattern) %><%= fmt_string(trace.format) %><%= fmt_string(trace.max_payload_bytes, 'Unlimited') %> - <%= fmt_detail_rate(trace.queue.message_stats, 'deliver_no_ack') %> - - <%= trace.queue.messages %> - <%= link_trace_queue(trace) %> - -
FAILED
-
<%= fmt_string(trace.tracer_connection_username) %> -
- - - -
-
- <% } else { %> -

... no traces running ...

- <% } %> -
-

Trace log files

- <% if (files.length > 0) { %> - - - - - - - - - - <% - for (var i = 0; i < files.length; i++) { - var file = files[i]; - %> - > - - - - - <% } %> - -
NameSize
<%= link_trace(node.name, file.name) %><%= fmt_bytes(file.size) %> -
- - -
-
- <% } else { %> -

... no files ...

- <% } %> -
-
-
- -
-

Add a new trace

-
-
- -<% if (vhosts_interesting) { %> - - - - -<% } else { %> - -<% } %> - - - - - - - - - - - - - - - - - - - - - - -
- -
*
- -
-
- -
-
- -
- - Examples: #, publish.#, deliver.# #.amq.direct, #.myqueue -
- -
-
-
diff --git a/release-notes/3.10.0.md b/release-notes/3.10.0.md index 4c67806a38b1..016e4edfe961 100644 --- a/release-notes/3.10.0.md +++ b/release-notes/3.10.0.md @@ -283,6 +283,16 @@ This release includes all applicable [bug fixes that shipped in `3.9.x` releases #### Enhancements + * The plugin now supports scope aliases. In some environments, it's unrealistic to + adopt JWTs that follow the `scope` convention assumed by the plugin. Instead, + identity services fill `scope` or `claims` field with a "role name" or "role alias" + that implicitly maps to a set of scopes/permissions. + + With this feature, RabbitMQ operators can map those values to a set of + scopes that can be translated to RabbitMQ permissions. + + GitHub issue: [#4588](https://github.com/rabbitmq/rabbitmq-server/issues/4588) + * Improvements to JKW support and new HTTPS settings. Contributed by @anhanhnguyen (Erlang Solutions).