您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

648 行
30 KiB

14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
14 年前
  1. %% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved.
  2. %%
  3. %% This file is provided to you under the Apache License,
  4. %% Version 2.0 (the "License"); you may not use this file
  5. %% except in compliance with the License. You may obtain
  6. %% a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing,
  11. %% software distributed under the License is distributed on an
  12. %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  13. %% KIND, either express or implied. See the License for the
  14. %% specific language governing permissions and limitations
  15. %% under the License.
  16. -module(lager_test_backend).
  17. -include("lager.hrl").
  18. -behaviour(gen_event).
  19. -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
  20. code_change/3]).
  21. -record(state, {level, buffer, ignored}).
  22. -compile([{parse_transform, lager_transform}]).
  23. -ifdef(TEST).
  24. -include_lib("eunit/include/eunit.hrl").
  25. -endif.
  26. init(Level) ->
  27. {ok, #state{level=lager_util:level_to_num(Level), buffer=[], ignored=[]}}.
  28. handle_call(count, #state{buffer=Buffer} = State) ->
  29. {ok, length(Buffer), State};
  30. handle_call(count_ignored, #state{ignored=Ignored} = State) ->
  31. {ok, length(Ignored), State};
  32. handle_call(flush, State) ->
  33. {ok, ok, State#state{buffer=[], ignored=[]}};
  34. handle_call(pop, #state{buffer=Buffer} = State) ->
  35. case Buffer of
  36. [] ->
  37. {ok, undefined, State};
  38. [H|T] ->
  39. {ok, H, State#state{buffer=T}}
  40. end;
  41. handle_call(get_loglevel, #state{level=Level} = State) ->
  42. {ok, Level, State};
  43. handle_call({set_loglevel, Level}, State) ->
  44. {ok, ok, State#state{level=lager_util:level_to_num(Level)}};
  45. handle_call(_Request, State) ->
  46. {ok, ok, State}.
  47. handle_event({log, Level, Time, Message}, #state{level=LogLevel,
  48. buffer=Buffer} = State) when Level =< LogLevel ->
  49. {ok, State#state{buffer=Buffer ++ [{Level, Time, Message}]}};
  50. handle_event({log, _Level, _Time, _Message}, #state{ignored=Ignored} = State) ->
  51. {ok, State#state{ignored=Ignored ++ [ignored]}};
  52. handle_event(_Event, State) ->
  53. {ok, State}.
  54. handle_info(_Info, State) ->
  55. {ok, State}.
  56. terminate(_Reason, _State) ->
  57. ok.
  58. code_change(_OldVsn, State, _Extra) ->
  59. {ok, State}.
  60. -ifdef(TEST).
  61. pop() ->
  62. gen_event:call(lager_event, ?MODULE, pop).
  63. count() ->
  64. gen_event:call(lager_event, ?MODULE, count).
  65. count_ignored() ->
  66. gen_event:call(lager_event, ?MODULE, count_ignored).
  67. not_running_test() ->
  68. ?assertEqual({error, lager_not_running}, lager:log(info, self(), "not running")).
  69. lager_test_() ->
  70. {foreach,
  71. fun setup/0,
  72. fun cleanup/1,
  73. [
  74. {"observe that there is nothing up my sleeve",
  75. fun() ->
  76. ?assertEqual(undefined, pop()),
  77. ?assertEqual(0, count())
  78. end
  79. },
  80. {"logging works",
  81. fun() ->
  82. lager:warning("test message"),
  83. ?assertEqual(1, count()),
  84. {Level, _Time, Message} = pop(),
  85. ?assertMatch(Level, lager_util:level_to_num(warning)),
  86. [LevelStr, _LocStr, MsgStr] = re:split(Message, " ", [{return, list}, {parts, 3}]),
  87. ?assertEqual("[warning]", LevelStr),
  88. ?assertEqual("test message", MsgStr),
  89. ok
  90. end
  91. },
  92. {"logging with arguments works",
  93. fun() ->
  94. lager:warning("test message ~p", [self()]),
  95. ?assertEqual(1, count()),
  96. {Level, _Time, Message} = pop(),
  97. ?assertMatch(Level, lager_util:level_to_num(warning)),
  98. [LevelStr, _LocStr, MsgStr] = re:split(Message, " ", [{return, list}, {parts, 3}]),
  99. ?assertEqual("[warning]", LevelStr),
  100. ?assertEqual(lists:flatten(io_lib:format("test message ~p", [self()])), MsgStr),
  101. ok
  102. end
  103. },
  104. {"logging works from inside a begin/end block",
  105. fun() ->
  106. ?assertEqual(0, count()),
  107. begin
  108. lager:warning("test message 2")
  109. end,
  110. ?assertEqual(1, count()),
  111. ok
  112. end
  113. },
  114. {"logging works from inside a list comprehension",
  115. fun() ->
  116. ?assertEqual(0, count()),
  117. [lager:warning("test message") || _N <- lists:seq(1, 10)],
  118. ?assertEqual(10, count()),
  119. ok
  120. end
  121. },
  122. {"logging works from a begin/end block inside a list comprehension",
  123. fun() ->
  124. ?assertEqual(0, count()),
  125. [ begin lager:warning("test message") end || _N <- lists:seq(1, 10)],
  126. ?assertEqual(10, count()),
  127. ok
  128. end
  129. },
  130. {"logging works from a nested list comprehension",
  131. fun() ->
  132. ?assertEqual(0, count()),
  133. [ [lager:warning("test message") || _N <- lists:seq(1, 10)] ||
  134. _I <- lists:seq(1, 10)],
  135. ?assertEqual(100, count()),
  136. ok
  137. end
  138. },
  139. {"log messages below the threshold are ignored",
  140. fun() ->
  141. ?assertEqual(0, count()),
  142. lager:debug("this message will be ignored"),
  143. ?assertEqual(0, count()),
  144. ?assertEqual(0, count_ignored()),
  145. lager_mochiglobal:put(loglevel, ?DEBUG),
  146. lager:debug("this message should be ignored"),
  147. ?assertEqual(0, count()),
  148. ?assertEqual(1, count_ignored()),
  149. lager:set_loglevel(?MODULE, debug),
  150. lager:debug("this message should be logged"),
  151. ?assertEqual(1, count()),
  152. ?assertEqual(1, count_ignored()),
  153. ?assertEqual(debug, lager:get_loglevel(?MODULE)),
  154. ok
  155. end
  156. }
  157. ]
  158. }.
  159. setup() ->
  160. error_logger:tty(false),
  161. application:load(lager),
  162. application:set_env(lager, handlers, [{?MODULE, info}]),
  163. application:set_env(lager, error_logger_redirect, false),
  164. application:start(lager),
  165. gen_event:call(lager_event, ?MODULE, flush).
  166. cleanup(_) ->
  167. application:stop(lager),
  168. application:unload(lager),
  169. error_logger:tty(true).
  170. crash(Type) ->
  171. spawn(fun() -> gen_server:call(crash, Type) end),
  172. timer:sleep(100).
  173. custom_sleep(MSec) ->
  174. timer:sleep(MSec),
  175. [_|_] = gen_event:which_handlers(error_logger),
  176. [_|_] = gen_event:which_handlers(lager_event),
  177. ok.
  178. error_logger_redirect_crash_test_() ->
  179. {foreach,
  180. fun() ->
  181. error_logger:tty(false),
  182. application:load(lager),
  183. application:set_env(lager, error_logger_redirect, true),
  184. application:set_env(lager, handlers, [{?MODULE, error}]),
  185. application:start(lager),
  186. crash:start()
  187. end,
  188. fun(_) ->
  189. application:stop(lager),
  190. application:unload(lager),
  191. case whereis(crash) of
  192. undefined -> ok;
  193. Pid -> exit(Pid, kill)
  194. end,
  195. error_logger:tty(true)
  196. end,
  197. [
  198. {"again, there is nothing up my sleeve",
  199. fun() ->
  200. ?assertEqual(undefined, pop()),
  201. ?assertEqual(0, count())
  202. end
  203. },
  204. {"bad return value",
  205. fun() ->
  206. Pid = whereis(crash),
  207. crash(bad_return),
  208. {_, _, Msg} = pop(),
  209. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad return value: bleh", [Pid])),
  210. ?assertEqual(Expected, lists:flatten(Msg))
  211. end
  212. },
  213. {"case clause",
  214. fun() ->
  215. Pid = whereis(crash),
  216. crash(case_clause),
  217. {_, _, Msg} = pop(),
  218. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no case clause matching {} in crash:handle_call/3", [Pid])),
  219. ?assertEqual(Expected, lists:flatten(Msg))
  220. end
  221. },
  222. {"function clause",
  223. fun() ->
  224. Pid = whereis(crash),
  225. crash(function_clause),
  226. {_, _, Msg} = pop(),
  227. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no function clause matching crash:function({})", [Pid])),
  228. ?assertEqual(Expected, lists:flatten(Msg))
  229. end
  230. },
  231. {"if clause",
  232. fun() ->
  233. Pid = whereis(crash),
  234. crash(if_clause),
  235. {_, _, Msg} = pop(),
  236. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no true branch found while evaluating if expression in crash:handle_call/3", [Pid])),
  237. ?assertEqual(Expected, lists:flatten(Msg))
  238. end
  239. },
  240. {"try clause",
  241. fun() ->
  242. Pid = whereis(crash),
  243. crash(try_clause),
  244. {_, _, Msg} = pop(),
  245. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no try clause matching [] in crash:handle_call/3", [Pid])),
  246. ?assertEqual(Expected, lists:flatten(Msg))
  247. end
  248. },
  249. {"undefined function",
  250. fun() ->
  251. Pid = whereis(crash),
  252. crash(undef),
  253. {_, _, Msg} = pop(),
  254. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: call to undefined function crash:booger/0 from crash:handle_call/3", [Pid])),
  255. ?assertEqual(Expected, lists:flatten(Msg))
  256. end
  257. },
  258. {"bad math",
  259. fun() ->
  260. Pid = whereis(crash),
  261. crash(badarith),
  262. {_, _, Msg} = pop(),
  263. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad arithmetic expression in crash:handle_call/3", [Pid])),
  264. ?assertEqual(Expected, lists:flatten(Msg))
  265. end
  266. },
  267. {"bad match",
  268. fun() ->
  269. Pid = whereis(crash),
  270. crash(badmatch),
  271. {_, _, Msg} = pop(),
  272. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no match of right hand value {} in crash:handle_call/3", [Pid])),
  273. ?assertEqual(Expected, lists:flatten(Msg))
  274. end
  275. },
  276. {"bad arity",
  277. fun() ->
  278. Pid = whereis(crash),
  279. crash(badarity),
  280. {_, _, Msg} = pop(),
  281. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: fun called with wrong arity of 1 instead of 3 in crash:handle_call/3", [Pid])),
  282. ?assertEqual(Expected, lists:flatten(Msg))
  283. end
  284. },
  285. {"bad arg1",
  286. fun() ->
  287. Pid = whereis(crash),
  288. crash(badarg1),
  289. {_, _, Msg} = pop(),
  290. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad argument in crash:handle_call/3", [Pid])),
  291. ?assertEqual(Expected, lists:flatten(Msg))
  292. end
  293. },
  294. {"bad arg2",
  295. fun() ->
  296. Pid = whereis(crash),
  297. crash(badarg2),
  298. {_, _, Msg} = pop(),
  299. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad argument in call to erlang:iolist_to_binary([[102,111,111],bar]) in crash:handle_call/3", [Pid])),
  300. ?assertEqual(Expected, lists:flatten(Msg))
  301. end
  302. },
  303. {"noproc",
  304. fun() ->
  305. Pid = whereis(crash),
  306. crash(noproc),
  307. {_, _, Msg} = pop(),
  308. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no such process or port in call to gen_event:call(foo, bar, baz)", [Pid])),
  309. ?assertEqual(Expected, lists:flatten(Msg))
  310. end
  311. },
  312. {"badfun",
  313. fun() ->
  314. Pid = whereis(crash),
  315. crash(badfun),
  316. {_, _, Msg} = pop(),
  317. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad function booger in crash:handle_call/3", [Pid])),
  318. ?assertEqual(Expected, lists:flatten(Msg))
  319. end
  320. }
  321. ]
  322. }.
  323. error_logger_redirect_test_() ->
  324. {foreach,
  325. fun() ->
  326. error_logger:tty(false),
  327. application:load(lager),
  328. application:set_env(lager, error_logger_redirect, true),
  329. application:set_env(lager, handlers, [{?MODULE, info}]),
  330. application:start(lager),
  331. timer:sleep(100),
  332. gen_event:call(lager_event, ?MODULE, flush)
  333. end,
  334. fun(_) ->
  335. application:stop(lager),
  336. application:unload(lager),
  337. error_logger:tty(true)
  338. end,
  339. [
  340. {"error reports are printed",
  341. fun() ->
  342. error_logger:error_report([{this, is}, a, {silly, format}]),
  343. custom_sleep(100),
  344. {_, _, Msg} = pop(),
  345. Expected = lists:flatten(io_lib:format("[error] ~w this: is, a, silly: format", [self()])),
  346. ?assertEqual(Expected, lists:flatten(Msg))
  347. end
  348. },
  349. {"string error reports are printed",
  350. fun() ->
  351. error_logger:error_report("this is less silly"),
  352. custom_sleep(100),
  353. {_, _, Msg} = pop(),
  354. Expected = lists:flatten(io_lib:format("[error] ~w this is less silly", [self()])),
  355. ?assertEqual(Expected, lists:flatten(Msg))
  356. end
  357. },
  358. {"error messages are printed",
  359. fun() ->
  360. error_logger:error_msg("doom, doom has come upon you all"),
  361. custom_sleep(100),
  362. {_, _, Msg} = pop(),
  363. Expected = lists:flatten(io_lib:format("[error] ~w doom, doom has come upon you all", [self()])),
  364. ?assertEqual(Expected, lists:flatten(Msg))
  365. end
  366. },
  367. {"error messages are truncated at 4096 characters",
  368. fun() ->
  369. error_logger:error_msg("doom, doom has come upon you all ~p", [string:copies("doom", 10000)]),
  370. custom_sleep(1000),
  371. {_, _, Msg} = pop(),
  372. ?assert(length(lists:flatten(Msg)) < 5100)
  373. end
  374. },
  375. {"info reports are printed",
  376. fun() ->
  377. error_logger:info_report([{this, is}, a, {silly, format}]),
  378. custom_sleep(100),
  379. {_, _, Msg} = pop(),
  380. Expected = lists:flatten(io_lib:format("[info] ~w this: is, a, silly: format", [self()])),
  381. ?assertEqual(Expected, lists:flatten(Msg))
  382. end
  383. },
  384. {"info reports are truncated at 4096 characters",
  385. fun() ->
  386. error_logger:info_report([[{this, is}, a, {silly, format}] || _ <- lists:seq(0, 600)]),
  387. custom_sleep(1000),
  388. {_, _, Msg} = pop(),
  389. ?assert(length(lists:flatten(Msg)) < 5000)
  390. end
  391. },
  392. {"single term info reports are printed",
  393. fun() ->
  394. error_logger:info_report({foolish, bees}),
  395. custom_sleep(100),
  396. {_, _, Msg} = pop(),
  397. Expected = lists:flatten(io_lib:format("[info] ~w {foolish,bees}", [self()])),
  398. ?assertEqual(Expected, lists:flatten(Msg))
  399. end
  400. },
  401. {"single term error reports are printed",
  402. fun() ->
  403. error_logger:error_report({foolish, bees}),
  404. custom_sleep(100),
  405. {_, _, Msg} = pop(),
  406. Expected = lists:flatten(io_lib:format("[error] ~w {foolish,bees}", [self()])),
  407. ?assertEqual(Expected, lists:flatten(Msg))
  408. end
  409. },
  410. {"string info reports are printed",
  411. fun() ->
  412. error_logger:info_report("this is less silly"),
  413. custom_sleep(100),
  414. {_, _, Msg} = pop(),
  415. Expected = lists:flatten(io_lib:format("[info] ~w this is less silly", [self()])),
  416. ?assertEqual(Expected, lists:flatten(Msg))
  417. end
  418. },
  419. {"string info reports are truncated at 4096 characters",
  420. fun() ->
  421. error_logger:info_report(string:copies("this is less silly", 1000)),
  422. custom_sleep(1000),
  423. {_, _, Msg} = pop(),
  424. ?assert(length(lists:flatten(Msg)) < 5100)
  425. end
  426. },
  427. {"info messages are printed",
  428. fun() ->
  429. error_logger:info_msg("doom, doom has come upon you all"),
  430. custom_sleep(100),
  431. {_, _, Msg} = pop(),
  432. Expected = lists:flatten(io_lib:format("[info] ~w doom, doom has come upon you all", [self()])),
  433. ?assertEqual(Expected, lists:flatten(Msg))
  434. end
  435. },
  436. {"info messages are truncated at 4096 characters",
  437. fun() ->
  438. error_logger:info_msg("doom, doom has come upon you all ~p", [string:copies("doom", 10000)]),
  439. custom_sleep(1000),
  440. {_, _, Msg} = pop(),
  441. ?assert(length(lists:flatten(Msg)) < 5100)
  442. end
  443. },
  444. {"warning messages are printed at the correct level",
  445. fun() ->
  446. error_logger:warning_msg("doom, doom has come upon you all"),
  447. Map = error_logger:warning_map(),
  448. custom_sleep(100),
  449. {_, _, Msg} = pop(),
  450. Expected = lists:flatten(io_lib:format("[~w] ~w doom, doom has come upon you all", [Map, self()])),
  451. ?assertEqual(Expected, lists:flatten(Msg))
  452. end
  453. },
  454. {"warning reports are printed at the correct level",
  455. fun() ->
  456. error_logger:warning_report([{i, like}, pie]),
  457. Map = error_logger:warning_map(),
  458. custom_sleep(100),
  459. {_, _, Msg} = pop(),
  460. Expected = lists:flatten(io_lib:format("[~w] ~w i: like, pie", [Map, self()])),
  461. ?assertEqual(Expected, lists:flatten(Msg))
  462. end
  463. },
  464. {"single term warning reports are printed at the correct level",
  465. fun() ->
  466. error_logger:warning_report({foolish, bees}),
  467. Map = error_logger:warning_map(),
  468. custom_sleep(100),
  469. {_, _, Msg} = pop(),
  470. Expected = lists:flatten(io_lib:format("[~w] ~w {foolish,bees}", [Map, self()])),
  471. ?assertEqual(Expected, lists:flatten(Msg))
  472. end
  473. },
  474. {"application stop reports",
  475. fun() ->
  476. error_logger:info_report([{application, foo}, {exited, quittin_time}, {type, lazy}]),
  477. custom_sleep(100),
  478. {_, _, Msg} = pop(),
  479. Expected = lists:flatten(io_lib:format("[info] ~w Application foo exited with reason: quittin_time", [self()])),
  480. ?assertEqual(Expected, lists:flatten(Msg))
  481. end
  482. },
  483. {"supervisor reports",
  484. fun() ->
  485. error_logger:error_report(supervisor_report, [{errorContext, france}, {offender, [{name, mini_steve}, {mfargs, {a, b, [c]}}, {pid, bleh}]}, {reason, fired}, {supervisor, {local, steve}}]),
  486. custom_sleep(100),
  487. {_, _, Msg} = pop(),
  488. Expected = lists:flatten(io_lib:format("[error] ~w Supervisor steve had child mini_steve started with a:b(c) at bleh exit with reason fired in context france", [self()])),
  489. ?assertEqual(Expected, lists:flatten(Msg))
  490. end
  491. },
  492. {"supervisor reports with real error",
  493. fun() ->
  494. error_logger:error_report(supervisor_report, [{errorContext, france}, {offender, [{name, mini_steve}, {mfargs, {a, b, [c]}}, {pid, bleh}]}, {reason, {function_clause,[{crash,handle_info,[foo]}]}}, {supervisor, {local, steve}}]),
  495. custom_sleep(100),
  496. {_, _, Msg} = pop(),
  497. Expected = lists:flatten(io_lib:format("[error] ~w Supervisor steve had child mini_steve started with a:b(c) at bleh exit with reason no function clause matching crash:handle_info(foo) in context france", [self()])),
  498. ?assertEqual(Expected, lists:flatten(Msg))
  499. end
  500. },
  501. {"supervisor_bridge reports",
  502. fun() ->
  503. error_logger:error_report(supervisor_report, [{errorContext, france}, {offender, [{mod, mini_steve}, {pid, bleh}]}, {reason, fired}, {supervisor, {local, steve}}]),
  504. custom_sleep(100),
  505. {_, _, Msg} = pop(),
  506. Expected = lists:flatten(io_lib:format("[error] ~w Supervisor steve had child at module mini_steve at bleh exit with reason fired in context france", [self()])),
  507. ?assertEqual(Expected, lists:flatten(Msg))
  508. end
  509. },
  510. {"application progress report",
  511. fun() ->
  512. error_logger:info_report(progress, [{application, foo}, {started_at, node()}]),
  513. custom_sleep(100),
  514. {_, _, Msg} = pop(),
  515. Expected = lists:flatten(io_lib:format("[info] ~w Application foo started on node ~w", [self(), node()])),
  516. ?assertEqual(Expected, lists:flatten(Msg))
  517. end
  518. },
  519. {"supervisor progress report",
  520. fun() ->
  521. lager:set_loglevel(?MODULE, debug),
  522. error_logger:info_report(progress, [{supervisor, {local, foo}}, {started, [{mfargs, {foo, bar, 1}}, {pid, baz}]}]),
  523. custom_sleep(100),
  524. {_, _, Msg} = pop(),
  525. Expected = lists:flatten(io_lib:format("[debug] ~w Supervisor foo started foo:bar/1 at pid baz", [self()])),
  526. ?assertEqual(Expected, lists:flatten(Msg))
  527. end
  528. },
  529. {"crash report for emfile",
  530. fun() ->
  531. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {emfile, [{stack, trace, 1}]}, []}}], []]),
  532. custom_sleep(100),
  533. {_, _, Msg} = pop(),
  534. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: maximum number of file descriptors exhausted, check ulimit -n", [self(), self()])),
  535. ?assertEqual(Expected, lists:flatten(Msg))
  536. end
  537. },
  538. {"crash report for system process limit",
  539. fun() ->
  540. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, spawn, 1}]}, []}}], []]),
  541. custom_sleep(100),
  542. {_, _, Msg} = pop(),
  543. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded", [self(), self()])),
  544. ?assertEqual(Expected, lists:flatten(Msg))
  545. end
  546. },
  547. {"crash report for system process limit2",
  548. fun() ->
  549. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, spawn_opt, 1}]}, []}}], []]),
  550. custom_sleep(100),
  551. {_, _, Msg} = pop(),
  552. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of processes exceeded", [self(), self()])),
  553. ?assertEqual(Expected, lists:flatten(Msg))
  554. end
  555. },
  556. {"crash report for system port limit",
  557. fun() ->
  558. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, open_port, 1}]}, []}}], []]),
  559. custom_sleep(100),
  560. {_, _, Msg} = pop(),
  561. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ports exceeded", [self(), self()])),
  562. ?assertEqual(Expected, lists:flatten(Msg))
  563. end
  564. },
  565. {"crash report for system port limit",
  566. fun() ->
  567. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, list_to_atom, 1}]}, []}}], []]),
  568. custom_sleep(100),
  569. {_, _, Msg} = pop(),
  570. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: tried to create an atom larger than 255, or maximum atom count exceeded", [self(), self()])),
  571. ?assertEqual(Expected, lists:flatten(Msg))
  572. end
  573. },
  574. {"crash report for system ets table limit",
  575. fun() ->
  576. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit,[{ets,new,[segment_offsets,[ordered_set,public]]},{mi_segment,open_write,1},{mi_buffer_converter,handle_cast,2},{gen_server,handle_msg,5},{proc_lib,init_p_do_apply,3}]}, []}}], []]),
  577. custom_sleep(100),
  578. {_, _, Msg} = pop(),
  579. Expected = lists:flatten(io_lib:format("[error] ~w CRASH REPORT Process ~w with 0 neighbours crashed with reason: system limit: maximum number of ETS tables exceeded", [self(), self()])),
  580. ?assertEqual(Expected, lists:flatten(Msg))
  581. end
  582. },
  583. {"crash report for unknown system limit should be truncated at 500 characters",
  584. fun() ->
  585. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit,[{wtf,boom,[string:copies("aaaa", 4096)]}]}, []}}], []]),
  586. custom_sleep(1000),
  587. {_, _, Msg} = pop(),
  588. ?assert(length(lists:flatten(Msg)) > 500),
  589. ?assert(length(lists:flatten(Msg)) < 700)
  590. end
  591. },
  592. {"messages should not be generated if they don't satisfy the threshold",
  593. fun() ->
  594. lager:set_loglevel(?MODULE, error),
  595. error_logger:info_report([hello, world]),
  596. custom_sleep(100),
  597. ?assertEqual(0, count()),
  598. ?assertEqual(0, count_ignored()),
  599. lager:set_loglevel(?MODULE, info),
  600. error_logger:info_report([hello, world]),
  601. custom_sleep(100),
  602. ?assertEqual(1, count()),
  603. ?assertEqual(0, count_ignored()),
  604. lager:set_loglevel(?MODULE, error),
  605. lager_mochiglobal:put(loglevel, ?DEBUG),
  606. error_logger:info_report([hello, world]),
  607. custom_sleep(100),
  608. ?assertEqual(1, count()),
  609. ?assertEqual(1, count_ignored())
  610. end
  611. }
  612. ]
  613. }.
  614. -endif.