Skip to content

Commit 1b4229b

Browse files
committed
Add tests, make minimum test interval configurable, use os:timestamp/0 instead of now/0
1 parent d9c9bca commit 1b4229b

11 files changed

+375
-15
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
ebin
22
rebar
33
deps
4+
test/*.beam
5+
.eunit
6+
logs
47
*~

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ compile: rebar
88
test: rebar compile
99
./rebar skip_deps=true eunit
1010

11+
ct: rebar compile
12+
./rebar skip_deps=true ct -v
13+
1114
clean: rebar
1215
./rebar clean
1316

src/alarms.app.src

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
mnesia
1111
]},
1212
{mod, {alarms_app, []}},
13-
{env, [{long_gc, 10000},
14-
{large_heap, 64000000},
15-
{handlers, [alarms_basic_handler,
16-
alarms_folsom_handler]}]}
13+
{env, [{handlers, [alarms_basic_handler,
14+
alarms_folsom_handler
15+
]},
16+
{long_gc, 10000},
17+
{large_heap, 1000000},
18+
{min_log_interval, 30}]}
1719
]}.

src/alarms_basic_handler.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
-include("alarms.hrl").
2121

22-
-define(MIN_LOG_INTERVAL, 30).
22+
-define(MIN_LOG_INTERVAL, alarms_utils:get_cfg(min_log_interval)).
2323

2424
-record(state, {alarms, log_ts}).
2525

@@ -190,12 +190,12 @@ handle_alarm(AlarmType, Details, Alarms0, LogTS0) ->
190190
{ok, {Cnt, _Last, _Details}} -> Cnt + 1;
191191
error -> 1
192192
end,
193-
TS = calendar:local_time(),
193+
TS = alarms_utils:epoch_usec_to_local_time(alarms_utils:now_epoch_usec()),
194194
Alarms = orddict:store(AlarmType, {Count, TS, Details}, Alarms0),
195195
ShouldLog = case orddict:find(AlarmType, LogTS0) of
196196
{ok, T} ->
197197
calendar:datetime_to_gregorian_seconds(TS) -
198-
calendar:datetime_to_gregorian_seconds(T) >
198+
calendar:datetime_to_gregorian_seconds(T) >=
199199
?MIN_LOG_INTERVAL;
200200
error ->
201201
true

src/alarms_folsom_handler.erl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,10 @@ code_change(_OldVsn, State, _Extra) ->
186186
%%%===================================================================
187187
%%% Internal functions
188188
%%%===================================================================
189-
-define(EPOCH_SEC, 62167219200).
190-
191189
do_get_alarm(AlarmType) ->
192190
[{count, Count}, {one, CurCount}] =
193191
folsom_metrics:get_metric_value({alarm, AlarmType, summary}),
194192
History0 = folsom_metrics:get_metric_value({alarm, AlarmType, history}),
195-
History = [{epoch_usec_to_local_time(TS), Events}
193+
History = [{alarms_utils:epoch_usec_to_local_time(TS), Events}
196194
|| {TS, Events} <- History0],
197195
{Count, CurCount, History}.
198-
199-
epoch_usec_to_local_time(USec) ->
200-
calendar:universal_time_to_local_time(
201-
calendar:gregorian_seconds_to_datetime(?EPOCH_SEC + USec div 1000000)).

src/alarms_utils.erl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
%%%-------------------------------------------------------------------
99
-module(alarms_utils).
1010

11-
-export([get_cfg/1, set_cfg/2, alarm_types/0, event_manager/0]).
11+
-export([get_cfg/1, set_cfg/2, alarm_types/0, event_manager/0,
12+
now_epoch_usec/0, epoch_usec_to_local_time/1]).
1213

1314
-include("alarms.hrl").
1415

16+
-define(EPOCH_SEC, 62167219200).
17+
1518
get_cfg(Key) ->
1619
{ok, Val} = application:get_env(alarms, Key),
1720
Val.
@@ -24,3 +27,11 @@ alarm_types() ->
2427

2528
event_manager() ->
2629
?EVENT_MANAGER.
30+
31+
now_epoch_usec() ->
32+
{Mega, Sec, Micro} = os:timestamp(),
33+
(Mega * 1000000 + Sec) * 1000000 + Micro.
34+
35+
epoch_usec_to_local_time(USec) ->
36+
calendar:universal_time_to_local_time(
37+
calendar:gregorian_seconds_to_datetime(?EPOCH_SEC + USec div 1000000)).

test/alarms_basic_handler_SUITE.erl

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
%%%-------------------------------------------------------------------
2+
%%% @author Pawel Chrzaszcz
3+
%%% @copyright (C) 2013, Erlang Solutions Ltd.
4+
%%% @doc Tests for alarms_basic_handler
5+
%%%
6+
%%% @end
7+
%%% Created : 16 May 2013 by [email protected]
8+
%%%-------------------------------------------------------------------
9+
-module(alarms_basic_handler_SUITE).
10+
11+
-compile(export_all).
12+
13+
-include_lib("common_test/include/ct.hrl").
14+
-include("alarms.hrl").
15+
16+
-import(test_utils, [init/0, fake_alarm/2]).
17+
18+
suite() ->
19+
[].
20+
21+
all() ->
22+
[test_summary,
23+
test_logging,
24+
test_unexpected].
25+
26+
init_per_suite(Config) ->
27+
init(),
28+
application:load(alarms),
29+
alarms_utils:set_cfg(handlers, [alarms_basic_handler]),
30+
Config.
31+
32+
end_per_suite(_Config) ->
33+
ok.
34+
35+
init_per_testcase(test_logging, Config) ->
36+
alarms:start(),
37+
Interval = alarms_utils:get_cfg(min_log_interval),
38+
alarms_utils:set_cfg(min_log_interval, 1),
39+
error_logger:add_report_handler(test_report_handler),
40+
[{min_log_interval, Interval}|Config];
41+
init_per_testcase(test_unexpected, Config) ->
42+
alarms:start(),
43+
error_logger:add_report_handler(test_report_handler),
44+
Config;
45+
init_per_testcase(_TC, Config) ->
46+
alarms:start(),
47+
Config.
48+
49+
end_per_testcase(test_logging, Config) ->
50+
error_logger:delete_report_handler(test_report_handler),
51+
alarms_utils:set_cfg(min_log_interval, ?config(min_log_interval, Config)),
52+
alarms:stop(),
53+
ok;
54+
end_per_testcase(test_unexpected, Config) ->
55+
error_logger:delete_report_handler(test_report_handler),
56+
alarms:stop(),
57+
Config;
58+
end_per_testcase(_TC, _Config) ->
59+
alarms:stop(),
60+
ok.
61+
62+
test_summary(_Config) ->
63+
fake_alarm(long_gc, gc1),
64+
Before = calendar:local_time(),
65+
fake_alarm(long_gc, gc2),
66+
fake_alarm(large_heap, lh),
67+
After = calendar:local_time(),
68+
69+
{ok, LH} = alarms_basic_handler:get_alarm(large_heap),
70+
{1, TS1, lh} = LH,
71+
{ok, GC} = alarms_basic_handler:get_alarm(long_gc),
72+
{2, TS2, gc2} = GC,
73+
error = alarms_basic_handler:get_alarm(mnesia_fatal),
74+
[{large_heap, LH}, {long_gc, GC}] = alarms_basic_handler:get_alarms(),
75+
true = Before =< TS2 andalso TS2 =< TS1 andalso TS1 =< After.
76+
77+
test_logging(_Config) ->
78+
fake_alarm(long_gc, gc1),
79+
fake_alarm(long_gc, gc2),
80+
fake_alarm(large_heap, lh),
81+
82+
%% Wait until events are processed
83+
sys:get_status(alarm_handler),
84+
timer:sleep(1000),
85+
fake_alarm(long_gc, gc3),
86+
87+
%% Wait until events are processed
88+
sys:get_status(alarm_handler),
89+
[GC1, LH, GC3] = test_report_handler:get_logs(),
90+
{info_report, _, {_, std_info,
91+
[{alarm, long_gc}, {count,1}, {details, gc1}]}} = GC1,
92+
{info_report, _, {_, std_info,
93+
[{alarm, large_heap}, {count,1}, {details, lh}]}} = LH,
94+
{info_report, _, {_, std_info,
95+
[{alarm, long_gc}, {count,3}, {details, gc3}]}} = GC3,
96+
true.
97+
98+
test_unexpected(_Config) ->
99+
fake_alarm(unexpected, alarm),
100+
[] = alarms_basic_handler:get_alarms(),
101+
[Log] = test_report_handler:get_logs(),
102+
{error, _, {_, "Unexpected alarm ~p: ~p~n", [unexpected, alarm]}} = Log,
103+
true.

test/alarms_folsom_handler_SUITE.erl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
%%%-------------------------------------------------------------------
2+
%%% @author Pawel Chrzaszcz
3+
%%% @copyright (C) 2013, Erlang Solutions Ltd.
4+
%%% @doc Tests for alarms_folsom_handler
5+
%%%
6+
%%% @end
7+
%%% Created : 16 May 2013 by [email protected]
8+
%%%-------------------------------------------------------------------
9+
-module(alarms_folsom_handler_SUITE).
10+
11+
-compile(export_all).
12+
13+
-include_lib("common_test/include/ct.hrl").
14+
-include("alarms.hrl").
15+
16+
-import(test_utils, [init/0, fake_alarm/2]).
17+
18+
suite() ->
19+
[].
20+
21+
all() ->
22+
[test_metrics,
23+
test_unexpected].
24+
25+
init_per_suite(Config) ->
26+
init(),
27+
application:load(alarms),
28+
alarms_utils:set_cfg(handlers, [alarms_folsom_handler]),
29+
Config.
30+
31+
end_per_suite(_Config) ->
32+
ok.
33+
34+
init_per_testcase(_TC, Config) ->
35+
alarms:start(),
36+
Config.
37+
38+
end_per_testcase(_TC, _Config) ->
39+
alarms:stop(),
40+
folsom:stop(),
41+
ok.
42+
43+
test_metrics(_Config) ->
44+
Before = alarms_utils:epoch_usec_to_local_time(
45+
folsom_utils:now_epoch_micro()),
46+
fake_alarm(long_gc, gc1),
47+
timer:sleep(100),
48+
fake_alarm(long_gc, gc2),
49+
timer:sleep(100),
50+
fake_alarm(large_heap, lh),
51+
After = alarms_utils:epoch_usec_to_local_time(
52+
folsom_utils:now_epoch_micro()),
53+
54+
{2, 2, [GC2, GC1]} = alarms_folsom_handler:get_alarm(long_gc),
55+
{1, 1, [LH]} = alarms_folsom_handler:get_alarm(large_heap),
56+
{0, 0, []} = alarms_folsom_handler:get_alarm(mnesia_fatal),
57+
58+
{GC_TS1, [{event, gc1}]} = GC1,
59+
{GC_TS2, [{event, gc2}]} = GC2,
60+
{LH_TS, [{event, lh}]} = LH,
61+
62+
true = Before =< GC_TS1 andalso GC_TS1 =< GC_TS2 andalso GC_TS2 =< LH_TS
63+
andalso LH_TS =< After.
64+
65+
test_unexpected(_Config) ->
66+
fake_alarm(unexpected, alarm),
67+
[] = alarms_folsom_handler:get_alarms(),
68+
true.

test/alarms_server_SUITE.erl

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
%%%-------------------------------------------------------------------
2+
%%% @author Pawel Chrzaszcz
3+
%%% @copyright (C) 2013, Erlang Solutions Ltd.
4+
%%% @doc Tests for alarms_server
5+
%%%
6+
%%% @end
7+
%%% Created : 15 May 2013 by [email protected]
8+
%%%-------------------------------------------------------------------
9+
-module(alarms_server_SUITE).
10+
11+
-compile(export_all).
12+
13+
-include_lib("common_test/include/ct.hrl").
14+
15+
-import(test_utils, [init/0, fake_event/1]).
16+
17+
suite() ->
18+
[].
19+
20+
all() ->
21+
[test_monitor,
22+
test_mnesia,
23+
test_alarm_handling].
24+
25+
init_per_suite(Config) ->
26+
init(),
27+
application:load(alarms),
28+
Config.
29+
30+
end_per_suite(_Config) ->
31+
ok.
32+
33+
init_per_testcase(_TC, Config) ->
34+
alarms_server:start(),
35+
Config.
36+
37+
end_per_testcase(_TC, _Config) ->
38+
alarms_server:stop(),
39+
ok.
40+
41+
test_monitor(_Config) ->
42+
Options = alarms_server:get_monitor_options(),
43+
true = proplists:get_value(busy_dist_port, Options),
44+
true = proplists:get_value(busy_port, Options),
45+
LH = proplists:get_value(large_heap, Options),
46+
LongGC = proplists:get_value(long_gc, Options),
47+
{ok, LH} = application:get_env(alarms, large_heap),
48+
{ok, LongGC} = application:get_env(alarms, long_gc),
49+
50+
NewOptions = lists:keyreplace(
51+
large_heap, 1, Options, {large_heap, 1234567}),
52+
Options = alarms_server:set_monitor_options(NewOptions),
53+
NewOptions = alarms_server:get_monitor_options(),
54+
true.
55+
56+
test_mnesia(_Config) ->
57+
Subscribers = mnesia:system_info(subscribers),
58+
ServerPid = whereis(alarms_server),
59+
true = lists:member(ServerPid, Subscribers).
60+
61+
test_alarm_handling(_Config) ->
62+
Pid = self(),
63+
64+
fake_event({monitor, Pid, long_gc, gc_info}),
65+
[{long_gc, {Pid, gc_info}}] = alarm_handler:get_alarms(),
66+
alarm_handler:clear_alarm(long_gc),
67+
68+
fake_event({monitor, Pid, large_heap, lh_info}),
69+
[{large_heap, {Pid, lh_info}}] = alarm_handler:get_alarms(),
70+
alarm_handler:clear_alarm(large_heap),
71+
72+
fake_event({monitor, Pid, busy_port, port}),
73+
[{busy_port, {Pid, port}}] = alarm_handler:get_alarms(),
74+
alarm_handler:clear_alarm(busy_port),
75+
76+
fake_event({monitor, Pid, busy_dist_port, distport}),
77+
[{busy_dist_port, {Pid, distport}}] = alarm_handler:get_alarms(),
78+
alarm_handler:clear_alarm(busy_dist_port),
79+
80+
fake_event({mnesia_overload, overload_info}),
81+
[{mnesia_overload, overload_info}] = alarm_handler:get_alarms(),
82+
alarm_handler:clear_alarm(mnesia_overload),
83+
84+
fake_event({inconsistent_database, context, info}),
85+
[{inconsistent_database, {context, info}}] = alarm_handler:get_alarms(),
86+
alarm_handler:clear_alarm(inconsistent_database),
87+
88+
fake_event({mnesia_fatal, "fatal", [], <<>>}),
89+
[{mnesia_fatal, {"fatal", [], <<>>}}] = alarm_handler:get_alarms(),
90+
alarm_handler:clear_alarm(mnesia_fatal),
91+
92+
fake_event({mnesia_error, "error", []}),
93+
[{mnesia_error, {"error", []}}] = alarm_handler:get_alarms(),
94+
alarm_handler:clear_alarm(mnesia_error),
95+
96+
fake_event({nodeup, upnode, []}),
97+
[{nodeup, {upnode, []}}] = alarm_handler:get_alarms(),
98+
alarm_handler:clear_alarm(nodeup),
99+
100+
fake_event({nodedown, downnode, []}),
101+
[{nodedown, {downnode, []}}] = alarm_handler:get_alarms(),
102+
alarm_handler:clear_alarm(nodedown),
103+
true.

0 commit comments

Comments
 (0)