Mnesia migrations with global lock on startup. Refs EventHub/EventHubBack#24
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
-module(migration_engine_tests).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("records.hrl").
|
||||
|
||||
-define(LOCK_VERSION, "__migration_lock__").
|
||||
|
||||
setup() ->
|
||||
mnesia:stop(),
|
||||
mnesia:delete_schema([node()]),
|
||||
mnesia:create_schema([node()]),
|
||||
mnesia:start(),
|
||||
mnesia:create_table(schema_migration, [
|
||||
{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, schema_migration)},
|
||||
{type, set}
|
||||
]),
|
||||
{ok, _} = migration_engine:start_link(),
|
||||
ok.
|
||||
|
||||
cleanup(_) ->
|
||||
catch gen_server:stop(migration_engine),
|
||||
catch mnesia:delete_table(schema_migration),
|
||||
mnesia:stop(),
|
||||
mnesia:delete_schema([node()]),
|
||||
ok.
|
||||
|
||||
migration_engine_test_() ->
|
||||
{foreach, fun setup/0, fun cleanup/1, [
|
||||
{"ensure_applied applies pending migrations", fun test_ensure_applied/0},
|
||||
{"ensure_applied is idempotent", fun test_ensure_applied_idempotent/0},
|
||||
{"lock record is not treated as migration", fun test_lock_not_applied/0},
|
||||
{"join node waits until migrations applied", fun test_join_wait/0}
|
||||
]}.
|
||||
|
||||
test_ensure_applied() ->
|
||||
?assertEqual(ok, migration_engine:ensure_applied()),
|
||||
Status = migration_engine:status(),
|
||||
?assertEqual([], maps:get(pending, Status)),
|
||||
Applied = maps:get(applied, Status),
|
||||
?assert(lists:member("20260501120000_base_schema", Applied)),
|
||||
?assert(lists:member("20260504150000_test_migration", Applied)).
|
||||
|
||||
test_ensure_applied_idempotent() ->
|
||||
?assertEqual(ok, migration_engine:ensure_applied()),
|
||||
?assertEqual(ok, migration_engine:ensure_applied()).
|
||||
|
||||
test_lock_not_applied() ->
|
||||
?assertEqual(ok, migration_engine:ensure_applied()),
|
||||
Status = migration_engine:status(),
|
||||
?assertNot(lists:member(?LOCK_VERSION, maps:get(applied, Status))).
|
||||
|
||||
test_join_wait() ->
|
||||
Now = calendar:universal_time(),
|
||||
mnesia:dirty_write(#schema_migration{version = ?LOCK_VERSION, applied_at = Now}),
|
||||
spawn(fun() ->
|
||||
timer:sleep(100),
|
||||
mnesia:dirty_write(#schema_migration{
|
||||
version = "20260501120000_base_schema", applied_at = Now}),
|
||||
mnesia:dirty_write(#schema_migration{
|
||||
version = "20260504150000_test_migration", applied_at = Now}),
|
||||
mnesia:dirty_delete({schema_migration, ?LOCK_VERSION})
|
||||
end),
|
||||
?assertEqual(ok, migration_engine:ensure_applied()).
|
||||
Reference in New Issue
Block a user