From 985c680709662aab89f5665ddc24e7b1296db900 Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Sun, 7 Feb 2021 12:53:59 +0000 Subject: [PATCH 1/5] Properly fetch opaque info. --- src/lager_transform.erl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/lager_transform.erl b/src/lager_transform.erl index a2d26c5e..a6496c78 100644 --- a/src/lager_transform.erl +++ b/src/lager_transform.erl @@ -267,11 +267,8 @@ handle_args(DefaultAttrs, Line, [Arg1, Arg2]) -> handle_args(DefaultAttrs, _Line, [Attrs, Format, Args]) -> {concat_lists(Attrs, DefaultAttrs), Format, Args}. -make_varname(Prefix, Loc) -> - list_to_atom(Prefix ++ atom_to_list(get(module)) ++ integer_to_list(line_from_loc(Loc))). - -line_from_loc({Line, _Col}) -> Line; -line_from_loc(Line) -> Line. +make_varname(Prefix, CallAnno) -> + list_to_atom(Prefix ++ atom_to_list(get(module)) ++ integer_to_list(erl_anno:line(CallAnno))). %% concat 2 list ASTs by replacing the terminating [] in A with the contents of B concat_lists({var, Line, _Name}=Var, B) -> From e75743e7f2987b130bca87dfa3681bc1f0433b06 Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Sun, 7 Feb 2021 12:54:11 +0000 Subject: [PATCH 2/5] Make our intentions explicit A warning was issue for _App (with OTP from `master`) --- src/lager.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lager.erl b/src/lager.erl index 275bebcf..5562042f 100644 --- a/src/lager.erl +++ b/src/lager.erl @@ -80,7 +80,7 @@ start(App) -> start_ok(App, application:start(App, permanent)). start_ok(_App, ok) -> ok; -start_ok(_App, {error, {already_started, _App}}) -> ok; +start_ok(App, {error, {already_started, App}}) -> ok; start_ok(App, {error, {not_started, Dep}}) -> ok = start(Dep), start(App); From 4a9e19df89eebcef21fd008979bf47086dde8d5f Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Mon, 8 Feb 2021 01:30:21 +0000 Subject: [PATCH 3/5] Replace Travis CI with GitHub Actions --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ .travis.yml | 6 ------ README.md | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..da4bb72d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +--- +name: build +on: + push: + branches: + - master + pull_request: + branches: + - master +jobs: + ci: + name: > + Run checks and tests over ${{matrix.otp_vsn}} and ${{matrix.os}} + runs-on: ${{matrix.os}} + container: + image: erlang:${{matrix.otp_vsn}} + options: --user 1001 + strategy: + matrix: + otp_vsn: [21.3, 22.3, 23.2] + os: [ubuntu-latest] + steps: + - uses: actions/checkout@v2 + - run: rebar3 dialyzer + - run: rebar3 eunit diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9d39d94b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -sudo: false -language: erlang -otp_release: - - 23.0 - - 22.3 - - 21.3 diff --git a/README.md b/README.md index ba333ccf..087880dd 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ to provide a more traditional way to perform logging in an erlang application that plays nicely with traditional UNIX logging tools like logrotate and syslog. -[Travis-CI](http://travis-ci.org/erlang-lager/lager) :: [![Build Status](https://travis-ci.org/erlang-lager/lager.svg?branch=master)] +[![Build Status](https://github.com/erlang-lager/lager/workflows/build/badge.svg)](https://github.com/erlang-lager/lager) [![Hex pm](https://img.shields.io/hexpm/v/lager)](https://hex.pm/packages/lager) Features From dae8efc91612fe77178d0fbbeeabe9b24818691c Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Mon, 8 Feb 2021 01:11:12 +0000 Subject: [PATCH 4/5] Embrace the future --- rebar.config | 2 +- test/lager_test_backend.erl | 80 +++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/rebar.config b/rebar.config index 4578da6a..75836147 100644 --- a/rebar.config +++ b/rebar.config @@ -21,7 +21,7 @@ {erl_opts, [ {lager_extra_sinks, ['__lager_test_sink']}, - {platform_define, "^(19|20|21|22)", test_statem}, + {platform_define, "^(19|20|21|22|23|24)", test_statem}, {platform_define, "^18", 'FUNCTION_NAME', unavailable}, {platform_define, "^18", 'FUNCTION_ARITY', 0}, debug_info, diff --git a/test/lager_test_backend.erl b/test/lager_test_backend.erl index 94dd22e2..78bee6cb 100644 --- a/test/lager_test_backend.erl +++ b/test/lager_test_backend.erl @@ -305,18 +305,18 @@ lager_test_() -> lager:info(Attr, "hello ~p", Args), lager:info([{d, delta}, {g, gamma}], Fmt, Args), ?assertEqual(6, count()), - {_Level, _Time, Message, Metadata} = pop(), + {Level, _Time, Message, Metadata} = pop(), ?assertMatch([{a, alpha}, {b, beta}|_], Metadata), ?assertEqual("hello", lists:flatten(Message)), - {_Level, _Time2, Message2, _Metadata2} = pop(), + {Level, _Time2, Message2, _Metadata2} = pop(), ?assertEqual("hello world", lists:flatten(Message2)), - {_Level, _Time3, Message3, _Metadata3} = pop(), + {Level, _Time3, Message3, _Metadata3} = pop(), ?assertEqual("format world", lists:flatten(Message3)), - {_Level, _Time4, Message4, _Metadata4} = pop(), + {Level, _Time4, Message4, _Metadata4} = pop(), ?assertEqual("hello world", lists:flatten(Message4)), - {_Level, _Time5, Message5, _Metadata5} = pop(), + {Level, _Time5, Message5, _Metadata5} = pop(), ?assertEqual("hello world", lists:flatten(Message5)), - {_Level, _Time6, Message6, Metadata6} = pop(), + {Level, _Time6, Message6, Metadata6} = pop(), ?assertMatch([{d, delta}, {g, gamma}|_], Metadata6), ?assertEqual("format world", lists:flatten(Message6)), ok @@ -335,18 +335,18 @@ lager_test_() -> lager:info([{K, atom_to_list(V)} || {K, V} <- Attr], "hello ~p", [{atom, X} || X <- Args]), lager:info([{d, delta}, {g, gamma}], Fmt, [{atom, X} || X <- Args]), ?assertEqual(6, count()), - {_Level, _Time, Message, Metadata} = pop(), + {Level, _Time, Message, Metadata} = pop(), ?assertMatch([{a, "alpha"}, {b, "beta"}|_], Metadata), ?assertEqual("hello", lists:flatten(Message)), - {_Level, _Time2, Message2, _Metadata2} = pop(), + {Level, _Time2, Message2, _Metadata2} = pop(), ?assertEqual("hello {atom,world}", lists:flatten(Message2)), - {_Level, _Time3, Message3, _Metadata3} = pop(), + {Level, _Time3, Message3, _Metadata3} = pop(), ?assertEqual("format world", lists:flatten(Message3)), - {_Level, _Time4, Message4, _Metadata4} = pop(), + {Level, _Time4, Message4, _Metadata4} = pop(), ?assertEqual("hello {atom,world}", lists:flatten(Message4)), - {_Level, _Time5, Message5, _Metadata5} = pop(), + {Level, _Time5, Message5, _Metadata5} = pop(), ?assertEqual("hello {atom,world}", lists:flatten(Message5)), - {_Level, _Time6, Message6, Metadata6} = pop(), + {Level, _Time6, Message6, Metadata6} = pop(), ?assertMatch([{d, delta}, {g, gamma}|_], Metadata6), ?assertEqual("format {atom,world}", lists:flatten(Message6)), ok @@ -365,18 +365,18 @@ lager_test_() -> lager:info(fun() -> get(attrs) end(), "hello ~p", get(args)), lager:info([{d, delta}, {g, gamma}], get(format), get(args)), ?assertEqual(6, count()), - {_Level, _Time, Message, Metadata} = pop(), + {Level, _Time, Message, Metadata} = pop(), ?assertMatch([{a, alpha}, {b, beta}|_], Metadata), ?assertEqual("hello", lists:flatten(Message)), - {_Level, _Time2, Message2, _Metadata2} = pop(), + {Level, _Time2, Message2, _Metadata2} = pop(), ?assertEqual("hello world", lists:flatten(Message2)), - {_Level, _Time3, Message3, _Metadata3} = pop(), + {Level, _Time3, Message3, _Metadata3} = pop(), ?assertEqual("format world", lists:flatten(Message3)), - {_Level, _Time4, Message4, _Metadata4} = pop(), + {Level, _Time4, Message4, _Metadata4} = pop(), ?assertEqual("hello world", lists:flatten(Message4)), - {_Level, _Time5, Message5, _Metadata5} = pop(), + {Level, _Time5, Message5, _Metadata5} = pop(), ?assertEqual("hello world", lists:flatten(Message5)), - {_Level, _Time6, Message6, Metadata6} = pop(), + {Level, _Time6, Message6, Metadata6} = pop(), ?assertMatch([{d, delta}, {g, gamma}|_], Metadata6), ?assertEqual("format world", lists:flatten(Message6)), ok @@ -393,18 +393,18 @@ lager_test_() -> lager:info(Test#test.attrs, "hello ~p", Test#test.args), lager:info([{d, delta}, {g, gamma}], Test#test.format, Test#test.args), ?assertEqual(6, count()), - {_Level, _Time, Message, Metadata} = pop(), + {Level, _Time, Message, Metadata} = pop(), ?assertMatch([{a, alpha}, {b, beta}|_], Metadata), ?assertEqual("hello", lists:flatten(Message)), - {_Level, _Time2, Message2, _Metadata2} = pop(), + {Level, _Time2, Message2, _Metadata2} = pop(), ?assertEqual("hello world", lists:flatten(Message2)), - {_Level, _Time3, Message3, _Metadata3} = pop(), + {Level, _Time3, Message3, _Metadata3} = pop(), ?assertEqual("format world", lists:flatten(Message3)), - {_Level, _Time4, Message4, _Metadata4} = pop(), + {Level, _Time4, Message4, _Metadata4} = pop(), ?assertEqual("hello world", lists:flatten(Message4)), - {_Level, _Time5, Message5, _Metadata5} = pop(), + {Level, _Time5, Message5, _Metadata5} = pop(), ?assertEqual("hello world", lists:flatten(Message5)), - {_Level, _Time6, Message6, Metadata6} = pop(), + {Level, _Time6, Message6, Metadata6} = pop(), ?assertMatch([{d, delta}, {g, gamma}|_], Metadata6), ?assertEqual("format world", lists:flatten(Message6)), ok @@ -794,18 +794,18 @@ extra_sinks_test_() -> ?TEST_SINK_NAME:info(Attr, "hello ~p", Args), ?TEST_SINK_NAME:info([{d, delta}, {g, gamma}], Fmt, Args), ?assertEqual(6, count(?TEST_SINK_EVENT)), - {_Level, _Time, Message, Metadata} = pop(?TEST_SINK_EVENT), + {Level, _Time, Message, Metadata} = pop(?TEST_SINK_EVENT), ?assertMatch([{a, alpha}, {b, beta}|_], Metadata), ?assertEqual("hello", lists:flatten(Message)), - {_Level, _Time2, Message2, _Metadata2} = pop(?TEST_SINK_EVENT), + {Level, _Time2, Message2, _Metadata2} = pop(?TEST_SINK_EVENT), ?assertEqual("hello world", lists:flatten(Message2)), - {_Level, _Time3, Message3, _Metadata3} = pop(?TEST_SINK_EVENT), + {Level, _Time3, Message3, _Metadata3} = pop(?TEST_SINK_EVENT), ?assertEqual("format world", lists:flatten(Message3)), - {_Level, _Time4, Message4, _Metadata4} = pop(?TEST_SINK_EVENT), + {Level, _Time4, Message4, _Metadata4} = pop(?TEST_SINK_EVENT), ?assertEqual("hello world", lists:flatten(Message4)), - {_Level, _Time5, Message5, _Metadata5} = pop(?TEST_SINK_EVENT), + {Level, _Time5, Message5, _Metadata5} = pop(?TEST_SINK_EVENT), ?assertEqual("hello world", lists:flatten(Message5)), - {_Level, _Time6, Message6, Metadata6} = pop(?TEST_SINK_EVENT), + {Level, _Time6, Message6, Metadata6} = pop(?TEST_SINK_EVENT), ?assertMatch([{d, delta}, {g, gamma}|_], Metadata6), ?assertEqual("format world", lists:flatten(Message6)), ok @@ -912,6 +912,9 @@ crash(Type) -> _ = gen_event:which_handlers(error_logger), ok. +test_body({slice, Expected}, Actual) -> + SlicedActual = string:slice(Actual, 0, length(Expected)), + ?assertEqual(Expected, SlicedActual, {Actual, sliced_to, SlicedActual, is_not_a_member_of, Expected}); test_body(Expected, Actual) -> ExLen = length(Expected), {Body, Rest} = case length(Actual) > ExLen of @@ -1056,11 +1059,10 @@ crash_fsm_test_() -> } end, - TestBody("gen_fsm crash", crash_fsm, crash, [], "gen_fsm crash_fsm in state state1 terminated with reason: call to undefined function crash_fsm:state1/3 from gen_fsm:handle_msg/"), - TestBody("gen_statem crash", crash_statem, crash, [], "gen_statem crash_statem in state state1 terminated with reason: no function clause matching crash_statem:handle"), - TestBody("gen_statem stop", crash_statem, stop, [explode], "gen_statem crash_statem in state state1 terminated with reason: explode"), - TestBody("gen_statem timeout", crash_statem, timeout, [], "gen_statem crash_statem in state state1 terminated with reason: timeout") - ], + TestBody("gen_statem crash", crash_statem, crash, [], {slice, "gen_statem crash_statem in state state1 terminated with reason"}), + TestBody("gen_statem stop", crash_statem, stop, [explode], {slice, "gen_statem crash_statem in state state1 terminated with reason"}), + TestBody("gen_statem timeout", crash_statem, timeout, [], {slice, "gen_statem crash_statem in state state1 terminated with reason"}) + ] ++ test_body_gen_fsm_crash(TestBody), {"FSM crash output tests", [ {"Default sink", @@ -1075,6 +1077,14 @@ crash_fsm_test_() -> Tests}} ]}. +-if(?OTP_RELEASE < 23). +test_body_gen_fsm_crash(TestBody) -> + [TestBody("gen_fsm crash", crash_fsm, crash, [], "gen_fsm crash_fsm in state state1 terminated with reason: call to undefined function crash_fsm:state1/3 from gen_fsm:handle_msg/")]. +-else. +test_body_gen_fsm_crash(_TestBody) -> + []. +-endif. + error_logger_redirect_crash_test_() -> TestBody=fun(Name,CrashReason,Expected) -> fun(Sink) -> From f2ae8feeb4cffcc27552c8834e43fc5a542a6f6c Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Wed, 24 Feb 2021 18:06:14 +0000 Subject: [PATCH 5/5] Get rid of pre-OTP 21 test code workarounds --- rebar.config | 1 - test/crash_statem.erl | 9 --------- test/pr_stacktrace_test.erl | 24 ++++++++---------------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/rebar.config b/rebar.config index 75836147..c3a639b5 100644 --- a/rebar.config +++ b/rebar.config @@ -21,7 +21,6 @@ {erl_opts, [ {lager_extra_sinks, ['__lager_test_sink']}, - {platform_define, "^(19|20|21|22|23|24)", test_statem}, {platform_define, "^18", 'FUNCTION_NAME', unavailable}, {platform_define, "^18", 'FUNCTION_ARITY', 0}, debug_info, diff --git a/test/crash_statem.erl b/test/crash_statem.erl index cf6bb150..c39c380f 100644 --- a/test/crash_statem.erl +++ b/test/crash_statem.erl @@ -1,6 +1,5 @@ -module(crash_statem). %% we're only going to compile this on OTP 19+ --ifdef(test_statem). -behaviour(gen_statem). -export([ @@ -45,11 +44,3 @@ handle_event({call, _From}, timeout, _Arg, _Data) -> {keep_state_and_data, [{state_timeout, 0, timeout}]}; handle_event({call, _From}, {stop, Reason}, state1, _Data) -> {stop, Reason}. - --else. --export([start/0, crash/0]). - -start() -> ok. -crash() -> ok. - --endif. diff --git a/test/pr_stacktrace_test.erl b/test/pr_stacktrace_test.erl index 2853a228..502bcde1 100644 --- a/test/pr_stacktrace_test.erl +++ b/test/pr_stacktrace_test.erl @@ -2,14 +2,6 @@ -compile([{parse_transform, lager_transform}]). --ifdef(OTP_RELEASE). %% this implies 21 or higher --define(EXCEPTION(Class, Reason, Stacktrace), Class:Reason:Stacktrace). --define(GET_STACK(Stacktrace), Stacktrace). --else. --define(EXCEPTION(Class, Reason, _), Class:Reason). --define(GET_STACK(_), erlang:get_stacktrace()). --endif. - -include_lib("eunit/include/eunit.hrl"). make_throw() -> @@ -25,8 +17,8 @@ pr_stacktrace_throw_test() -> Got = try make_throw() catch - ?EXCEPTION(Class, Reason, Stacktrace) -> - lager:pr_stacktrace(?GET_STACK(Stacktrace), {Class, Reason}) + Class:Reason:Stacktrace -> + lager:pr_stacktrace(Stacktrace, {Class, Reason}) end, Want = "pr_stacktrace_test:pr_stacktrace_throw_test/0 line 26\n pr_stacktrace_test:make_throw/0 line 16\nthrow:{test,exception}", ?assertNotEqual(nomatch, string:find(Got, Want)). @@ -35,8 +27,8 @@ pr_stacktrace_bad_arg_test() -> Got = try bad_arg() catch - ?EXCEPTION(Class, Reason, Stacktrace) -> - lager:pr_stacktrace(?GET_STACK(Stacktrace), {Class, Reason}) + Class:Reason:Stacktrace -> + lager:pr_stacktrace(Stacktrace, {Class, Reason}) end, Want = "pr_stacktrace_test:pr_stacktrace_bad_arg_test/0 line 36\n pr_stacktrace_test:bad_arg/0 line 22\nerror:badarg", ?assertNotEqual(nomatch, string:find(Got, Want)). @@ -45,8 +37,8 @@ pr_stacktrace_bad_arity_test() -> Got = try bad_arity() catch - ?EXCEPTION(Class, Reason, Stacktrace) -> - lager:pr_stacktrace(?GET_STACK(Stacktrace), {Class, Reason}) + Class:Reason:Stacktrace -> + lager:pr_stacktrace(Stacktrace, {Class, Reason}) end, Want = "pr_stacktrace_test:pr_stacktrace_bad_arity_test/0 line 46\n lists:concat([], [])\nerror:undef", ?assertNotEqual(nomatch, string:find(Got, Want)). @@ -56,8 +48,8 @@ pr_stacktrace_no_reverse_test() -> Got = try bad_arity() catch - ?EXCEPTION(Class, Reason, Stacktrace) -> - lager:pr_stacktrace(?GET_STACK(Stacktrace), {Class, Reason}) + Class:Reason:Stacktrace -> + lager:pr_stacktrace(Stacktrace, {Class, Reason}) end, Want = "error:undef\n lists:concat([], [])\n pr_stacktrace_test:pr_stacktrace_bad_arity_test/0 line 57", ?assertEqual(nomatch, string:find(Got, Want)).