104 lines
3.2 KiB
Erlang
104 lines
3.2 KiB
Erlang
-module(mnesia_rocksdb_error_handling).
|
|
|
|
-export([run/0,
|
|
run/4]).
|
|
|
|
|
|
run() ->
|
|
setup(),
|
|
%% run only one test for 'fatal', to save time.
|
|
[run(Type, Op, L, MaintainSz) || MaintainSz <- [false, true],
|
|
Type <- [set, bag],
|
|
Op <- [insert, update, delete],
|
|
L <- levels()]
|
|
++ [run(set, insert, fatal, false)].
|
|
|
|
run(Type, Op, Level, MaintainSz) ->
|
|
setup(),
|
|
{ok, Tab} = create_tab(Type, Level, MaintainSz),
|
|
mnesia:dirty_write({Tab, a, 1}), % pre-existing data
|
|
with_mock(Level, Op, Tab, fun() ->
|
|
try_write(Op, Type, Tab),
|
|
expect_error(Level, Tab)
|
|
end).
|
|
|
|
levels() ->
|
|
[debug, verbose, warning, error].
|
|
|
|
setup() ->
|
|
mnesia:stop(),
|
|
start_mnesia().
|
|
|
|
create_tab(Type, Level, MaintainSz) ->
|
|
TabName = tab_name(Type, Level, MaintainSz),
|
|
UserProps = user_props(Level, MaintainSz),
|
|
{atomic, ok} = mnesia:create_table(TabName, [{rdb, [node()]},
|
|
{user_properties, UserProps}]),
|
|
{ok, TabName}.
|
|
|
|
tab_name(Type, Level, MaintainSz) ->
|
|
binary_to_atom(iolist_to_binary(
|
|
["t" | [["_", atom_to_list(A)]
|
|
|| A <- [?MODULE, Type, Level, MaintainSz]]]), utf8).
|
|
|
|
user_props(Level, MaintainSz) ->
|
|
[{maintain_sz, MaintainSz},
|
|
{rocksdb_opts, [{on_write_error, Level}]}].
|
|
|
|
start_mnesia() ->
|
|
mnesia_rocksdb_tlib:start_mnesia(reset),
|
|
ok.
|
|
|
|
with_mock(Level, Op, Tab, F) ->
|
|
mnesia:subscribe(system),
|
|
mnesia:set_debug_level(debug),
|
|
meck:new(mnesia_rocksdb_lib, [passthrough]),
|
|
meck:expect(mnesia_rocksdb_lib, put, 4, {error, some_put_error}),
|
|
meck:expect(mnesia_rocksdb_lib, write, 3, {error, some_write_error}),
|
|
meck:expect(mnesia_rocksdb_lib, delete, 3, {error,some_delete_error}),
|
|
try {Level, Op, Tab, F()} of
|
|
{_, _, _, ok} ->
|
|
ok;
|
|
Other ->
|
|
io:fwrite("OTHER: ~p~n", [Other]),
|
|
ok
|
|
catch
|
|
exit:{{aborted,_},_} ->
|
|
Level = error,
|
|
ok
|
|
after
|
|
mnesia:set_debug_level(none),
|
|
mnesia:unsubscribe(system),
|
|
meck:unload(mnesia_rocksdb_lib)
|
|
end.
|
|
|
|
try_write(insert, set, Tab) ->
|
|
mnesia:dirty_write({Tab, b, 2});
|
|
try_write(insert, bag, Tab) ->
|
|
mnesia:dirty_write({Tab, a, 2});
|
|
try_write(update, _, Tab) ->
|
|
mnesia:dirty_write({Tab, a, 1});
|
|
try_write(delete, _, Tab) ->
|
|
mnesia:dirty_delete({Tab, a}).
|
|
|
|
|
|
expect_error(Level, Tab) ->
|
|
Tag = rpt_tag(Level),
|
|
receive
|
|
{mnesia_system_event, {mnesia_fatal, Fmt, Args, _Core}} ->
|
|
Tag = mnesia_fatal,
|
|
io:fwrite("EVENT(~p, ~p):~n ~s", [Tag, Tab, io_lib:fwrite(Fmt, Args)]),
|
|
ok;
|
|
{mnesia_system_event, {Tag, Fmt, Args}} ->
|
|
io:fwrite("EVENT(~p, ~p):~n ~s", [Tag, Tab, io_lib:fwrite(Fmt, Args)]),
|
|
ok
|
|
after 1000 ->
|
|
error({expected_error, [Level, Tab]})
|
|
end.
|
|
|
|
rpt_tag(fatal ) -> mnesia_fatal;
|
|
rpt_tag(error ) -> mnesia_error;
|
|
rpt_tag(warning) -> mnesia_warning;
|
|
rpt_tag(verbose) -> mnesia_info;
|
|
rpt_tag(debug ) -> mnesia_info.
|