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: ]. 32: 33: init_per_suite(C) -> 34: application:load(exometer_core), 35: application:set_env(exometer_core, mongooseim_report_interval, 1000), 36: {Port, Socket} = carbon_cache_server:start(), 37: Sup = spawn(fun() -> 38: mim_ct_sup:start_link(ejabberd_sup), 39: Hooks = 40: {gen_hook, 41: {gen_hook, start_link, []}, 42: permanent, 43: brutal_kill, 44: worker, 45: [gen_hook]}, 46: C2SSupervisor = 47: {ejabberd_c2s_sup, 48: {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]}, 49: permanent, 50: infinity, 51: supervisor, 52: [ejabberd_tmp_sup]}, 53: supervisor:start_child(ejabberd_sup, Hooks), 54: supervisor:start_child(ejabberd_sup, C2SSupervisor), 55: receive 56: stop -> 57: ok 58: end 59: end), 60: Reporters = get_reporters_cfg(Port), 61: application:set_env(exometer_core, report, Reporters), 62: PortServer = carbon_cache_server:wait_for_accepting(), 63: gen_tcp:controlling_process(Socket, PortServer), 64: {ok, _Apps} = application:ensure_all_started(exometer_core), 65: exometer:new([carbon, packets], spiral), 66: [{carbon_port, Port}, {test_sup, Sup}, {carbon_server, PortServer}, {carbon_socket, Socket} | C]. 67: 68: end_per_suite(C) -> 69: Sup = ?config(test_sup, C), 70: Sup ! stop, 71: CarbonServer = ?config(carbon_server, C), 72: erlang:exit(CarbonServer, kill), 73: CarbonSocket = ?config(carbon_socket, C), 74: gen_tcp:close(CarbonSocket), 75: application:stop(exometer_core), 76: C. 77: 78: init_per_group(Group, C) -> 79: [mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts(Group)], 80: mongoose_metrics:init(), 81: C. 82: 83: end_per_group(Group, C) -> 84: mongoose_metrics:remove_host_type_metrics(<<"localhost">>), 85: mongoose_metrics:remove_host_type_metrics(global), 86: [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts(Group)], 87: C. 88: 89: init_per_testcase(CN, C) when tcp_connections_detected =:= CN; 90: tcp_metric_varies_with_tcp_variations =:= CN -> 91: exometer:setopts([global, tcpPortsUsed], [{sample_interval, 50}]), 92: exometer:repair([global, tcpPortsUsed]), 93: C; 94: init_per_testcase(queued_messages_increase, C) -> 95: exometer:setopts([global, processQueueLengths], [{sample_interval, 50}]), 96: exometer:repair([global, processQueueLengths]), 97: PidsFun = fun() -> put('$internal_queue_len', 1), 98: receive die -> ok 99: end 100: end, 101: Pids = [spawn(PidsFun) || _ <- lists:seq(1,5)], 102: lists:foreach(fun(Pid) -> Pid ! undefined end, Pids), 103: [{pids, Pids} | C]; 104: init_per_testcase(_N, C) -> 105: C. 106: 107: end_per_testcase(queued_messages_increase, C) -> 108: [Pid ! die || Pid <- ?config(pids, C)], 109: C; 110: end_per_testcase(_N, C) -> 111: C. 112: 113: up_time_positive(_C) -> 114: {ok, [{value, X}]} = mongoose_metrics:get_metric_value(global, nodeUpTime), 115: ?assert(X > 0). 116: 117: get_new_tcp_metric_value(OldValue) -> 118: Validator = fun(NewValue) -> OldValue =/= NewValue end, 119: {ok, {ok, [{value, X}]}} = async_helper:wait_until( 120: fun() -> mongoose_metrics:get_metric_value(global, tcpPortsUsed) end, 121: true, #{validator => Validator, sleep_time => 30, time_left => 500} 122: ), 123: X. 124: 125: tcp_connections_detected(_C) -> 126: get_new_tcp_metric_value({ok, []}). 127: 128: tcp_metric_varies_with_tcp_variations(_C) -> 129: X = get_new_tcp_metric_value({ok, []}), 130: {ok, Socket} = gen_tcp:listen(1805, []), 131: Y = get_new_tcp_metric_value({ok, [{value, X}]}), 132: ?assert(Y == X + 1), 133: gen_tcp:close(Socket), 134: X = get_new_tcp_metric_value({ok, [{value, Y}]}). 135: 136: queued_messages_increase(_C) -> 137: async_helper:wait_until( 138: fun() -> 139: {ok, L} = mongoose_metrics:get_metric_value(global, processQueueLengths), 140: lists:sort(L) 141: end, 142: [{fsm, 5}, {regular, 5}, {total, 10}] 143: ). 144: 145: no_skip_metric(_C) -> 146: ok = mongoose_metrics:create_generic_hook_metric(<<"localhost">>, sm_register_connection_hook), 147: undefined = exometer:info([<<"localhost">>, sm_register_connection_hook]). 148: 149: subscriptions_initialised(_C) -> 150: true = wait_for_update(exometer:get_value([carbon, packets], count), 60). 151: 152: wait_for_update({ok, [{count,X}]}, 0) -> 153: X > 0; 154: wait_for_update({ok, [{count,X}]}, _N) when X > 0 -> 155: true; 156: wait_for_update({ok, [{count,0}]}, N) -> 157: timer:sleep(1000), 158: wait_for_update(exometer:get_value([carbon, packets], count), N-1). 159: 160: opts(Group) -> 161: [{hosts, [<<"localhost">>]}, 162: {host_types, []}, 163: {all_metrics_are_global, Group =:= all_metrics_are_global}]. 164: 165: get_reporters_cfg(Port) -> 166: [{reporters, [ 167: {exometer_report_graphite, [ 168: {prefix, "mongooseim"}, 169: {connect_timeout, 10000}, 170: {host, "127.0.0.1"}, 171: {port, Port}, 172: {api_key, ""} 173: ]} 174: ]}].