1: -module(mongooseim_metrics_SUITE). 2: 3: -include_lib("exml/include/exml.hrl"). 4: -include_lib("proper/include/proper.hrl"). 5: -include_lib("eunit/include/eunit.hrl"). 6: -include("jlib.hrl"). 7: -include_lib("common_test/include/ct.hrl"). 8: 9: -compile([export_all, nowarn_export_all]). 10: 11: all() -> 12: [ 13: {group, ordinary_mode}, 14: {group, all_metrics_are_global} 15: ]. 16: 17: groups() -> 18: [ 19: {ordinary_mode, [], all_metrics_list()}, 20: {all_metrics_are_global, [], all_metrics_list()} 21: ]. 22: 23: all_metrics_list() -> 24: [ 25: no_skip_metric, 26: subscriptions_initialised, 27: tcp_connections_detected, 28: tcp_metric_varies_with_tcp_variations, 29: up_time_positive, 30: queued_messages_increase, 31: function_ensure_subscribed_metric_subscribes 32: ]. 33: 34: init_per_suite(C) -> 35: application:load(exometer_core), 36: application:set_env(exometer_core, mongooseim_report_interval, 1000), 37: {Port, Socket} = carbon_cache_server:start(), 38: Sup = spawn(fun() -> 39: mim_ct_sup:start_link(ejabberd_sup), 40: Hooks = 41: {gen_hook, 42: {gen_hook, start_link, []}, 43: permanent, 44: brutal_kill, 45: worker, 46: [gen_hook]}, 47: C2SSupervisor = 48: {ejabberd_c2s_sup, 49: {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]}, 50: permanent, 51: infinity, 52: supervisor, 53: [ejabberd_tmp_sup]}, 54: supervisor:start_child(ejabberd_sup, Hooks), 55: supervisor:start_child(ejabberd_sup, C2SSupervisor), 56: receive 57: stop -> 58: ok 59: end 60: end), 61: Reporters = get_reporters_cfg(Port), 62: application:set_env(exometer_core, report, Reporters), 63: PortServer = carbon_cache_server:wait_for_accepting(), 64: gen_tcp:controlling_process(Socket, PortServer), 65: {ok, _Apps} = application:ensure_all_started(exometer_core), 66: exometer:new([carbon, packets], spiral), 67: [{carbon_port, Port}, {test_sup, Sup}, {carbon_server, PortServer}, {carbon_socket, Socket} | C]. 68: 69: end_per_suite(C) -> 70: Sup = ?config(test_sup, C), 71: Sup ! stop, 72: CarbonServer = ?config(carbon_server, C), 73: erlang:exit(CarbonServer, kill), 74: CarbonSocket = ?config(carbon_socket, C), 75: gen_tcp:close(CarbonSocket), 76: application:stop(exometer_core), 77: C. 78: 79: init_per_group(Group, C) -> 80: [mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts(Group)], 81: mongoose_metrics:init(), 82: C. 83: 84: end_per_group(Group, C) -> 85: mongoose_metrics:remove_host_type_metrics(<<"localhost">>), 86: mongoose_metrics:remove_host_type_metrics(global), 87: [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts(Group)], 88: C. 89: 90: init_per_testcase(CN, C) when tcp_connections_detected =:= CN; 91: tcp_metric_varies_with_tcp_variations =:= CN -> 92: exometer:setopts([global, tcpPortsUsed], [{sample_interval, 50}]), 93: exometer:repair([global, tcpPortsUsed]), 94: C; 95: init_per_testcase(queued_messages_increase, C) -> 96: exometer:setopts([global, processQueueLengths], [{sample_interval, 50}]), 97: exometer:repair([global, processQueueLengths]), 98: PidsFun = fun() -> put('$internal_queue_len', 1), 99: receive die -> ok 100: end 101: end, 102: Pids = [spawn(PidsFun) || _ <- lists:seq(1,5)], 103: lists:foreach(fun(Pid) -> Pid ! undefined end, Pids), 104: [{pids, Pids} | C]; 105: init_per_testcase(_N, C) -> 106: C. 107: 108: end_per_testcase(queued_messages_increase, C) -> 109: [Pid ! die || Pid <- ?config(pids, C)], 110: C; 111: end_per_testcase(_N, C) -> 112: C. 113: 114: up_time_positive(_C) -> 115: {ok, [{value, X}]} = mongoose_metrics:get_metric_value(global, nodeUpTime), 116: ?assert(X > 0). 117: 118: function_ensure_subscribed_metric_subscribes(_C) -> 119: SubMetric = [happy_metric], 120: UnsubMetric = [sad_metric], 121: mongoose_metrics:ensure_subscribed_metric(global, SubMetric, spiral), 122: mongoose_metrics:ensure_metric(global, UnsubMetric, spiral), 123: Subs = exometer_report:list_subscriptions(exometer_report_graphite), 124: try 125: true = lists:keymember([global|SubMetric], 1, Subs), 126: false = lists:keymember([global|UnsubMetric], 1, Subs) 127: catch C:E:S -> 128: ct:pal("Subs ~p", [Subs]), 129: erlang:raise(C, E, S) 130: end. 131: 132: get_new_tcp_metric_value(OldValue) -> 133: Validator = fun(NewValue) -> OldValue =/= NewValue end, 134: {ok, {ok, [{value, X}]}} = async_helper:wait_until( 135: fun() -> mongoose_metrics:get_metric_value(global, tcpPortsUsed) end, 136: true, #{validator => Validator, sleep_time => 30, time_left => 500} 137: ), 138: X. 139: 140: tcp_connections_detected(_C) -> 141: get_new_tcp_metric_value({ok, []}). 142: 143: tcp_metric_varies_with_tcp_variations(_C) -> 144: X = get_new_tcp_metric_value({ok, []}), 145: {ok, Socket} = gen_tcp:listen(1805, []), 146: Y = get_new_tcp_metric_value({ok, [{value, X}]}), 147: ?assert(Y == X + 1), 148: gen_tcp:close(Socket), 149: X = get_new_tcp_metric_value({ok, [{value, Y}]}). 150: 151: queued_messages_increase(_C) -> 152: async_helper:wait_until( 153: fun() -> 154: {ok, L} = mongoose_metrics:get_metric_value(global, processQueueLengths), 155: lists:sort(L) 156: end, 157: [{fsm, 5}, {regular, 5}, {total, 10}] 158: ). 159: 160: no_skip_metric(_C) -> 161: ok = mongoose_metrics:create_generic_hook_metric(<<"localhost">>, sm_register_connection_hook), 162: undefined = exometer:info([<<"localhost">>, sm_register_connection_hook]). 163: 164: subscriptions_initialised(_C) -> 165: true = wait_for_update(exometer:get_value([carbon, packets], count), 60). 166: 167: wait_for_update({ok, [{count,X}]}, 0) -> 168: X > 0; 169: wait_for_update({ok, [{count,X}]}, _N) when X > 0 -> 170: true; 171: wait_for_update({ok, [{count,0}]}, N) -> 172: timer:sleep(1000), 173: wait_for_update(exometer:get_value([carbon, packets], count), N-1). 174: 175: opts(Group) -> 176: [{hosts, [<<"localhost">>]}, 177: {host_types, []}, 178: {all_metrics_are_global, Group =:= all_metrics_are_global}]. 179: 180: get_reporters_cfg(Port) -> 181: [{reporters, [ 182: {exometer_report_graphite, [ 183: {prefix, "mongooseim"}, 184: {connect_timeout, 10000}, 185: {host, "127.0.0.1"}, 186: {port, Port}, 187: {api_key, ""} 188: ]} 189: ]}].