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