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

669 行
32 KiB

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