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

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