diff --git a/.github/workflows/erlang.yml b/.github/workflows/erlang.yml index 995f1f4..a5d23fc 100644 --- a/.github/workflows/erlang.yml +++ b/.github/workflows/erlang.yml @@ -15,18 +15,13 @@ jobs: runs-on: ubuntu-22.04 - strategy: - matrix: - otp: ['25', '26'] - rebar: ['3.22'] - steps: - uses: actions/checkout@v3 - uses: erlef/setup-beam@v1 id: setup-beam with: - otp-version: ${{matrix.otp}} - rebar3-version: ${{matrix.rebar}} + version-type: strict + version-file: .tool-versions - name: Restore _build uses: actions/cache@v3 with: diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..1ae24a9 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +erlang 27.0.1 +rebar 3.23.0 diff --git a/rebar.config b/rebar.config index d63d7f3..55f1e58 100644 --- a/rebar.config +++ b/rebar.config @@ -3,7 +3,7 @@ {erl_opts, [warn_unused_import, warn_export_vars, warnings_as_errors, verbose, report, debug_info]}. -{minimum_otp_vsn, "21"}. +{minimum_otp_vsn, "27"}. {profiles, [{test, diff --git a/src/wpool_process.erl b/src/wpool_process.erl index dff3d84..886c853 100644 --- a/src/wpool_process.erl +++ b/src/wpool_process.erl @@ -46,9 +46,16 @@ %% api -export([start_link/4, call/3, cast/2, send_request/2]). + +-ifdef(TEST). + +-export([get_state/1]). + +-endif. + %% gen_server callbacks -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2, - handle_continue/2, format_status/2]). + handle_continue/2, format_status/1]). %%%=================================================================== %%% API @@ -79,6 +86,14 @@ cast(Process, Cast) -> send_request(Name, Request) -> gen_server:send_request(Name, Request). +-ifdef(TEST). + +-spec get_state(state()) -> term(). +get_state(#state{state = State}) -> + State. + +-endif. + %%%=================================================================== %%% init, terminate, code_change, info callbacks %%%=================================================================== @@ -177,19 +192,13 @@ handle_continue(Continue, State) -> end. %% @private --spec format_status(normal | terminate, [[{_, _}] | state(), ...]) -> term(). -format_status(Opt, [PDict, State]) -> - case erlang:function_exported(State#state.mod, format_status, 2) of +-spec format_status(gen_server:format_status()) -> gen_server:format_status(). +format_status(#{state := #state{mod = Mod}} = Status) -> + case erlang:function_exported(Mod, format_status, 1) of false -> - case Opt % This is copied from gen_server:format_status/4 - of - terminate -> - State#state.state; - normal -> - [{data, [{"State", State#state.state}]}] - end; + Status; true -> - (State#state.mod):format_status(Opt, [PDict, State#state.state]) + Mod:format_status(Status) end. %%%=================================================================== diff --git a/test/echo_server.erl b/test/echo_server.erl index 09a4405..82d5012 100644 --- a/test/echo_server.erl +++ b/test/echo_server.erl @@ -18,7 +18,7 @@ %% gen_server callbacks -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2, - handle_continue/2, format_status/2]). + handle_continue/2, format_status/1]). -dialyzer([no_behaviours]). @@ -59,7 +59,6 @@ handle_call(Call, _From, _State) -> handle_continue(Continue, _State) -> Continue. --spec format_status(normal | terminate, [[{_, _}] | State, ...]) -> - {formatted_state, State}. -format_status(_, [_PDict, State]) -> - {formatted_state, State}. +-spec format_status(gen_server:format_status()) -> gen_server:format_status(). +format_status(State) -> + State. diff --git a/test/wpool_process_SUITE.erl b/test/wpool_process_SUITE.erl index 36f7a0d..7638452 100644 --- a/test/wpool_process_SUITE.erl +++ b/test/wpool_process_SUITE.erl @@ -175,24 +175,19 @@ continue(_Config) -> -spec format_status(config()) -> {comment, []}. format_status(_Config) -> - %% echo_server implements format_status/2 + %% echo_server implements format_status/1 {ok, Pid} = wpool_process:start_link(?MODULE, echo_server, {ok, state}, []), - %% therefore it returns {formatted_state, State} as its status - {status, Pid, {module, gen_server}, SItems} = sys:get_status(Pid), - [state] = [S || SItemList = [_ | _] <- SItems, {formatted_state, S} <- SItemList], - %% this code is actually what we use to retrieve the state in other tests + %% therefore it returns State as its status state = get_state(Pid), {comment, []}. -spec no_format_status(config()) -> {comment, []}. no_format_status(_Config) -> - %% crashy_server doesn't implement format_status/2 + %% crashy_server doesn't implement format_status/1 {ok, Pid} = wpool_process:start_link(?MODULE, crashy_server, state, []), %% therefore it uses the default format for the stauts (but with the status of %% the gen_server, not wpool_process) - {status, Pid, {module, gen_server}, SItems} = sys:get_status(Pid), - [state] = - [S || SItemList = [_ | _] <- SItems, {data, Data} <- SItemList, {"State", S} <- Data], + state = get_state(Pid), {comment, []}. -spec call(config()) -> {comment, []}. @@ -329,13 +324,20 @@ complete_coverage(_Config) -> {comment, []}. %% @doc We can use this function in tests since echo_server implements -%% format_status/2 by returning the state as a tuple {formatted_state, S}. +%% format_status/1 by returning the status as a map S. %% We can safely grab it from the result of sys:get_status/1 -%% @see gen_server:format_status/2 +%% @see gen_server:format_status/1 %% @see sys:get_status/2 get_state(Atom) when is_atom(Atom) -> get_state(whereis(Atom)); get_state(Pid) -> - {status, Pid, {module, gen_server}, SItems} = sys:get_status(Pid), - [State] = [S || SItemList = [_ | _] <- SItems, {formatted_state, S} <- SItemList], - State. + {status, Pid, {module, gen_server}, [_PDict, _SysState, _Parent, _Dbg, Misc]} = + sys:get_status(Pid), + [State] = + lists:filtermap(fun ({data, [{"State", State}]}) -> + {true, State}; + (_) -> + false + end, + Misc), + wpool_process:get_state(State).