1

我实现了一个故意崩溃的模块(以测试另一个模块的功能,该模块正在监视它)。问题是,当这个 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.

关于如何在不通过常见测试的情况下获得此功能的任何想法?

4

1 回答 1

1

问题是我的 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.
% ...
于 2021-07-23T18:13:44.017 回答