diff options
Diffstat (limited to 'lib/mnesia/test')
-rw-r--r-- | lib/mnesia/test/mnesia_evil_backup.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/test/mnesia_evil_coverage_test.erl | 60 | ||||
-rw-r--r-- | lib/mnesia/test/mnesia_frag_hash_test.erl | 94 | ||||
-rw-r--r-- | lib/mnesia/test/mnesia_install_test.erl | 23 |
4 files changed, 166 insertions, 19 deletions
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl index 63f4146d98..9e0a8db1ae 100644 --- a/lib/mnesia/test/mnesia_evil_backup.erl +++ b/lib/mnesia/test/mnesia_evil_backup.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% Copyright Ericsson AB 1998-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -244,9 +244,9 @@ restore(Config, Op) -> [rpc:call(Node, ?MODULE, check_tab, [Res31, ?LINE]) || Node <- Nodes], %% Restore all tables on it's nodes - mnesia_schema:clear_table(Tab1), - mnesia_schema:clear_table(Tab2), - mnesia_schema:clear_table(Tab3), + mnesia:clear_table(Tab1), + mnesia:clear_table(Tab2), + mnesia:clear_table(Tab3), [mnesia:dirty_write({Tab1, N, N+1}) || N <- lists:seq(1, 11)], [mnesia:dirty_write({Tab2, N, N+1}) || N <- lists:seq(1, 11)], [mnesia:dirty_write({Tab3, N, N+1}) || N <- lists:seq(1, 11)], diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl index 668eba176f..64b61288ef 100644 --- a/lib/mnesia/test/mnesia_evil_coverage_test.erl +++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -37,7 +37,8 @@ end_per_testcase(Func, Conf) -> all() -> [system_info, table_info, error_description, db_node_lifecycle, evil_delete_db_node, start_and_stop, - checkpoint, table_lifecycle, add_copy_conflict, + checkpoint, table_lifecycle, storage_options, + add_copy_conflict, add_copy_when_going_down, replica_management, schema_availability, local_content, {group, table_access_modifications}, replica_location, @@ -244,7 +245,7 @@ db_node_lifecycle(Config) when is_list(Config) -> ?match([], mnesia_test_lib:start_mnesia(AllNodes)), ?match([SNs, SNs, SNs], - lists:map({lists, sort}, + lists:map(fun lists:sort/1, element(1, rpc:multicall(AllNodes, mnesia, table_info, [schema, disc_copies])))), @@ -259,7 +260,7 @@ db_node_lifecycle(Config) when is_list(Config) -> mnesia:change_table_copy_type(schema, Node2, disc_copies)), ?match([SNs, SNs, SNs], - lists:map({lists, sort}, + lists:map(fun lists:sort/1, element(1, rpc:multicall(AllNodes, mnesia, table_info, [schema, disc_copies])))), @@ -462,7 +463,7 @@ table_lifecycle(Config) when is_list(Config) -> ?match({atomic, ok}, mnesia:create_table([{name, already_exists}, {ram_copies, [Node1]}])), ?match({aborted, Reason23 } when element(1, Reason23) ==already_exists, - mnesia:create_table([{name, already_exists}, + mnesia:create_table([{name, already_exists}, {ram_copies, [Node1]}])), ?match({aborted, Reason21 } when element(1, Reason21) == bad_type, mnesia:create_table([{name, bad_node}, {ram_copies, ["foo"]}])), @@ -520,12 +521,57 @@ table_lifecycle(Config) when is_list(Config) -> ?match({atomic, ok}, mnesia:create_table([{name, create_with_index}, {index, [3]}, {ram_copies, [Node1]}])), - ets:new(ets_table, [named_table]), + ets:new(ets_table, [named_table]), ?match({aborted, _}, mnesia:create_table(ets_table, [{ram_copies, Nodes}])), + ?match({aborted, _}, mnesia:create_table(ets_table, [{ram_copies, [Node1]}])), + ets:delete(ets_table), + ?match({atomic, ok}, mnesia:create_table(ets_table, [{ram_copies, [Node1]}])), + ?match(Node1, rpc:call(Node1, mnesia_lib, val, [{ets_table,where_to_read}])), + ?match(Node1, rpc:call(Node2, mnesia_lib, val, [{ets_table,where_to_read}])), + ?match({atomic, ok}, mnesia:change_table_copy_type(ets_table, Node1, disc_only_copies)), + ?match(Node1, rpc:call(Node2, mnesia_lib, val, [{ets_table,where_to_read}])), + + ?verify_mnesia(Nodes, []). + + +storage_options(suite) -> []; +storage_options(Config) when is_list(Config) -> + [N1,N2,N3] = Nodes = ?acquire_nodes(3, Config), + + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,foobar}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,[foobar]}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,[duplicate_bag]}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{dets,[{type,bag}]}]}])), + + ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, [N1]}, + {disc_only_copies, [N2]}, + {storage_properties, + [{ets,[compressed]}, + {dets, [{auto_save, 5000}]} ]}])), + ?match(true, ets:info(a, compressed)), + ?match(5000, rpc:call(N2, dets, info, [a, auto_save])), + ?match(ok, mnesia:dirty_write({a,1,1})), + ?match([{a,1,1}], mnesia:dirty_read({a,1})), + mnesia:dump_log(), + W2C1 = [{N2, disc_only_copies}, {N1, ram_copies}], + ?match(W2C1, lists:sort(rpc:call(N2, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(W2C1, lists:sort(rpc:call(N3, mnesia_lib, val, [{a, where_to_commit}]))), + ?match({atomic,ok}, mnesia:change_table_copy_type(a, N1, disc_only_copies)), + W2C2 = [{N2, disc_only_copies}, {N1, disc_only_copies}], + ?match(W2C2, lists:sort(rpc:call(N2, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(W2C2, lists:sort(rpc:call(N3, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(undefined, ets:info(a, compressed)), + ?match(5000, dets:info(a, auto_save)), + ?match({atomic,ok}, mnesia:change_table_copy_type(a, N1, disc_copies)), + ?match(true, ets:info(a, compressed)), ?verify_mnesia(Nodes, []). + + + + add_copy_conflict(suite) -> []; add_copy_conflict(doc) -> ["Verify that OTP-5065 doesn't happen again, whitebox testing"]; @@ -1795,7 +1841,7 @@ subscribe_extended(Config) when is_list(Config) -> ?match({mnesia_table_event, {delete, schema, {schema, Tab1}, [{schema, Tab1, _}],_}}, recv_event()), ?match({mnesia_table_event, {write, schema, {schema, Tab1, _}, [], _}}, recv_event()), - ?match({atomic, ok}, mnesia_schema:clear_table(Tab2)), + ?match({atomic, ok}, mnesia:clear_table(Tab2)), ?match({mnesia_table_event, {delete, schema, {schema, Tab2}, [{schema, Tab2, _}],_}}, recv_event()), ?match({mnesia_table_event, {write, schema, {schema, Tab2, _}, [], _}}, recv_event()), diff --git a/lib/mnesia/test/mnesia_frag_hash_test.erl b/lib/mnesia/test/mnesia_frag_hash_test.erl new file mode 100644 index 0000000000..095d25e74f --- /dev/null +++ b/lib/mnesia/test/mnesia_frag_hash_test.erl @@ -0,0 +1,94 @@ +-module(mnesia_frag_hash_test). + +-export([test/0]). + +-define(NUM_FRAGS, 20). +-define(NUM_KEYS, 10000). + +-record(hash_state, + {n_fragments, + next_n_to_split, + n_doubles, + function}). + +% OLD mnesia_frag_hash:key_to_frag_number/2. +old_key_to_frag_number(#hash_state{function = phash, next_n_to_split = SplitN, n_doubles = L}, Key) -> + P = SplitN, + A = erlang:phash(Key, power2(L)), + if + A < P -> + erlang:phash(Key, power2(L + 1)); + true -> + A + end; +old_key_to_frag_number(#hash_state{function = phash2, next_n_to_split = SplitN, n_doubles = L}, Key) -> + P = SplitN, + A = erlang:phash2(Key, power2(L)) + 1, + if + A < P -> + erlang:phash2(Key, power2(L + 1)) + 1; + true -> + A + end; +old_key_to_frag_number(OldState, Key) -> + State = convert_old_state(OldState), + old_key_to_frag_number(State, Key). + + +% NEW mnesia_frag_hash:key_to_frag_number/2. +new_key_to_frag_number(#hash_state{function = phash, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash(Key, power2(L + 1)), + if + A > N -> + A - power2(L); + true -> + A + end; +new_key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash2(Key, power2(L + 1)) + 1, + if + A > N -> + A - power2(L); + true -> + A + end; +new_key_to_frag_number(OldState, Key) -> + State = convert_old_state(OldState), + new_key_to_frag_number(State, Key). + + +% Helpers for key_to_frag_number functions. + +power2(Y) -> + 1 bsl Y. % trunc(math:pow(2, Y)). + +convert_old_state({hash_state, N, P, L}) -> + #hash_state{n_fragments = N, + next_n_to_split = P, + n_doubles = L, + function = phash}. + + +test() -> + test2(mnesia_frag_hash:init_state(undefined, undefined)), % phash2 + test2({hash_state, 1, 1, 0}). % phash + +test2(I) -> + test_keys(I), + lists:foldl( + fun(_, S) -> test_frag(S) end, + I, lists:seq(1, ?NUM_FRAGS)), + ok. + +test_frag(State) -> + {State2,_,_} = mnesia_frag_hash:add_frag(State), + test_keys(State2), + State2. + +test_keys(State) -> + [test_key(State, Key) || Key <- lists:seq(1, ?NUM_KEYS)]. + +test_key(State, Key) -> + Old = old_key_to_frag_number(State, Key), + New = new_key_to_frag_number(State, Key), + Old = New. diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl index 5d55fcac0e..3a2d44aa95 100644 --- a/lib/mnesia/test/mnesia_install_test.erl +++ b/lib/mnesia/test/mnesia_install_test.erl @@ -205,7 +205,7 @@ silly_upgrade(Config) when is_list(Config) -> ?match(ok, mnesia:install_fallback(Bup2)), file:delete(Bup2), %% Will generate intentional crash, fatal error - ?match([], mnesia_test_lib:stop_mnesia([Node2])), + ?match([], mnesia_test_lib:stop_mnesia([Node2])), wait_till_dead([Node1, Node2]), ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab1, Tab2])), ?match(match, verify_state(Tab1, Tab2, CpState)), @@ -213,22 +213,29 @@ silly_upgrade(Config) when is_list(Config) -> ?match(ok, mnesia:install_fallback(Bup)), file:delete(Bup), %% Will generate intentional crash, fatal error - ?match([], mnesia_test_lib:stop_mnesia([Node1, Node2])), + ?match([], mnesia_test_lib:stop_mnesia([Node1, Node2])), wait_till_dead([Node1, Node2]), ?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab1, Tab2])), CpState2 = [X || X <- CpState, element(1, X) /= Tab1], ?match(match, verify_state(Tab1, Tab2, CpState2)), ?verify_mnesia(Nodes, []). -wait_till_dead([]) -> ok; -wait_till_dead([N|Ns]) -> +wait_till_dead([]) -> + ok; %% timer:sleep(5); +wait_till_dead(Repeat = [N|Ns]) -> Apps = rpc:call(N, application, which_applications, []), case lists:keymember(mnesia, 1, Apps) of - true -> + true -> timer:sleep(10), - wait_till_dead([N|Ns]); - false -> - wait_till_dead(Ns) + wait_till_dead(Repeat); + false -> + case rpc:call(N, erlang, whereis, [mnesia_monitor]) of + undefined -> + wait_till_dead(Ns); + _ -> + timer:sleep(10), + wait_till_dead(Repeat) + end end. add_some_records(Tab1, Tab2, Old) -> |