微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在不通过 Common Test 的情况下杀死 gen_server

如何解决在不通过 Common Test 的情况下杀死 gen_server

我实现了一个故意崩溃的模块(以测试另一个模块的功能,它正在监视它)。问题是,当这个 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,238},{mod_bad_process,kill,48},{monitor_tests,remonitor_test,62},{test_server,ts_tc,1784},run_test_case_eval1,1293},run_test_case_eval,1225}]
=== === Reason: {killed,[mod_bad_process_global,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.
% ...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。