%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% %% -module(mnesia_majority_test). -author('ulf.wiger@erlang-solutions.com'). -export([init_per_testcase/2, end_per_testcase/2, all/0]). -export([write/1, wread/1, delete/1, clear_table/1, frag/1, change_majority/1, frag_change_majority/1 ]). -include("mnesia_test_lib.hrl"). init_per_testcase(Func, Conf) -> mnesia_test_lib:init_per_testcase(Func, Conf). end_per_testcase(Func, Conf) -> mnesia_test_lib:end_per_testcase(Func, Conf). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% all() -> [ write , wread , delete , clear_table , frag , change_majority , frag_change_majority ]. write(suite) -> []; write(Config) when is_list(Config) -> [N1, N2, N3] = ?acquire_nodes(3, Config), Tab = t, Schema = [{name, Tab}, {ram_copies, [N1,N2,N3]}, {majority,true}], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match({[ok,ok,ok],[]}, rpc:multicall([N1,N2,N3], mnesia, wait_for_tables, [[Tab], 3000])), ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), mnesia_test_lib:kill_mnesia([N3]), ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), mnesia_test_lib:kill_mnesia([N2]), ?match({aborted,{no_majority,Tab}}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)). wread(suite) -> []; wread(Config) when is_list(Config) -> [N1, N2] = ?acquire_nodes(2, Config), Tab = t, Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match({[ok,ok],[]}, rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), ?match({atomic,[]}, mnesia:transaction(fun() -> mnesia:read(t,1,write) end)), mnesia_test_lib:kill_mnesia([N2]), ?match({aborted,{no_majority,Tab}}, mnesia:transaction(fun() -> mnesia:read(t,1,write) end)). delete(suite) -> []; delete(Config) when is_list(Config) -> [N1, N2] = ?acquire_nodes(2, Config), Tab = t, Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match({[ok,ok],[]}, rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), %% works as expected with majority of nodes present ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:delete({t,1}) end)), ?match({atomic,[]}, mnesia:transaction(fun() -> mnesia:read({t,1}) end)), %% put the record back ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), ?match({atomic,[{t,1,a}]}, mnesia:transaction(fun() -> mnesia:read({t,1}) end)), mnesia_test_lib:kill_mnesia([N2]), ?match({aborted,{no_majority,Tab}}, mnesia:transaction(fun() -> mnesia:delete({t,1}) end)). clear_table(suite) -> []; clear_table(Config) when is_list(Config) -> [N1, N2] = ?acquire_nodes(2, Config), Tab = t, Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match({[ok,ok],[]}, rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), %% works as expected with majority of nodes present ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), ?match({atomic,ok}, mnesia:clear_table(t)), ?match({atomic,[]}, mnesia:transaction(fun() -> mnesia:read({t,1}) end)), %% put the record back ?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), ?match({atomic,[{t,1,a}]}, mnesia:transaction(fun() -> mnesia:read({t,1}) end)), mnesia_test_lib:kill_mnesia([N2]), ?match({aborted,{no_majority,Tab}}, mnesia:clear_table(t)). frag(suite) -> []; frag(Config) when is_list(Config) -> [N1] = ?acquire_nodes(1, Config), Tab = t, Schema = [ {name, Tab}, {ram_copies, [N1]}, {majority,true}, {frag_properties, [{n_fragments, 2}]} ], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match(true, mnesia:table_info(t, majority)), ?match(true, mnesia:table_info(t_frag2, majority)). change_majority(suite) -> []; change_majority(Config) when is_list(Config) -> [N1,N2] = ?acquire_nodes(2, Config), Tab = t, Schema = [ {name, Tab}, {ram_copies, [N1,N2]}, {majority,false} ], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match(false, mnesia:table_info(t, majority)), ?match({atomic, ok}, mnesia:change_table_majority(t, true)), ?match(true, mnesia:table_info(t, majority)), ?match(ok, mnesia:activity(transaction, fun() -> mnesia:write({t,1,a}) end)), mnesia_test_lib:kill_mnesia([N2]), ?match({'EXIT',{aborted,{no_majority,_}}}, mnesia:activity(transaction, fun() -> mnesia:write({t,1,a}) end)). frag_change_majority(suite) -> []; frag_change_majority(Config) when is_list(Config) -> [N1,N2] = ?acquire_nodes(2, Config), Tab = t, Schema = [ {name, Tab}, {ram_copies, [N1,N2]}, {majority,false}, {frag_properties, [{n_fragments, 2}, {n_ram_copies, 2}, {node_pool, [N1,N2]}]} ], ?match({atomic, ok}, mnesia:create_table(Schema)), ?match(false, mnesia:table_info(t, majority)), ?match(false, mnesia:table_info(t_frag2, majority)), ?match({aborted,{bad_type,t_frag2}}, mnesia:change_table_majority(t_frag2, true)), ?match({atomic, ok}, mnesia:change_table_majority(t, true)), ?match(true, mnesia:table_info(t, majority)), ?match(true, mnesia:table_info(t_frag2, majority)), ?match(ok, mnesia:activity(transaction, fun() -> mnesia:write({t,1,a}) end, mnesia_frag)), mnesia_test_lib:kill_mnesia([N2]), ?match({'EXIT',{aborted,{no_majority,_}}}, mnesia:activity(transaction, fun() -> mnesia:write({t,1,a}) end, mnesia_frag)).