1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2010-2011. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: %% 21: -module(mnesia_majority_test). 22: -author('ulf.wiger@erlang-solutions.com'). 23: -compile(export_all). 24: -include("mnesia_test_lib.hrl"). 25: 26: init_per_testcase(Func, Conf) -> 27: mnesia_test_lib:init_per_testcase(Func, Conf). 28: 29: end_per_testcase(Func, Conf) -> 30: mnesia_test_lib:end_per_testcase(Func, Conf). 31: 32: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33: all() -> 34: [ 35: write 36: , wread 37: , delete 38: , clear_table 39: , frag 40: , change_majority 41: , frag_change_majority 42: ]. 43: 44: write(suite) -> []; 45: write(Config) when is_list(Config) -> 46: [N1, N2, N3] = ?acquire_nodes(3, Config), 47: Tab = t, 48: Schema = [{name, Tab}, {ram_copies, [N1,N2,N3]}, {majority,true}], 49: ?match({atomic, ok}, mnesia:create_table(Schema)), 50: ?match({[ok,ok,ok],[]}, 51: rpc:multicall([N1,N2,N3], mnesia, wait_for_tables, [[Tab], 3000])), 52: ?match({atomic,ok}, 53: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 54: mnesia_test_lib:kill_mnesia([N3]), 55: ?match({atomic,ok}, 56: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 57: mnesia_test_lib:kill_mnesia([N2]), 58: ?match({aborted,{no_majority,Tab}}, 59: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)). 60: 61: wread(suite) -> []; 62: wread(Config) when is_list(Config) -> 63: [N1, N2] = ?acquire_nodes(2, Config), 64: Tab = t, 65: Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], 66: ?match({atomic, ok}, mnesia:create_table(Schema)), 67: ?match({[ok,ok],[]}, 68: rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), 69: ?match({atomic,[]}, 70: mnesia:transaction(fun() -> mnesia:read(t,1,write) end)), 71: mnesia_test_lib:kill_mnesia([N2]), 72: ?match({aborted,{no_majority,Tab}}, 73: mnesia:transaction(fun() -> mnesia:read(t,1,write) end)). 74: 75: delete(suite) -> []; 76: delete(Config) when is_list(Config) -> 77: [N1, N2] = ?acquire_nodes(2, Config), 78: Tab = t, 79: Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], 80: ?match({atomic, ok}, mnesia:create_table(Schema)), 81: ?match({[ok,ok],[]}, 82: rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), 83: %% works as expected with majority of nodes present 84: ?match({atomic,ok}, 85: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 86: ?match({atomic,ok}, 87: mnesia:transaction(fun() -> mnesia:delete({t,1}) end)), 88: ?match({atomic,[]}, 89: mnesia:transaction(fun() -> mnesia:read({t,1}) end)), 90: %% put the record back 91: ?match({atomic,ok}, 92: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 93: ?match({atomic,[{t,1,a}]}, 94: mnesia:transaction(fun() -> mnesia:read({t,1}) end)), 95: mnesia_test_lib:kill_mnesia([N2]), 96: ?match({aborted,{no_majority,Tab}}, 97: mnesia:transaction(fun() -> mnesia:delete({t,1}) end)). 98: 99: clear_table(suite) -> []; 100: clear_table(Config) when is_list(Config) -> 101: [N1, N2] = ?acquire_nodes(2, Config), 102: Tab = t, 103: Schema = [{name, Tab}, {ram_copies, [N1,N2]}, {majority,true}], 104: ?match({atomic, ok}, mnesia:create_table(Schema)), 105: ?match({[ok,ok],[]}, 106: rpc:multicall([N1,N2], mnesia, wait_for_tables, [[Tab], 3000])), 107: %% works as expected with majority of nodes present 108: ?match({atomic,ok}, 109: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 110: ?match({atomic,ok}, mnesia:clear_table(t)), 111: ?match({atomic,[]}, 112: mnesia:transaction(fun() -> mnesia:read({t,1}) end)), 113: %% put the record back 114: ?match({atomic,ok}, 115: mnesia:transaction(fun() -> mnesia:write({t,1,a}) end)), 116: ?match({atomic,[{t,1,a}]}, 117: mnesia:transaction(fun() -> mnesia:read({t,1}) end)), 118: mnesia_test_lib:kill_mnesia([N2]), 119: ?match({aborted,{no_majority,Tab}}, mnesia:clear_table(t)). 120: 121: frag(suite) -> []; 122: frag(Config) when is_list(Config) -> 123: [N1] = ?acquire_nodes(1, Config), 124: Tab = t, 125: Schema = [ 126: {name, Tab}, {ram_copies, [N1]}, 127: {majority,true}, 128: {frag_properties, [{n_fragments, 2}]} 129: ], 130: ?match({atomic, ok}, mnesia:create_table(Schema)), 131: ?match(true, mnesia:table_info(t, majority)), 132: ?match(true, mnesia:table_info(t_frag2, majority)). 133: 134: change_majority(suite) -> []; 135: change_majority(Config) when is_list(Config) -> 136: [N1,N2] = ?acquire_nodes(2, Config), 137: Tab = t, 138: Schema = [ 139: {name, Tab}, {ram_copies, [N1,N2]}, 140: {majority,false} 141: ], 142: ?match({atomic, ok}, mnesia:create_table(Schema)), 143: ?match(false, mnesia:table_info(t, majority)), 144: ?match({atomic, ok}, 145: mnesia:change_table_majority(t, true)), 146: ?match(true, mnesia:table_info(t, majority)), 147: ?match(ok, 148: mnesia:activity(transaction, fun() -> 149: mnesia:write({t,1,a}) 150: end)), 151: mnesia_test_lib:kill_mnesia([N2]), 152: ?match({'EXIT',{aborted,{no_majority,_}}}, 153: mnesia:activity(transaction, fun() -> 154: mnesia:write({t,1,a}) 155: end)). 156: 157: frag_change_majority(suite) -> []; 158: frag_change_majority(Config) when is_list(Config) -> 159: [N1,N2] = ?acquire_nodes(2, Config), 160: Tab = t, 161: Schema = [ 162: {name, Tab}, {ram_copies, [N1,N2]}, 163: {majority,false}, 164: {frag_properties, 165: [{n_fragments, 2}, 166: {n_ram_copies, 2}, 167: {node_pool, [N1,N2]}]} 168: ], 169: ?match({atomic, ok}, mnesia:create_table(Schema)), 170: ?match(false, mnesia:table_info(t, majority)), 171: ?match(false, mnesia:table_info(t_frag2, majority)), 172: ?match({aborted,{bad_type,t_frag2}}, 173: mnesia:change_table_majority(t_frag2, true)), 174: ?match({atomic, ok}, 175: mnesia:change_table_majority(t, true)), 176: ?match(true, mnesia:table_info(t, majority)), 177: ?match(true, mnesia:table_info(t_frag2, majority)), 178: ?match(ok, 179: mnesia:activity(transaction, fun() -> 180: mnesia:write({t,1,a}) 181: end, mnesia_frag)), 182: mnesia_test_lib:kill_mnesia([N2]), 183: ?match({'EXIT',{aborted,{no_majority,_}}}, 184: mnesia:activity(transaction, fun() -> 185: mnesia:write({t,1,a}) 186: end, mnesia_frag)).