在 Common Test 未通过的情况下杀死 gen_server
Killing a gen_server without failing the Common Test
我实现了一个故意崩溃的模块(以测试另一个正在监视它的模块的功能)。问题是,当这个 gen_server 崩溃时,它也会导致对它的通用测试失败。我试过使用 try/catch 并设置 process_flag(trap_exit, true)
但似乎没有任何效果。
这里是一些相关的代码:
-module(mod_bad_process).
% ...
%% ct calls this function directly
kill() ->
gen_server:call(?MODULE, {update_behavior, kill}).
% ...
handle_cast({update_behavior, Behavior}, _From, State) ->
case Behavior of
kill -> {stop, killed, State};
_ -> {reply, ok, State#{state := Behavior}}
end;
% ...
和普通测试:
% ...
-define(BAD_PROC, mod_bad_process).
% ...
remonitor_test(_Conf) ->
InitialPid = whereis(?BAD_PROC),
true = undefined =/= InitialPid,
true = is_monitored_gen_server(?BAD_PROC),
mod_bad_process:kill(), % gen_server crashes
timer:sleep(?REMONITOR_DELAY_MS),
FinalPid = whereis(?BAD_PROC),
true = InitialPid =/= FinalPid,
true = undefined =/= FinalPid,
true = is_monitored_gen_server(?BAD_PROC).
% ...
以及 ct 产生的错误:
*** CT Error Notification 2021-07-16 16:08:20.791 ***
gen_server:call failed on line 238
Reason: {killed,{gen_server,call,...}}
=== Ended at 2021-07-16 16:08:20
=== Location: [{gen_server,call,238},
{mod_bad_process,kill,48},
{monitor_tests,remonitor_test,62},
{test_server,ts_tc,1784},
{test_server,run_test_case_eval1,1293},
{test_server,run_test_case_eval,1225}]
=== === Reason: {killed,{gen_server,call,
[mod_bad_process_global,
{update_behavior,kill}]}}
===
*** monitor_remonitor_test failed.
Skipping all other cases in sequence.
关于如何在不通过通用测试的情况下获得此功能的任何想法?
问题是我的 try/catch 尝试没有与实际错误进行模式匹配。这是修复:
-module(mod_bad_process).
% ...
kill() ->
try gen_server:call(?MODULE, {update_behavior, kill}) of
_ -> error(failed_to_kill)
catch
exit:{killed, _} -> ok
end.
% ...
我实现了一个故意崩溃的模块(以测试另一个正在监视它的模块的功能)。问题是,当这个 gen_server 崩溃时,它也会导致对它的通用测试失败。我试过使用 try/catch 并设置 process_flag(trap_exit, true)
但似乎没有任何效果。
这里是一些相关的代码:
-module(mod_bad_process).
% ...
%% ct calls this function directly
kill() ->
gen_server:call(?MODULE, {update_behavior, kill}).
% ...
handle_cast({update_behavior, Behavior}, _From, State) ->
case Behavior of
kill -> {stop, killed, State};
_ -> {reply, ok, State#{state := Behavior}}
end;
% ...
和普通测试:
% ...
-define(BAD_PROC, mod_bad_process).
% ...
remonitor_test(_Conf) ->
InitialPid = whereis(?BAD_PROC),
true = undefined =/= InitialPid,
true = is_monitored_gen_server(?BAD_PROC),
mod_bad_process:kill(), % gen_server crashes
timer:sleep(?REMONITOR_DELAY_MS),
FinalPid = whereis(?BAD_PROC),
true = InitialPid =/= FinalPid,
true = undefined =/= FinalPid,
true = is_monitored_gen_server(?BAD_PROC).
% ...
以及 ct 产生的错误:
*** CT Error Notification 2021-07-16 16:08:20.791 ***
gen_server:call failed on line 238
Reason: {killed,{gen_server,call,...}}
=== Ended at 2021-07-16 16:08:20
=== Location: [{gen_server,call,238},
{mod_bad_process,kill,48},
{monitor_tests,remonitor_test,62},
{test_server,ts_tc,1784},
{test_server,run_test_case_eval1,1293},
{test_server,run_test_case_eval,1225}]
=== === Reason: {killed,{gen_server,call,
[mod_bad_process_global,
{update_behavior,kill}]}}
===
*** monitor_remonitor_test failed.
Skipping all other cases in sequence.
关于如何在不通过通用测试的情况下获得此功能的任何想法?
问题是我的 try/catch 尝试没有与实际错误进行模式匹配。这是修复:
-module(mod_bad_process).
% ...
kill() ->
try gen_server:call(?MODULE, {update_behavior, kill}) of
_ -> error(failed_to_kill)
catch
exit:{killed, _} -> ok
end.
% ...