Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

642 lignes
30 KiB

il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
il y a 14 ans
  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, wtf, "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. error_logger_redirect_crash_test_() ->
  174. {foreach,
  175. fun() ->
  176. error_logger:tty(false),
  177. application:load(lager),
  178. application:set_env(lager, error_logger_redirect, true),
  179. application:set_env(lager, handlers, [{?MODULE, error}]),
  180. application:start(lager),
  181. crash:start()
  182. end,
  183. fun(_) ->
  184. application:stop(lager),
  185. application:unload(lager),
  186. case whereis(crash) of
  187. undefined -> ok;
  188. Pid -> exit(Pid, kill)
  189. end,
  190. error_logger:tty(true)
  191. end,
  192. [
  193. {"again, there is nothing up my sleeve",
  194. fun() ->
  195. ?assertEqual(undefined, pop()),
  196. ?assertEqual(0, count())
  197. end
  198. },
  199. {"bad return value",
  200. fun() ->
  201. Pid = whereis(crash),
  202. crash(bad_return),
  203. {_, _, Msg} = pop(),
  204. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad return value: bleh", [Pid])),
  205. ?assertEqual(Expected, lists:flatten(Msg))
  206. end
  207. },
  208. {"case clause",
  209. fun() ->
  210. Pid = whereis(crash),
  211. crash(case_clause),
  212. {_, _, Msg} = pop(),
  213. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no case clause matching {} in crash:handle_call/3", [Pid])),
  214. ?assertEqual(Expected, lists:flatten(Msg))
  215. end
  216. },
  217. {"function clause",
  218. fun() ->
  219. Pid = whereis(crash),
  220. crash(function_clause),
  221. {_, _, Msg} = pop(),
  222. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no function clause matching crash:function({})", [Pid])),
  223. ?assertEqual(Expected, lists:flatten(Msg))
  224. end
  225. },
  226. {"if clause",
  227. fun() ->
  228. Pid = whereis(crash),
  229. crash(if_clause),
  230. {_, _, Msg} = pop(),
  231. 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])),
  232. ?assertEqual(Expected, lists:flatten(Msg))
  233. end
  234. },
  235. {"try clause",
  236. fun() ->
  237. Pid = whereis(crash),
  238. crash(try_clause),
  239. {_, _, Msg} = pop(),
  240. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: no try clause matching [] in crash:handle_call/3", [Pid])),
  241. ?assertEqual(Expected, lists:flatten(Msg))
  242. end
  243. },
  244. {"undefined function",
  245. fun() ->
  246. Pid = whereis(crash),
  247. crash(undef),
  248. {_, _, Msg} = pop(),
  249. 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])),
  250. ?assertEqual(Expected, lists:flatten(Msg))
  251. end
  252. },
  253. {"bad math",
  254. fun() ->
  255. Pid = whereis(crash),
  256. crash(badarith),
  257. {_, _, Msg} = pop(),
  258. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad arithmetic expression in crash:handle_call/3", [Pid])),
  259. ?assertEqual(Expected, lists:flatten(Msg))
  260. end
  261. },
  262. {"bad match",
  263. fun() ->
  264. Pid = whereis(crash),
  265. crash(badmatch),
  266. {_, _, Msg} = pop(),
  267. 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])),
  268. ?assertEqual(Expected, lists:flatten(Msg))
  269. end
  270. },
  271. {"bad arity",
  272. fun() ->
  273. Pid = whereis(crash),
  274. crash(badarity),
  275. {_, _, Msg} = pop(),
  276. 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])),
  277. ?assertEqual(Expected, lists:flatten(Msg))
  278. end
  279. },
  280. {"bad arg1",
  281. fun() ->
  282. Pid = whereis(crash),
  283. crash(badarg1),
  284. {_, _, Msg} = pop(),
  285. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad argument in crash:handle_call/3", [Pid])),
  286. ?assertEqual(Expected, lists:flatten(Msg))
  287. end
  288. },
  289. {"bad arg2",
  290. fun() ->
  291. Pid = whereis(crash),
  292. crash(badarg2),
  293. {_, _, Msg} = pop(),
  294. 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])),
  295. ?assertEqual(Expected, lists:flatten(Msg))
  296. end
  297. },
  298. {"noproc",
  299. fun() ->
  300. Pid = whereis(crash),
  301. crash(noproc),
  302. {_, _, Msg} = pop(),
  303. 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])),
  304. ?assertEqual(Expected, lists:flatten(Msg))
  305. end
  306. },
  307. {"badfun",
  308. fun() ->
  309. Pid = whereis(crash),
  310. crash(badfun),
  311. {_, _, Msg} = pop(),
  312. Expected = lists:flatten(io_lib:format("[error] ~w gen_server crash terminated with reason: bad function booger in crash:handle_call/3", [Pid])),
  313. ?assertEqual(Expected, lists:flatten(Msg))
  314. end
  315. }
  316. ]
  317. }.
  318. error_logger_redirect_test_() ->
  319. {foreach,
  320. fun() ->
  321. error_logger:tty(false),
  322. application:load(lager),
  323. application:set_env(lager, error_logger_redirect, true),
  324. application:set_env(lager, handlers, [{?MODULE, info}]),
  325. application:start(lager),
  326. timer:sleep(100),
  327. gen_event:call(lager_event, ?MODULE, flush)
  328. end,
  329. fun(_) ->
  330. application:stop(lager),
  331. application:unload(lager),
  332. error_logger:tty(true)
  333. end,
  334. [
  335. {"error reports are printed",
  336. fun() ->
  337. error_logger:error_report([{this, is}, a, {silly, format}]),
  338. timer:sleep(100),
  339. {_, _, Msg} = pop(),
  340. Expected = lists:flatten(io_lib:format("[error] ~w this: is, a, silly: format", [self()])),
  341. ?assertEqual(Expected, lists:flatten(Msg))
  342. end
  343. },
  344. {"string error reports are printed",
  345. fun() ->
  346. error_logger:error_report("this is less silly"),
  347. timer:sleep(100),
  348. {_, _, Msg} = pop(),
  349. Expected = lists:flatten(io_lib:format("[error] ~w this is less silly", [self()])),
  350. ?assertEqual(Expected, lists:flatten(Msg))
  351. end
  352. },
  353. {"error messages are printed",
  354. fun() ->
  355. error_logger:error_msg("doom, doom has come upon you all"),
  356. timer:sleep(100),
  357. {_, _, Msg} = pop(),
  358. Expected = lists:flatten(io_lib:format("[error] ~w doom, doom has come upon you all", [self()])),
  359. ?assertEqual(Expected, lists:flatten(Msg))
  360. end
  361. },
  362. {"error messages are truncated at 4096 characters",
  363. fun() ->
  364. error_logger:error_msg("doom, doom has come upon you all ~p", [string:copies("doom", 10000)]),
  365. timer:sleep(100),
  366. {_, _, Msg} = pop(),
  367. ?assert(length(lists:flatten(Msg)) < 5100)
  368. end
  369. },
  370. {"info reports are printed",
  371. fun() ->
  372. error_logger:info_report([{this, is}, a, {silly, format}]),
  373. timer:sleep(100),
  374. {_, _, Msg} = pop(),
  375. Expected = lists:flatten(io_lib:format("[info] ~w this: is, a, silly: format", [self()])),
  376. ?assertEqual(Expected, lists:flatten(Msg))
  377. end
  378. },
  379. {"info reports are truncated at 4096 characters",
  380. fun() ->
  381. error_logger:info_report([[{this, is}, a, {silly, format}] || _ <- lists:seq(0, 600)]),
  382. timer:sleep(1000),
  383. {_, _, Msg} = pop(),
  384. ?assert(length(lists:flatten(Msg)) < 5000)
  385. end
  386. },
  387. {"single term info reports are printed",
  388. fun() ->
  389. error_logger:info_report({foolish, bees}),
  390. timer:sleep(100),
  391. {_, _, Msg} = pop(),
  392. Expected = lists:flatten(io_lib:format("[info] ~w {foolish,bees}", [self()])),
  393. ?assertEqual(Expected, lists:flatten(Msg))
  394. end
  395. },
  396. {"single term error reports are printed",
  397. fun() ->
  398. error_logger:error_report({foolish, bees}),
  399. timer:sleep(100),
  400. {_, _, Msg} = pop(),
  401. Expected = lists:flatten(io_lib:format("[error] ~w {foolish,bees}", [self()])),
  402. ?assertEqual(Expected, lists:flatten(Msg))
  403. end
  404. },
  405. {"string info reports are printed",
  406. fun() ->
  407. error_logger:info_report("this is less silly"),
  408. timer:sleep(100),
  409. {_, _, Msg} = pop(),
  410. Expected = lists:flatten(io_lib:format("[info] ~w this is less silly", [self()])),
  411. ?assertEqual(Expected, lists:flatten(Msg))
  412. end
  413. },
  414. {"string info reports are truncated at 4096 characters",
  415. fun() ->
  416. error_logger:info_report(string:copies("this is less silly", 1000)),
  417. timer:sleep(100),
  418. {_, _, Msg} = pop(),
  419. ?assert(length(lists:flatten(Msg)) < 5100)
  420. end
  421. },
  422. {"info messages are printed",
  423. fun() ->
  424. error_logger:info_msg("doom, doom has come upon you all"),
  425. timer:sleep(100),
  426. {_, _, Msg} = pop(),
  427. Expected = lists:flatten(io_lib:format("[info] ~w doom, doom has come upon you all", [self()])),
  428. ?assertEqual(Expected, lists:flatten(Msg))
  429. end
  430. },
  431. {"info messages are truncated at 4096 characters",
  432. fun() ->
  433. error_logger:info_msg("doom, doom has come upon you all ~p", [string:copies("doom", 10000)]),
  434. timer:sleep(100),
  435. {_, _, Msg} = pop(),
  436. ?assert(length(lists:flatten(Msg)) < 5100)
  437. end
  438. },
  439. {"warning messages are printed at the correct level",
  440. fun() ->
  441. error_logger:warning_msg("doom, doom has come upon you all"),
  442. Map = error_logger:warning_map(),
  443. timer:sleep(100),
  444. {_, _, Msg} = pop(),
  445. Expected = lists:flatten(io_lib:format("[~w] ~w doom, doom has come upon you all", [Map, self()])),
  446. ?assertEqual(Expected, lists:flatten(Msg))
  447. end
  448. },
  449. {"warning reports are printed at the correct level",
  450. fun() ->
  451. error_logger:warning_report([{i, like}, pie]),
  452. Map = error_logger:warning_map(),
  453. timer:sleep(100),
  454. {_, _, Msg} = pop(),
  455. Expected = lists:flatten(io_lib:format("[~w] ~w i: like, pie", [Map, self()])),
  456. ?assertEqual(Expected, lists:flatten(Msg))
  457. end
  458. },
  459. {"single term warning reports are printed at the correct level",
  460. fun() ->
  461. error_logger:warning_report({foolish, bees}),
  462. Map = error_logger:warning_map(),
  463. timer:sleep(100),
  464. {_, _, Msg} = pop(),
  465. Expected = lists:flatten(io_lib:format("[~w] ~w {foolish,bees}", [Map, self()])),
  466. ?assertEqual(Expected, lists:flatten(Msg))
  467. end
  468. },
  469. {"application stop reports",
  470. fun() ->
  471. error_logger:info_report([{application, foo}, {exited, quittin_time}, {type, lazy}]),
  472. timer:sleep(100),
  473. {_, _, Msg} = pop(),
  474. Expected = lists:flatten(io_lib:format("[info] ~w Application foo exited with reason: quittin_time", [self()])),
  475. ?assertEqual(Expected, lists:flatten(Msg))
  476. end
  477. },
  478. {"supervisor reports",
  479. fun() ->
  480. error_logger:error_report(supervisor_report, [{errorContext, france}, {offender, [{name, mini_steve}, {mfargs, {a, b, [c]}}, {pid, bleh}]}, {reason, fired}, {supervisor, {local, steve}}]),
  481. timer:sleep(100),
  482. {_, _, Msg} = pop(),
  483. 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()])),
  484. ?assertEqual(Expected, lists:flatten(Msg))
  485. end
  486. },
  487. {"supervisor reports with real error",
  488. fun() ->
  489. 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}}]),
  490. timer:sleep(100),
  491. {_, _, Msg} = pop(),
  492. 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()])),
  493. ?assertEqual(Expected, lists:flatten(Msg))
  494. end
  495. },
  496. {"supervisor_bridge reports",
  497. fun() ->
  498. error_logger:error_report(supervisor_report, [{errorContext, france}, {offender, [{mod, mini_steve}, {pid, bleh}]}, {reason, fired}, {supervisor, {local, steve}}]),
  499. timer:sleep(100),
  500. {_, _, Msg} = pop(),
  501. 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()])),
  502. ?assertEqual(Expected, lists:flatten(Msg))
  503. end
  504. },
  505. {"application progress report",
  506. fun() ->
  507. error_logger:info_report(progress, [{application, foo}, {started_at, node()}]),
  508. timer:sleep(100),
  509. {_, _, Msg} = pop(),
  510. Expected = lists:flatten(io_lib:format("[info] ~w Application foo started on node ~w", [self(), node()])),
  511. ?assertEqual(Expected, lists:flatten(Msg))
  512. end
  513. },
  514. {"supervisor progress report",
  515. fun() ->
  516. lager:set_loglevel(?MODULE, debug),
  517. error_logger:info_report(progress, [{supervisor, {local, foo}}, {started, [{mfargs, {foo, bar, 1}}, {pid, baz}]}]),
  518. timer:sleep(100),
  519. {_, _, Msg} = pop(),
  520. Expected = lists:flatten(io_lib:format("[debug] ~w Supervisor foo started foo:bar/1 at pid baz", [self()])),
  521. ?assertEqual(Expected, lists:flatten(Msg))
  522. end
  523. },
  524. {"crash report for emfile",
  525. fun() ->
  526. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {emfile, [{stack, trace, 1}]}, []}}], []]),
  527. timer:sleep(100),
  528. {_, _, Msg} = pop(),
  529. 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()])),
  530. ?assertEqual(Expected, lists:flatten(Msg))
  531. end
  532. },
  533. {"crash report for system process limit",
  534. fun() ->
  535. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, spawn, 1}]}, []}}], []]),
  536. timer:sleep(100),
  537. {_, _, Msg} = pop(),
  538. 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()])),
  539. ?assertEqual(Expected, lists:flatten(Msg))
  540. end
  541. },
  542. {"crash report for system process limit2",
  543. fun() ->
  544. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, spawn_opt, 1}]}, []}}], []]),
  545. timer:sleep(100),
  546. {_, _, Msg} = pop(),
  547. 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()])),
  548. ?assertEqual(Expected, lists:flatten(Msg))
  549. end
  550. },
  551. {"crash report for system port limit",
  552. fun() ->
  553. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, open_port, 1}]}, []}}], []]),
  554. timer:sleep(100),
  555. {_, _, Msg} = pop(),
  556. 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()])),
  557. ?assertEqual(Expected, lists:flatten(Msg))
  558. end
  559. },
  560. {"crash report for system port limit",
  561. fun() ->
  562. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit, [{erlang, list_to_atom, 1}]}, []}}], []]),
  563. timer:sleep(100),
  564. {_, _, Msg} = pop(),
  565. 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()])),
  566. ?assertEqual(Expected, lists:flatten(Msg))
  567. end
  568. },
  569. {"crash report for system ets table limit",
  570. fun() ->
  571. 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}]}, []}}], []]),
  572. timer:sleep(100),
  573. {_, _, Msg} = pop(),
  574. 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()])),
  575. ?assertEqual(Expected, lists:flatten(Msg))
  576. end
  577. },
  578. {"crash report for unknown system limit should be truncated at 500 characters",
  579. fun() ->
  580. error_logger:error_report(crash_report, [[{pid, self()}, {error_info, {error, {system_limit,[{wtf,boom,[string:copies("aaaa", 4096)]}]}, []}}], []]),
  581. timer:sleep(100),
  582. {_, _, Msg} = pop(),
  583. ?assert(length(lists:flatten(Msg)) > 500),
  584. ?assert(length(lists:flatten(Msg)) < 700)
  585. end
  586. },
  587. {"messages should not be generated if they don't satisfy the threshold",
  588. fun() ->
  589. lager:set_loglevel(?MODULE, error),
  590. error_logger:info_report([hello, world]),
  591. timer:sleep(100),
  592. ?assertEqual(0, count()),
  593. ?assertEqual(0, count_ignored()),
  594. lager:set_loglevel(?MODULE, info),
  595. error_logger:info_report([hello, world]),
  596. timer:sleep(100),
  597. ?assertEqual(1, count()),
  598. ?assertEqual(0, count_ignored()),
  599. lager:set_loglevel(?MODULE, error),
  600. lager_mochiglobal:put(loglevel, ?DEBUG),
  601. error_logger:info_report([hello, world]),
  602. timer:sleep(100),
  603. ?assertEqual(1, count()),
  604. ?assertEqual(1, count_ignored())
  605. end
  606. }
  607. ]
  608. }.
  609. -endif.