diff options
| author | Luke Bakken <lbakken@pivotal.io> | 2017-06-20 15:01:58 -0700 |
|---|---|---|
| committer | Luke Bakken <lbakken@pivotal.io> | 2017-06-20 15:01:58 -0700 |
| commit | 59ce657abcdbbed66799f466792657709baae37d (patch) | |
| tree | a98982fb337c24aef536955fb31f3afa1a41a524 | |
| parent | dd18cf3540bc4e87b4a5d586a6c88a4bf8b88874 (diff) | |
| parent | 72415b1c9446db5ad38b7d70a45fec6942682ec0 (diff) | |
| download | rabbitmq-server-git-59ce657abcdbbed66799f466792657709baae37d.tar.gz | |
Merge branch 'master' into rabbitmq-server-1246-master
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | docs/rabbitmqctl.8 | 94 | ||||
| -rw-r--r-- | priv/schema/rabbit.schema (renamed from priv/schema/rabbitmq.schema) | 8 | ||||
| -rw-r--r-- | scripts/rabbitmq-env.bat | 3 | ||||
| -rwxr-xr-x | scripts/rabbitmq-server | 4 | ||||
| -rw-r--r-- | scripts/rabbitmq-server.bat | 4 | ||||
| -rw-r--r-- | scripts/rabbitmq-service.bat | 4 | ||||
| -rw-r--r-- | src/rabbit.erl | 2 | ||||
| -rw-r--r-- | src/rabbit_node_monitor.erl | 40 | ||||
| -rw-r--r-- | src/rabbit_vm.erl | 125 | ||||
| -rw-r--r-- | src/term_to_binary_compat.erl | 13 | ||||
| -rw-r--r-- | src/vm_memory_monitor.erl | 13 | ||||
| -rw-r--r-- | test/config_schema_SUITE_data/rabbit.snippets | 12 | ||||
| -rw-r--r-- | test/partitions_SUITE.erl | 38 | ||||
| -rw-r--r-- | test/term_to_binary_compat_prop_SUITE.erl | 59 | ||||
| -rw-r--r-- | test/topic_permission_SUITE.erl | 32 |
16 files changed, 386 insertions, 68 deletions
@@ -16,6 +16,7 @@ define PROJECT_ENV {ssl_options, []}, {vm_memory_high_watermark, 0.4}, {vm_memory_high_watermark_paging_ratio, 0.5}, + {vm_memory_calculation_strategy, rss}, {memory_monitor_interval, 2500}, {disk_free_limit, 50000000}, %% 50MB {msg_store_index_module, rabbit_msg_store_ets_index}, @@ -125,7 +126,7 @@ define PROJECT_ENV ] endef -LOCAL_DEPS = sasl mnesia os_mon +LOCAL_DEPS = sasl mnesia os_mon inets BUILD_DEPS = rabbitmq_cli DEPS = ranch lager rabbit_common TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client meck proper diff --git a/docs/rabbitmqctl.8 b/docs/rabbitmqctl.8 index e12f6f496f..91b99560d6 100644 --- a/docs/rabbitmqctl.8 +++ b/docs/rabbitmqctl.8 @@ -784,6 +784,100 @@ has been granted access, and the permissions the user has for operations on resources in these virtual hosts: .sp .Dl rabbitmqctl list_user_permissions tonyg +.\" ------------------------------------ +.It Cm set_topic_permissions Oo Fl p Ar vhost Oc Ar user Ar exchange Ar write Ar read +.Bl -tag -width Ds +.It Ar vhost +The name of the virtual host to which to grant the user access, +defaulting to +.Qq / . +.It Ar user +The name of the user the permissions apply to in the target virtual host. +.It Ar exchange +The name of the topic exchange the authorisation check will be applied to. +.It Ar write +A regular expression matching the routing key of the published message. +.It Ar read +A regular expression matching the routing key of the consumed message. +.El +.Pp +Sets user topic permissions. +.Pp +For example, this command instructs the RabbitMQ broker to let the +user named +.Qq tonyg +publish and consume messages going through the +.Qq amp.topic +exchange of the +.Qq /myvhost +virtual host with a routing key starting with +.Qq tonyg- : +.sp +.Dl rabbitmqctl set_topic_permissions -p /myvhost tonyg amq.topic Qo ^tonyg-.* Qc Qo ^tonyg-.* Qc +.Pp +Topic permissions support variable expansion for the following variables: +username, vhost, and client_id. Note that client_id is expanded only when using MQTT. +The previous example could be made more generic by using +.Qq ^{username}-.* : +.sp +.Dl rabbitmqctl set_topic_permissions -p /myvhost tonyg amq.topic Qo ^{username}-.* Qc Qo ^{username}-.* Qc +.\" ------------------------------------ +.It Cm clear_topic_permissions Oo Fl p Ar vhost Oc Ar username Oo Ar exchange Oc +.Bl -tag -width Ds +.It Ar vhost +The name of the virtual host to which to clear the topic permissions, +defaulting to +.Qq / . +.It Ar username +The name of the user to clear topic permissions to the specified virtual host. +.It Ar exchange +The name of the topic exchange to clear topic permissions, defaulting to all the +topic exchanges the given user has topic permissions for. +.El +.Pp +Clear user topic permissions. +.Pp +For example, this command instructs the RabbitMQ broker to remove topic permissions for user +named +.Qq tonyg +for the topic exchange +.Qq amq.topic +in the virtual host called +.Qq /myvhost : +.sp +.Dl rabbitmqctl clear_topic_permissions -p /myvhost tonyg amq.topic +.\" ------------------------------------ +.It Cm list_topic_permissions Op Fl p Ar vhost +.Bl -tag -width Ds +.It Ar vhost +The name of the virtual host for which to list the users topic permissions. +Defaults to +.Qq / . +.El +.Pp +Lists topic permissions in a virtual host. +.Pp +For example, this command instructs the RabbitMQ broker to list all the +users which have been granted topic permissions in the virtual host called +.Qq /myvhost: +.sp +.Dl rabbitmqctl list_topic_permissions -p /myvhost +.\" ------------------------------------ +.It Cm list_user_topic_permissions Ar username +.Bl -tag -width Ds +.It Ar username +The name of the user for which to list the topic permissions. +.El +.Pp +Lists user topic permissions. +.Pp +For example, this command instructs the RabbitMQ broker to list all the +virtual hosts to which the user named +.Qq tonyg +has been granted access, and the topic permissions the user has in these virtual hosts: +.sp +.Dl rabbitmqctl list_topic_user_permissions tonyg + .El .Ss Parameter Management Certain features of RabbitMQ (such as the federation plugin) are diff --git a/priv/schema/rabbitmq.schema b/priv/schema/rabbit.schema index 985c77b9a8..e3eff6fb59 100644 --- a/priv/schema/rabbitmq.schema +++ b/priv/schema/rabbit.schema @@ -683,6 +683,14 @@ end}. {mapping, "memory_monitor_interval", "rabbit.memory_monitor_interval", [{datatype, integer}]}. +%% When set to rss, RabbitMQ will display the memory usage as reported +%% by the operating system (RSS value), not by the Erlang VM. +%% +%% {vm_memory_calculation_strategy, rss}, + +{mapping, "vm_memory_calculation_strategy", "rabbit.vm_memory_calculation_strategy", + [{datatype, {enum, [rss, erlang]}}]}. + %% Set disk free limit (in bytes). Once free disk space reaches this %% lower bound, a disk alarm will be set - see the documentation %% listed above for more details. diff --git a/scripts/rabbitmq-env.bat b/scripts/rabbitmq-env.bat index 9d7a724318..e3fddbb3eb 100644 --- a/scripts/rabbitmq-env.bat +++ b/scripts/rabbitmq-env.bat @@ -202,7 +202,6 @@ if "!RABBITMQ_SCHEMA_DIR!" == "" ( )
)
-
REM [ "x" = "x$RABBITMQ_LOG_BASE" ] && RABBITMQ_LOG_BASE=${LOG_BASE}
if "!RABBITMQ_LOG_BASE!"=="" (
if "!LOG_BASE!"=="" (
@@ -418,7 +417,7 @@ exit /b :filter_path
REM Ensure ERL_LIBS begins with valid path
-IF [%ERL_LIBS%] EQU [] (
+IF "%ERL_LIBS%"=="" (
set ERL_LIBS=%~dps1%~n1%~x1
) else (
set ERL_LIBS=%ERL_LIBS%;%~dps1%~n1%~x1
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index a318b55d75..d307e79138 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -115,8 +115,8 @@ if [ ! -d ${RABBITMQ_GENERATED_CONFIG_DIR} ]; then mkdir -p "${RABBITMQ_GENERATED_CONFIG_DIR}" fi -if [ ! -f "${RABBITMQ_SCHEMA_DIR}/rabbitmq.schema" ]; then - cp "${RABBITMQ_HOME}/priv/schema/rabbitmq.schema" "${RABBITMQ_SCHEMA_DIR}" +if [ ! -f "${RABBITMQ_SCHEMA_DIR}/rabbit.schema" ]; then + cp "${RABBITMQ_HOME}/priv/schema/rabbit.schema" "${RABBITMQ_SCHEMA_DIR}" fi set -e diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat index de25f95bdf..ea417dcad4 100644 --- a/scripts/rabbitmq-server.bat +++ b/scripts/rabbitmq-server.bat @@ -79,8 +79,8 @@ if not exist "!RABBITMQ_GENERATED_CONFIG_DIR!" ( mkdir "!RABBITMQ_GENERATED_CONFIG_DIR!"
)
-if not exist "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema" (
- copy "!RABBITMQ_HOME!\priv\schema\rabbitmq.schema" "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema"
+if not exist "!RABBITMQ_SCHEMA_DIR!\rabbit.schema" (
+ copy "!RABBITMQ_HOME!\priv\schema\rabbit.schema" "!RABBITMQ_SCHEMA_DIR!\rabbit.schema"
)
set RABBITMQ_EBIN_PATH="-pa !RABBITMQ_EBIN_ROOT!"
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat index 624d18d913..2f118205ab 100644 --- a/scripts/rabbitmq-service.bat +++ b/scripts/rabbitmq-service.bat @@ -165,8 +165,8 @@ if not exist "!RABBITMQ_GENERATED_CONFIG_DIR!" ( mkdir "!RABBITMQ_GENERATED_CONFIG_DIR!"
)
-if not exist "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema" (
- copy "!RABBITMQ_HOME!\priv\schema\rabbitmq.schema" "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema"
+if not exist "!RABBITMQ_SCHEMA_DIR!\rabbit.schema" (
+ copy "!RABBITMQ_HOME!\priv\schema\rabbit.schema" "!RABBITMQ_SCHEMA_DIR!\rabbit.schema"
)
REM Try to create advanced config file, if it doesn't exist
REM It still can fail to be created, but at least not for default install
diff --git a/src/rabbit.erl b/src/rabbit.erl index 26a69ddeea..138d03f051 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -624,7 +624,7 @@ decrypt_list([Value|Tail], Algo, Acc) -> stop_apps(Apps) -> rabbit_log:info( - lists:flatten(["Stopping RabbitMQ applications and their dependencies in the following order: ~n", + lists:flatten(["Stopping RabbitMQ applications and their dependencies in the following order:~n", [" ~p~n" || _ <- Apps]]), lists:reverse(Apps)), ok = app_utils:stop_applications( diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl index 0eadf0ff59..810df2d1fc 100644 --- a/src/rabbit_node_monitor.erl +++ b/src/rabbit_node_monitor.erl @@ -344,8 +344,8 @@ init([]) -> Nodes = possibly_partitioned_nodes(), startup_log(Nodes), Monitors = lists:foldl(fun(Node, Monitors0) -> - pmon:monitor({rabbit, Node}, Monitors0) - end, pmon:new(), Nodes), + pmon:monitor({rabbit, Node}, Monitors0) + end, pmon:new(), Nodes), {ok, ensure_keepalive_timer(#state{monitors = Monitors, subscribers = pmon:new(), partitions = [], @@ -420,12 +420,12 @@ handle_cast({check_partial_partition, Node, Rep, NodeGUID, MyGUID, RepGUID}, fun () -> case rpc:call(Node, rabbit, is_running, []) of {badrpc, _} -> ok; - _ -> - rabbit_log:warning("Received a 'DOWN' message" - " from ~p but still can" - " communicate with it ~n", - [Node]), - cast(Rep, {partial_partition, + _ -> + rabbit_log:warning("Received a 'DOWN' message" + " from ~p but still can" + " communicate with it ~n", + [Node]), + cast(Rep, {partial_partition, Node, node(), RepGUID}) end end); @@ -499,18 +499,18 @@ handle_cast({node_up, Node, NodeType}, rabbit_log:info("rabbit on node ~p up~n", [Node]), {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), write_cluster_status({add_node(Node, AllNodes), - case NodeType of - disc -> add_node(Node, DiscNodes); - ram -> DiscNodes - end, - add_node(Node, RunningNodes)}), + case NodeType of + disc -> add_node(Node, DiscNodes); + ram -> DiscNodes + end, + add_node(Node, RunningNodes)}), ok = handle_live_rabbit(Node), Monitors1 = case pmon:is_monitored({rabbit, Node}, Monitors) of - true -> - Monitors; - false -> - pmon:monitor({rabbit, Node}, Monitors) - end, + true -> + Monitors; + false -> + pmon:monitor({rabbit, Node}, Monitors) + end, {noreply, maybe_autoheal(State#state{monitors = Monitors1})}; handle_cast({joined_cluster, Node, NodeType}, State) -> @@ -584,7 +584,7 @@ handle_info({mnesia_system_event, State1 = case pmon:is_monitored({rabbit, Node}, Monitors) of true -> State; false -> State#state{ - monitors = pmon:monitor({rabbit, Node}, Monitors)} + monitors = pmon:monitor({rabbit, Node}, Monitors)} end, ok = handle_live_rabbit(Node), Partitions1 = lists:usort([Node | Partitions]), @@ -893,4 +893,4 @@ startup_log([]) -> rabbit_log:info("Starting rabbit_node_monitor~n", []); startup_log(Nodes) -> rabbit_log:info("Starting rabbit_node_monitor, might be partitioned from ~p~n", - [Nodes]). + [Nodes]). diff --git a/src/rabbit_vm.erl b/src/rabbit_vm.erl index b65536c0d4..17dae558b9 100644 --- a/src/rabbit_vm.erl +++ b/src/rabbit_vm.erl @@ -16,7 +16,7 @@ -module(rabbit_vm). --export([memory/0, binary/0, ets_tables_memory/1]). +-export([memory/0, total_memory/0, binary/0, ets_tables_memory/1]). -define(MAGIC_PLUGINS, ["cowboy", "ranch", "sockjs"]). @@ -30,7 +30,6 @@ %%---------------------------------------------------------------------------- -%% Like erlang:memory(), but with awareness of rabbit-y things memory() -> All = interesting_sups(), {Sums, _Other} = sum_processes( @@ -41,7 +40,7 @@ memory() -> [aggregate(Names, Sums, memory, fun (X) -> X end) || Names <- distinguished_interesting_sups()], - Mnesia = mnesia_memory(), + MnesiaETS = mnesia_memory(), MsgIndexETS = ets_memory(msg_stores()), MetricsETS = ets_memory([rabbit_metrics]), MetricsProc = @@ -53,8 +52,9 @@ memory() -> 0 end, MgmtDbETS = ets_memory([rabbit_mgmt_storage]), + OsTotal = total_memory(), - [{total, Total}, + [{total, ErlangTotal}, {processes, Processes}, {ets, ETS}, {atom, Atom}, @@ -67,30 +67,137 @@ memory() -> - ConnsReader - ConnsWriter - ConnsChannel - ConnsOther - Qs - QsSlave - MsgIndexProc - Plugins - MgmtDbProc - MetricsProc, - [{total, Total}, + [ + %% Connections {connection_readers, ConnsReader}, {connection_writers, ConnsWriter}, {connection_channels, ConnsChannel}, {connection_other, ConnsOther}, + + %% Queues {queue_procs, Qs}, {queue_slave_procs, QsSlave}, + + %% Processes {plugins, Plugins}, {other_proc, lists:max([0, OtherProc])}, %% [1] - {mnesia, Mnesia}, + + %% Metrics {metrics, MetricsETS + MetricsProc}, {mgmt_db, MgmtDbETS + MgmtDbProc}, - {msg_index, MsgIndexETS + MsgIndexProc}, - {other_ets, ETS - Mnesia - MsgIndexETS - MgmtDbETS}, + + %% ETS + {mnesia, MnesiaETS}, + {other_ets, ETS - MnesiaETS - MetricsETS - MgmtDbETS - MsgIndexETS}, + + %% Messages (mostly, some binaries are not messages) {binary, Bin}, + {msg_index, MsgIndexETS + MsgIndexProc}, + + %% System {code, Code}, {atom, Atom}, - {other_system, System - ETS - Atom - Bin - Code}]. + {other_system, System - ETS - Bin - Code - Atom + (OsTotal - ErlangTotal)}, + {total, OsTotal} + ]. %% [1] - erlang:memory(processes) can be less than the sum of its %% parts. Rather than display something nonsensical, just silence any %% claims about negative memory. See %% http://erlang.org/pipermail/erlang-questions/2012-September/069320.html +%% Memory reported by erlang:memory(total) is not supposed to +%% be equal to the total size of all pages mapped to the emulator, +%% according to http://erlang.org/doc/man/erlang.html#memory-0 +%% erlang:memory(total) under-reports memory usage by around 20% +-spec total_memory() -> Bytes :: integer(). +total_memory() -> + case get_memory_calculation_strategy() of + rss -> + case get_system_process_resident_memory() of + {ok, MemInBytes} -> + MemInBytes; + {error, Reason} -> + rabbit_log:debug("Unable to get system memory used. Reason: ~p." + " Falling back to erlang memory reporting", + [Reason]), + erlang:memory(total) + end; + erlang -> + erlang:memory(total) + end. + +-spec get_memory_calculation_strategy() -> rss | erlang. +get_memory_calculation_strategy() -> + case application:get_env(rabbit, vm_memory_calculation_strategy, rss) of + erlang -> + erlang; + rss -> + rss; + UnsupportedValue -> + rabbit_log:warning( + "Unsupported value '~p' for vm_memory_calculation_strategy. " + "Supported values: (rss|erlang). " + "Defaulting to 'rss'", + [UnsupportedValue] + ), + rss + end. + +-spec get_system_process_resident_memory() -> {ok, Bytes :: integer()} | {error, term()}. +get_system_process_resident_memory() -> + try + get_system_process_resident_memory(os:type()) + catch _:Error -> + {error, {"Failed to get process resident memory", Error}} + end. + +get_system_process_resident_memory({unix,darwin}) -> + get_ps_memory(); + +get_system_process_resident_memory({unix, linux}) -> + get_ps_memory(); + +get_system_process_resident_memory({unix,freebsd}) -> + get_ps_memory(); + +get_system_process_resident_memory({unix,openbsd}) -> + get_ps_memory(); + +get_system_process_resident_memory({win32,_OSname}) -> + OsPid = os:getpid(), + Cmd = " tasklist /fi \"pid eq " ++ OsPid ++ "\" /fo LIST 2>&1 ", + CmdOutput = os:cmd(Cmd), + %% Memory usage is displayed in kilobytes + %% with comma-separated thousands + case re:run(CmdOutput, "Mem Usage:\\s+([0-9,]+)\\s+K", [{capture, all_but_first, list}]) of + {match, [Match]} -> + NoCommas = [ N || N <- Match, N =/= $, ], + {ok, list_to_integer(NoCommas) * 1024}; + _ -> + {error, {unexpected_output_from_command, Cmd, CmdOutput}} + end; + +get_system_process_resident_memory({unix, sunos}) -> + get_ps_memory(); + +get_system_process_resident_memory({unix, aix}) -> + get_ps_memory(); + +get_system_process_resident_memory(_OsType) -> + {error, not_implemented_for_os}. + +get_ps_memory() -> + OsPid = os:getpid(), + Cmd = "ps -p " ++ OsPid ++ " -o rss=", + CmdOutput = os:cmd(Cmd), + case re:run(CmdOutput, "[0-9]+", [{capture, first, list}]) of + {match, [Match]} -> + {ok, list_to_integer(Match) * 1024}; + _ -> + {error, {unexpected_output_from_command, Cmd, CmdOutput}} + end. + binary() -> All = interesting_sups(), {Sums, Rest} = diff --git a/src/term_to_binary_compat.erl b/src/term_to_binary_compat.erl index a3e1045623..13396ddacb 100644 --- a/src/term_to_binary_compat.erl +++ b/src/term_to_binary_compat.erl @@ -18,15 +18,8 @@ -include("rabbit.hrl"). --export([queue_name_to_binary/1]). +-export([term_to_binary_1/1]). -queue_name_to_binary(#resource{kind = queue} = {resource, VHost, queue, Name}) -> - VHostBSize = byte_size(VHost), - NameBSize = byte_size(Name), - <<131, %% Binary format "version" - 104, 4, %% 4-element tuple - 100, 0, 8, "resource", %% `resource` atom - 109, VHostBSize:32, VHost/binary, %% Vhost binary - 100, 0, 5, "queue", %% `queue` atom - 109, NameBSize:32, Name/binary>>. %% Name binary +term_to_binary_1(Term) -> + term_to_binary(Term, [{minor_version, 1}]). diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 71e9f36c46..bc45d04d62 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -117,14 +117,14 @@ get_memory_limit() -> get_memory_use(bytes) -> MemoryLimit = get_memory_limit(), - {erlang:memory(total), case MemoryLimit > 0.0 of - true -> MemoryLimit; - false -> infinity - end}; + {rabbit_vm:total_memory(), case MemoryLimit > 0.0 of + true -> MemoryLimit; + false -> infinity + end}; get_memory_use(ratio) -> MemoryLimit = get_memory_limit(), case MemoryLimit > 0.0 of - true -> erlang:memory(total) / MemoryLimit; + true -> rabbit_vm:total_memory() / MemoryLimit; false -> infinity end. @@ -268,7 +268,7 @@ parse_mem_limit(_) -> internal_update(State = #state { memory_limit = MemLimit, alarmed = Alarmed, alarm_funs = {AlarmSet, AlarmClear} }) -> - MemUsed = erlang:memory(total), + MemUsed = rabbit_vm:total_memory(), NewAlarmed = MemUsed > MemLimit, case {Alarmed, NewAlarmed} of {false, true} -> emit_update_info(set, MemUsed, MemLimit), @@ -365,6 +365,7 @@ get_total_memory({unix, aix}) -> get_total_memory(_OsType) -> unknown. + %% A line looks like "Foo bar: 123456." parse_line_mach(Line) -> [Name, RHS | _Rest] = string:tokens(Line, ":"), diff --git a/test/config_schema_SUITE_data/rabbit.snippets b/test/config_schema_SUITE_data/rabbit.snippets index 69e926100e..03a687db66 100644 --- a/test/config_schema_SUITE_data/rabbit.snippets +++ b/test/config_schema_SUITE_data/rabbit.snippets @@ -131,6 +131,18 @@ tcp_listen_options.exit_on_close = false", [{vm_memory_high_watermark_paging_ratio,0.75}, {vm_memory_high_watermark,0.4}]}], []}, + {memory_monitor_interval, "memory_monitor_interval = 5000", + [{rabbit, + [{memory_monitor_interval, 5000}]}], + []}, + {vm_memory_calculation_strategy, "vm_memory_calculation_strategy = rss", + [{rabbit, + [{vm_memory_calculation_strategy, rss}]}], + []}, + {vm_memory_calculation_strategy, "vm_memory_calculation_strategy = erlang", + [{rabbit, + [{vm_memory_calculation_strategy, erlang}]}], + []}, {listeners_tcp_ip, "listeners.tcp.1 = 192.168.1.99:5672", [{rabbit,[{tcp_listeners,[{"192.168.1.99",5672}]}]}], diff --git a/test/partitions_SUITE.erl b/test/partitions_SUITE.erl index 8c8a772987..b09d05b550 100644 --- a/test/partitions_SUITE.erl +++ b/test/partitions_SUITE.erl @@ -335,16 +335,26 @@ autoheal_unexpected_finish(Config) -> partial_false_positive(Config) -> [A, B, C] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + suspend_node_monitor(Config, C), block([{A, B}]), timer:sleep(1000), block([{A, C}]), timer:sleep(?DELAY), + resume_node_monitor(Config, C), + timer:sleep(?DELAY), unblock([{A, B}, {A, C}]), timer:sleep(?DELAY), %% When B times out A's connection, it will check with C. C will %% not have timed out A yet, but already it can't talk to it. We %% need to not consider this a partial partition; B and C should %% still talk to each other. + %% + %% Because there is a chance that C can still talk to A when B + %% requests to check for a partial partition, we suspend C's + %% rabbit_node_monitor at the beginning and resume it after the + %% link between A and C is blocked. This way, when B asks C about + %% A, we make sure that the A<->C link is blocked before C's + %% rabbit_node_monitor processes B's request. [B, C] = partitions(A), [A] = partitions(B), [A] = partitions(C), @@ -369,7 +379,19 @@ partial_to_full(Config) -> partial_pause_minority(Config) -> [A, B, C] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), set_mode(Config, pause_minority), + %% We suspend rabbit_node_monitor on C while we block the link + %% between A and B. This should make sure C's rabbit_node_monitor + %% processes both partial partition checks from A and B at about + %% the same time, and thus increase the chance both A and B decides + %% there is a partial partition. + %% + %% Without this, one node may see the partial partition and stop, + %% before the other node sees it. In this case, the other node + %% doesn't stop and this testcase fails. + suspend_node_monitor(Config, C), block([{A, B}]), + timer:sleep(?DELAY), + resume_node_monitor(Config, C), [await_running(N, false) || N <- [A, B]], await_running(C, true), unblock([{A, B}]), @@ -394,6 +416,22 @@ set_mode(Config, Mode) -> set_mode(Config, Nodes, Mode) -> rabbit_ct_broker_helpers:set_partition_handling_mode(Config, Nodes, Mode). +suspend_node_monitor(Config, Node) -> + rabbit_ct_broker_helpers:rpc( + Config, Node, ?MODULE, suspend_or_resume_node_monitor, [suspend]). + +resume_node_monitor(Config, Node) -> + rabbit_ct_broker_helpers:rpc( + Config, Node, ?MODULE, suspend_or_resume_node_monitor, [resume]). + +suspend_or_resume_node_monitor(SuspendOrResume) -> + Action = case SuspendOrResume of + suspend -> "Suspending"; + resume -> "Resuming" + end, + rabbit_log:info("(~s) ~s node monitor~n", [?MODULE, Action]), + ok = sys:SuspendOrResume(rabbit_node_monitor). + block_unblock(Pairs) -> block(Pairs), timer:sleep(?DELAY), diff --git a/test/term_to_binary_compat_prop_SUITE.erl b/test/term_to_binary_compat_prop_SUITE.erl index d09b23c9ea..6c8a92a29f 100644 --- a/test/term_to_binary_compat_prop_SUITE.erl +++ b/test/term_to_binary_compat_prop_SUITE.erl @@ -24,13 +24,11 @@ -include_lib("proper/include/proper.hrl"). all() -> - %% The test should run on OTP < 20 (erts < 9) - case erts_gt_8() of - true -> - []; - false -> - [queue_name_to_binary] - end. + [ + pre_3_6_11_works, + term_to_binary_latin_atom, + queue_name_to_binary + ]. erts_gt_8() -> Vsn = erlang:system_info(version), @@ -47,16 +45,51 @@ end_per_suite(Config) -> init_per_testcase(Testcase, Config) -> rabbit_ct_helpers:testcase_started(Config, Testcase). +%% If this test fails - the erlang version is not supported in +%% RabbitMQ-3.6.10 and earlier. +pre_3_6_11_works(Config) -> + Fun = fun () -> prop_pre_3_6_11_works(Config) end, + rabbit_ct_proper_helpers:run_proper(Fun, [], 50000). + +prop_pre_3_6_11_works(_Config) -> + ?FORALL(Term, any(), + begin + Current = term_to_binary(Term), + Compat = term_to_binary_compat:term_to_binary_1(Term), + Current =:= Compat + end). + +term_to_binary_latin_atom(Config) -> + Fun = fun () -> prop_term_to_binary_latin_atom(Config) end, + rabbit_ct_proper_helpers:run_proper(Fun, [], 10000). + +prop_term_to_binary_latin_atom(_Config) -> + ?FORALL(LatinString, list(integer(0, 255)), + begin + Length = length(LatinString), + Atom = list_to_atom(LatinString), + Binary = list_to_binary(LatinString), + <<131,100, Length:16, Binary/binary>> =:= term_to_binary_compat:term_to_binary_1(Atom) + end). + queue_name_to_binary(Config) -> Fun = fun () -> prop_queue_name_to_binary(Config) end, rabbit_ct_proper_helpers:run_proper(Fun, [], 10000). prop_queue_name_to_binary(_Config) -> - ?FORALL({Vhost, QName}, {binary(), binary()}, + ?FORALL({VHost, QName}, {binary(), binary()}, begin - Resource = rabbit_misc:r(Vhost, queue, QName), - Legacy = term_to_binary_compat:queue_name_to_binary(Resource), - Current = term_to_binary(Resource), - Current =:= Legacy - end).
\ No newline at end of file + VHostBSize = byte_size(VHost), + NameBSize = byte_size(QName), + Expected = + <<131, %% Binary format "version" + 104, 4, %% 4-element tuple + 100, 0, 8, "resource", %% `resource` atom + 109, VHostBSize:32, VHost/binary, %% Vhost binary + 100, 0, 5, "queue", %% `queue` atom + 109, NameBSize:32, QName/binary>>, %% Name binary + Resource = rabbit_misc:r(VHost, queue, QName), + Current = term_to_binary_compat:term_to_binary_1(Resource), + Current =:= Expected + end). diff --git a/test/topic_permission_SUITE.erl b/test/topic_permission_SUITE.erl index 7b9d9f7701..c656746432 100644 --- a/test/topic_permission_SUITE.erl +++ b/test/topic_permission_SUITE.erl @@ -218,4 +218,36 @@ topic_permission_checks1(_Config) -> Perm, Context ) || Perm <- Permissions], + + %% expand variables + rabbit_auth_backend_internal:set_topic_permissions( + <<"guest">>, <<"other-vhost">>, <<"amq.topic">>, + "services.{vhost}.accounts.{username}.notifications", + "services.{vhost}.accounts.{username}.notifications", <<"acting-user">> + ), + %% routing key OK + [true = rabbit_auth_backend_internal:check_topic_access( + User, + Topic#resource{virtual_host = <<"other-vhost">>}, + Perm, + #{routing_key => <<"services.other-vhost.accounts.guest.notifications">>, + variable_map => #{ + <<"username">> => <<"guest">>, + <<"vhost">> => <<"other-vhost">> + } + } + ) || Perm <- Permissions], + %% routing key KO + [false = rabbit_auth_backend_internal:check_topic_access( + User, + Topic#resource{virtual_host = <<"other-vhost">>}, + Perm, + #{routing_key => <<"services.default.accounts.dummy.notifications">>, + variable_map => #{ + <<"username">> => <<"guest">>, + <<"vhost">> => <<"other-vhost">> + } + } + ) || Perm <- Permissions], + ok. |
