mirror of
https://github.com/valitydev/machinery-erlang.git
synced 2024-11-06 08:45:19 +00:00
Fix machinegun format_version
field usage (#25)
This commit is contained in:
parent
e2d1d3e82f
commit
4e8245860a
@ -343,16 +343,18 @@ marshal({repair_fail, Schema}, Reason) ->
|
|||||||
};
|
};
|
||||||
|
|
||||||
marshal({state_change, Schema}, #{} = V) ->
|
marshal({state_change, Schema}, #{} = V) ->
|
||||||
Version = machinery_mg_schema:get_version(Schema, aux_state),
|
AuxStateVersion = machinery_mg_schema:get_version(Schema, aux_state),
|
||||||
|
EventVersion = machinery_mg_schema:get_version(Schema, event),
|
||||||
#mg_stateproc_MachineStateChange{
|
#mg_stateproc_MachineStateChange{
|
||||||
events = [
|
events = [
|
||||||
#mg_stateproc_Content{data = Event}
|
#mg_stateproc_Content{data = Event, format_version = EventVersion}
|
||||||
|| Event <- marshal({list, {schema, Schema, {event, Version}}}, maps:get(events, V, []))
|
|| Event <- marshal({list, {schema, Schema, {event, EventVersion}}}, maps:get(events, V, []))
|
||||||
],
|
],
|
||||||
% TODO
|
% TODO
|
||||||
% Provide this to logic handlers as well
|
% Provide this to logic handlers as well
|
||||||
aux_state = #mg_stateproc_Content{
|
aux_state = #mg_stateproc_Content{
|
||||||
data = marshal({schema, Schema, {aux_state, Version}}, maps:get(aux_state, V, undefined))
|
data = marshal({schema, Schema, {aux_state, AuxStateVersion}}, maps:get(aux_state, V, undefined)),
|
||||||
|
format_version = AuxStateVersion
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
233
test/machinery_mg_schema_versions_SUITE.erl
Normal file
233
test/machinery_mg_schema_versions_SUITE.erl
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
-module(machinery_mg_schema_versions_SUITE).
|
||||||
|
|
||||||
|
-behaviour(machinery).
|
||||||
|
|
||||||
|
-include_lib("stdlib/include/assert.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
%% Common Tests callbacks
|
||||||
|
-export([all/0]).
|
||||||
|
-export([groups/0]).
|
||||||
|
-export([init_per_suite/1]).
|
||||||
|
-export([end_per_suite/1]).
|
||||||
|
-export([init_per_testcase/2]).
|
||||||
|
|
||||||
|
%% Tests
|
||||||
|
|
||||||
|
-export([schema_versions_used_properly_test/1]).
|
||||||
|
|
||||||
|
%% Machinery callbacks
|
||||||
|
|
||||||
|
-export([init/4]).
|
||||||
|
-export([process_timeout/3]).
|
||||||
|
-export([process_repair/4]).
|
||||||
|
-export([process_call/4]).
|
||||||
|
|
||||||
|
%% machinery_mg_schema callbacks
|
||||||
|
|
||||||
|
-export([marshal/2]).
|
||||||
|
-export([unmarshal/2]).
|
||||||
|
-export([get_version/1]).
|
||||||
|
|
||||||
|
%% Internal types
|
||||||
|
|
||||||
|
-type config() :: ct_helper:config().
|
||||||
|
-type test_case_name() :: ct_helper:test_case_name().
|
||||||
|
-type group_name() :: ct_helper:group_name().
|
||||||
|
-type test_return() :: _ | no_return().
|
||||||
|
|
||||||
|
-spec all() -> [test_case_name() | {group, group_name()}].
|
||||||
|
all() ->
|
||||||
|
[
|
||||||
|
{group, all}
|
||||||
|
].
|
||||||
|
|
||||||
|
-spec groups() ->
|
||||||
|
[{group_name(), list(), test_case_name()}].
|
||||||
|
groups() ->
|
||||||
|
[
|
||||||
|
{all, [parallel], [
|
||||||
|
schema_versions_used_properly_test
|
||||||
|
]}
|
||||||
|
].
|
||||||
|
|
||||||
|
-spec init_per_suite(config()) -> config().
|
||||||
|
init_per_suite(C0) ->
|
||||||
|
{StartedApps, _StartupCtx} = ct_helper:start_apps([machinery]),
|
||||||
|
C1 = [{backend, machinery_mg_backend}, {group_sup, ct_sup:start()} | C0],
|
||||||
|
{ok, _Pid} = start_backend(C1),
|
||||||
|
[{started_apps, StartedApps}| C1].
|
||||||
|
|
||||||
|
-spec end_per_suite(config()) -> _.
|
||||||
|
end_per_suite(C) ->
|
||||||
|
ok = ct_helper:stop_apps(?config(started_apps, C)),
|
||||||
|
ok = ct_sup:stop(?config(group_sup, C)).
|
||||||
|
|
||||||
|
-spec init_per_testcase(test_case_name(), config()) -> config().
|
||||||
|
init_per_testcase(TestCaseName, C) ->
|
||||||
|
ct_helper:makeup_cfg([ct_helper:test_case_name(TestCaseName), ct_helper:woody_ctx()], C).
|
||||||
|
|
||||||
|
%% Tests
|
||||||
|
|
||||||
|
-spec schema_versions_used_properly_test(config()) -> test_return().
|
||||||
|
schema_versions_used_properly_test(C) ->
|
||||||
|
ID = unique(),
|
||||||
|
?assertEqual(ok, start(ID, init_something, C)),
|
||||||
|
?assertEqual({ok, done}, call(ID, do_something, C)),
|
||||||
|
timer:sleep(timer:seconds(5)),
|
||||||
|
?assertEqual({ok, done}, call(ID, do_something, C)),
|
||||||
|
?assertError({failed, general, ID}, call(ID, fail, C)),
|
||||||
|
?assertEqual({ok, done}, repair(ID, repair_something, {20, 10, forward}, C)),
|
||||||
|
?assertEqual({ok, done}, call(ID, do_something, C)).
|
||||||
|
|
||||||
|
%% Machinery handler
|
||||||
|
|
||||||
|
-type event() :: any().
|
||||||
|
-type aux_st() :: any().
|
||||||
|
-type machine() :: machinery:machine(event(), aux_st()).
|
||||||
|
-type handler_opts() :: machinery:handler_opts(_).
|
||||||
|
-type result() :: machinery:result(event(), aux_st()).
|
||||||
|
-type response() :: machinery:response(_).
|
||||||
|
|
||||||
|
-spec init(_Args, machine(), undefined, handler_opts()) ->
|
||||||
|
result().
|
||||||
|
init(init_something, _Machine, _, _Opts) ->
|
||||||
|
#{
|
||||||
|
events => [init_event],
|
||||||
|
action => continue,
|
||||||
|
aux_state => #{some => <<"complex">>, aux_state => 1}
|
||||||
|
}.
|
||||||
|
|
||||||
|
-spec process_timeout(machine(), undefined, handler_opts()) ->
|
||||||
|
result().
|
||||||
|
process_timeout(_Machine, _, _Opts) ->
|
||||||
|
#{
|
||||||
|
events => [{timeout_event, 1}],
|
||||||
|
action => unset_timer, % why not
|
||||||
|
aux_state => #{some => <<"other complex">>, aux_state => 1}
|
||||||
|
}.
|
||||||
|
|
||||||
|
-spec process_call(_Args, machine(), undefined, handler_opts()) ->
|
||||||
|
{response(), result()}.
|
||||||
|
process_call(do_something, _Machine, _, _Opts) ->
|
||||||
|
{done, #{
|
||||||
|
events => [call_event],
|
||||||
|
aux_state => undefined
|
||||||
|
}};
|
||||||
|
process_call(fail, _Machine, _, _Opts) ->
|
||||||
|
erlang:error(fail).
|
||||||
|
|
||||||
|
-spec process_repair(_Args, machine(), undefined, handler_opts()) ->
|
||||||
|
no_return().
|
||||||
|
process_repair(repair_something, #{history := History}, _, _Opts) ->
|
||||||
|
{ok, {done, #{events => [{count_events, erlang:length(History)}]}}}.
|
||||||
|
|
||||||
|
%% machinery_mg_schema callbacks
|
||||||
|
|
||||||
|
-spec marshal(machinery_mg_schema:t(), any()) ->
|
||||||
|
machinery_msgpack:t().
|
||||||
|
marshal(T, V) when
|
||||||
|
T =:= {aux_state, 1} orelse
|
||||||
|
T =:= {event, 2} orelse
|
||||||
|
T =:= {args, init} orelse
|
||||||
|
T =:= {args, call} orelse
|
||||||
|
T =:= {args, repair} orelse
|
||||||
|
T =:= {response, call} orelse
|
||||||
|
T =:= {response, {repair, success}} orelse
|
||||||
|
T =:= {response, {repair, failure}}
|
||||||
|
->
|
||||||
|
{bin, erlang:term_to_binary(V)}.
|
||||||
|
|
||||||
|
-spec unmarshal(machinery_mg_schema:t(), machinery_msgpack:t()) ->
|
||||||
|
any().
|
||||||
|
unmarshal(T, V) when
|
||||||
|
T =:= {aux_state, 1} orelse
|
||||||
|
T =:= {event, 2} orelse
|
||||||
|
T =:= {args, init} orelse
|
||||||
|
T =:= {args, call} orelse
|
||||||
|
T =:= {args, repair} orelse
|
||||||
|
T =:= {response, call} orelse
|
||||||
|
T =:= {response, {repair, failure}}
|
||||||
|
->
|
||||||
|
{bin, EncodedV} = V,
|
||||||
|
erlang:binary_to_term(EncodedV);
|
||||||
|
unmarshal({aux_state, undefined}, {bin, <<>>}) ->
|
||||||
|
% initial aux_state
|
||||||
|
undefined;
|
||||||
|
unmarshal({response, {repair, success}}, {bin, <<"ok">>}) ->
|
||||||
|
% mg repair migration artefact
|
||||||
|
done.
|
||||||
|
|
||||||
|
-spec get_version(machinery_mg_schema:vt()) ->
|
||||||
|
machinery_mg_schema:version().
|
||||||
|
get_version(aux_state) ->
|
||||||
|
1;
|
||||||
|
get_version(event) ->
|
||||||
|
2.
|
||||||
|
|
||||||
|
%% Helpers
|
||||||
|
|
||||||
|
start(ID, Args, C) ->
|
||||||
|
machinery:start(namespace(), ID, Args, get_backend(C)).
|
||||||
|
|
||||||
|
call(Ref, Args, C) ->
|
||||||
|
machinery:call(namespace(), Ref, Args, get_backend(C)).
|
||||||
|
|
||||||
|
repair(Ref, Args, Range, C) ->
|
||||||
|
machinery:repair(namespace(), Ref, Range, Args, get_backend(C)).
|
||||||
|
|
||||||
|
namespace() ->
|
||||||
|
general.
|
||||||
|
|
||||||
|
unique() ->
|
||||||
|
genlib:unique().
|
||||||
|
|
||||||
|
start_backend(C) ->
|
||||||
|
{ok, _PID} = supervisor:start_child(
|
||||||
|
?config(group_sup, C),
|
||||||
|
child_spec(C)
|
||||||
|
).
|
||||||
|
|
||||||
|
-spec child_spec(config()) ->
|
||||||
|
supervisor:child_spec().
|
||||||
|
child_spec(C) ->
|
||||||
|
child_spec(?config(backend, C), C).
|
||||||
|
|
||||||
|
-spec child_spec(atom(), config()) ->
|
||||||
|
supervisor:child_spec().
|
||||||
|
child_spec(machinery_mg_backend, _C) ->
|
||||||
|
BackendConfig = #{
|
||||||
|
path => <<"/v1/stateproc">>,
|
||||||
|
backend_config => #{
|
||||||
|
schema => ?MODULE
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Handler = {?MODULE, BackendConfig},
|
||||||
|
Routes = machinery_mg_backend:get_routes(
|
||||||
|
[Handler],
|
||||||
|
#{event_handler => woody_event_handler_default}
|
||||||
|
),
|
||||||
|
ServerConfig = #{
|
||||||
|
ip => {0, 0, 0, 0},
|
||||||
|
port => 8022
|
||||||
|
},
|
||||||
|
machinery_utils:woody_child_spec(machinery_mg_backend, Routes, ServerConfig).
|
||||||
|
|
||||||
|
-spec get_backend(config()) ->
|
||||||
|
machinery_mg_backend:backend().
|
||||||
|
get_backend(C) ->
|
||||||
|
get_backend(?config(backend, C), C).
|
||||||
|
|
||||||
|
-spec get_backend(atom(), config()) ->
|
||||||
|
machinery_mg_backend:backend().
|
||||||
|
get_backend(machinery_mg_backend, C) ->
|
||||||
|
machinery_mg_backend:new(
|
||||||
|
ct_helper:get_woody_ctx(C),
|
||||||
|
#{
|
||||||
|
client => #{
|
||||||
|
url => <<"http://machinegun:8022/v1/automaton">>,
|
||||||
|
event_handler => woody_event_handler_default
|
||||||
|
},
|
||||||
|
schema => ?MODULE
|
||||||
|
}
|
||||||
|
).
|
Loading…
Reference in New Issue
Block a user