Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:20
erlang
3911-eunit-Include-a-stacktrace-when-a-test-tim...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3911-eunit-Include-a-stacktrace-when-a-test-times-out.patch of Package erlang
From 5ddb41e42652c270e62aab8baf9bfa1105875362 Mon Sep 17 00:00:00 2001 From: Tomas Abrahamsson <tomas.abrahamsson@gmail.com> Date: Fri, 3 Sep 2021 17:59:25 +0200 Subject: [PATCH] eunit: Include a stacktrace when a test times out In an eunit test, when a test case times out, include a stacktrace. This can be useful when debugging. In the event of a test timeout, the printout now looks like this: 1> eunit:test(tl, [verbose]). eunit:test(tl, [verbose]). ======================== EUnit ======================== tl: takes_too_long_test (module 'tl')...*timed out* in function timer:sleep/1 (timer.erl, line 152) in call from tl:takes_too_long_test/0 (/.../tl.erl, line 6) in call from eunit_test:'-mf_wrapper/2-fun-0-'/2 (eunit_test.erl, line 273) in call from eunit_test:run_testfun/1 (eunit_test.erl, line 71) in call from eunit_proc:run_test/1 (/.../eunit_proc.erl, line 528) in call from eunit_proc:with_timeout/3 (/.../eunit_proc.erl, line 353) in call from eunit_proc:handle_test/2 (/.../eunit_proc.erl, line 511) in call from eunit_proc:tests_inorder/3 (/.../eunit_proc.erl, line 453) undefined ======================================================= Failed: 0. Skipped: 0. Passed: 0. One or more tests were cancelled. error Previously, it looked like below. 1> eunit:test(tl, [verbose]). eunit:test(tl, [verbose]). ======================== EUnit ======================== tl: takes_too_long_test (module 'tl')...*timed out* undefined ======================================================= Failed: 0. Skipped: 0. Passed: 0. One or more tests were cancelled. error For an eunit_listener, the handle_cancel/3 will now be called with {timeout, #{stacktrace => Stacktrace}} as 2nd argument, in case of a timeout. Previously it was only the atom timeout. In the eunit_surefire handler, include the stacktrace in the xml, as well. --- lib/eunit/src/eunit_lib.erl | 2 +- lib/eunit/src/eunit_proc.erl | 11 ++++++++++- lib/eunit/src/eunit_surefire.erl | 4 ++++ lib/eunit/src/eunit_tty.erl | 3 +++ lib/eunit/test/Makefile | 3 ++- lib/eunit/test/eunit_SUITE.erl | 15 +++++++++++++-- lib/eunit/test/ttimesout.erl | 6 ++++++ 7 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 lib/eunit/test/ttimesout.erl diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl index 5b7d90ab0d..c7555597c2 100644 --- a/lib/eunit/src/eunit_lib.erl +++ b/lib/eunit/src/eunit_lib.erl @@ -36,7 +36,7 @@ command/2, command/3, trie_new/0, trie_store/2, trie_match/2, split_node/1, consult_file/1, list_dir/1, format_exit_term/1, format_exception/1, format_exception/2, format_error/1, format_error/2, - is_not_test/1]). + format_stacktrace/1, is_not_test/1]). -define(DEFAULT_DEPTH, 20). diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl index fb6619a6d4..7622bab2a9 100644 --- a/lib/eunit/src/eunit_proc.erl +++ b/lib/eunit/src/eunit_proc.erl @@ -95,6 +95,9 @@ get_output() -> %% {cancel, Descriptor} %% where Descriptor can be: %% timeout a timeout occurred +%% {timeout, #{stacktrace := Stacktrace} +%% a timeout occurred and there is a stacktrace +%% of the eunit test %% {blame, Id} forced to terminate because of item `Id' %% {abort, Cause} the test or group failed to execute %% {exit, Reason} the test process terminated unexpectedly @@ -273,7 +276,13 @@ insulator_wait(Child, Parent, Buf, St) -> io_request(From, ReplyAs, Req, []), insulator_wait(Child, Parent, Buf, St); {timeout, Child, Id} -> - exit_messages(Id, timeout, St), + Timeout = case process_info(Child, current_stacktrace) of + undefined -> + timeout; + {current_stacktrace, Stack} -> + {timeout, #{stacktrace => Stack}} + end, + exit_messages(Id, Timeout, St), kill_task(Child, St); {'EXIT', Child, normal} -> terminate_insulator(St); diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl index 71f3765f21..a37ec72965 100644 --- a/lib/eunit/src/eunit_surefire.erl +++ b/lib/eunit/src/eunit_surefire.erl @@ -395,6 +395,10 @@ format_testcase_result({skipped, {abort, Error}}) when is_tuple(Error) -> [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(element(1, Error))), <<"\">">>, ?NEWLINE, escape_text(eunit_lib:format_error(Error)), ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE]; +format_testcase_result({skipped, {timeout, #{stacktrace := Stack}}}) -> + [?INDENT, ?INDENT, <<"<skipped type=\"timeout\">">>, ?NEWLINE, + escape_text(eunit_lib:format_stacktrace(Stack)), + ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE]; format_testcase_result({skipped, {Type, Term}}) when is_atom(Type) -> [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE, escape_text(io_lib:write(Term)), diff --git a/lib/eunit/src/eunit_tty.erl b/lib/eunit/src/eunit_tty.erl index fd5245c971..aee8e466e2 100644 --- a/lib/eunit/src/eunit_tty.erl +++ b/lib/eunit/src/eunit_tty.erl @@ -253,6 +253,9 @@ format_cancel(undefined, _) -> "*skipped*\n"; format_cancel(timeout, _) -> "*timed out*\n"; +format_cancel({timeout, #{stacktrace := Stack}}, _) -> + ["*timed out*\n", + eunit_lib:format_stacktrace(Stack)]; format_cancel({startup, Reason}, Depth) -> io_lib:fwrite("*could not start test process*\n::~tP\n\n", [Reason, Depth]); diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile index 99d1f8093a..903adfde3f 100644 --- a/lib/eunit/test/Makefile +++ b/lib/eunit/test/Makefile @@ -24,7 +24,8 @@ MODULES = \ eunit_SUITE \ tc0 \ tlatin \ - tutf8 + tutf8 \ + ttimesout ERL_FILES= $(MODULES:%=%.erl) diff --git a/lib/eunit/test/eunit_SUITE.erl b/lib/eunit/test/eunit_SUITE.erl index df754e46c5..5940fd3857 100644 --- a/lib/eunit/test/eunit_SUITE.erl +++ b/lib/eunit/test/eunit_SUITE.erl @@ -22,7 +22,8 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, app_test/1,appup_test/1,eunit_test/1,surefire_utf8_test/1,surefire_latin_test/1, - surefire_c0_test/1, surefire_ensure_dir_test/1]). + surefire_c0_test/1, surefire_ensure_dir_test/1, + stacktrace_at_timeout_test/1]). -include_lib("common_test/include/ct.hrl"). @@ -30,7 +31,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [app_test, appup_test, eunit_test, surefire_utf8_test, surefire_latin_test, - surefire_c0_test, surefire_ensure_dir_test]. + surefire_c0_test, surefire_ensure_dir_test, stacktrace_at_timeout_test]. groups() -> []. @@ -81,6 +82,16 @@ surefire_ensure_dir_test(Config) when is_list(Config) -> ok = eunit:test(tc0, [{report,{eunit_surefire,[{dir,XMLDir}]}}]), ok = file:del_dir_r(XMLDir). +stacktrace_at_timeout_test(Config) when is_list(Config) -> + Chars = check_surefire(ttimesout), + case string:find(Chars, "in call from") of + nomatch -> + ct:pal("Surefire XML:~n~ts", [Chars]), + ct:fail(missing_stacktrace_in_surefire); + _ -> + ok + end. + check_surefire(Module) -> File = "TEST-"++atom_to_list(Module)++".xml", file:delete(File), diff --git a/lib/eunit/test/ttimesout.erl b/lib/eunit/test/ttimesout.erl new file mode 100644 index 0000000000..91f6be847d --- /dev/null +++ b/lib/eunit/test/ttimesout.erl @@ -0,0 +1,6 @@ +-module(ttimesout). + +-include_lib("eunit/include/eunit.hrl"). + +times_out_test_() -> + {timeout, 1, fun() -> timer:sleep(20_000) end}. -- 2.31.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor