1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1998-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_schema_recovery_test). 23-author('hakan@erix.ericsson.se'). 24 25-export([init_per_testcase/2, end_per_testcase/2, 26 init_per_group/2, end_per_group/2, 27 all/0, groups/0]). 28 29-export([interrupted_before_create_ram/1, 30 interrupted_before_create_disc/1, 31 interrupted_before_create_do/1, 32 interrupted_before_create_nostore/1, 33 interrupted_before_delete_ram/1, 34 interrupted_before_delete_disc/1, 35 interrupted_before_delete_do/1, 36 interrupted_before_add_ram/1, 37 interrupted_before_add_disc/1, 38 interrupted_before_add_do/1, 39 interrupted_before_add_kill_copier/1, 40 interrupted_before_move_ram/1, 41 interrupted_before_move_disc/1, 42 interrupted_before_move_do/1, 43 interrupted_before_move_kill_copier/1, 44 interrupted_before_delcopy_ram/1, 45 interrupted_before_delcopy_disc/1, 46 interrupted_before_delcopy_do/1, 47 interrupted_before_delcopy_kill_copier/1, 48 interrupted_before_addindex_ram/1, 49 interrupted_before_addindex_disc/1, 50 interrupted_before_addindex_do/1, 51 interrupted_before_delindex_ram/1, 52 interrupted_before_delindex_disc/1, 53 interrupted_before_delindex_do/1, 54 interrupted_before_change_type_ram2disc/1, 55 interrupted_before_change_type_ram2do/1, 56 interrupted_before_change_type_disc2ram/1, 57 interrupted_before_change_type_disc2do/1, 58 interrupted_before_change_type_do2ram/1, 59 interrupted_before_change_type_do2disc/1, 60 interrupted_before_change_type_other_node/1, 61 interrupted_before_change_schema_type/1, 62 interrupted_after_create_ram/1, 63 interrupted_after_create_disc/1, 64 interrupted_after_create_do/1, 65 interrupted_after_create_nostore/1, 66 interrupted_after_delete_ram/1, 67 interrupted_after_delete_disc/1, 68 interrupted_after_delete_do/1, 69 interrupted_after_add_ram/1, 70 interrupted_after_add_disc/1, 71 interrupted_after_add_do/1, 72 interrupted_after_add_kill_copier/1, 73 interrupted_after_move_ram/1, 74 interrupted_after_move_disc/1, 75 interrupted_after_move_do/1, 76 interrupted_after_move_kill_copier/1, 77 interrupted_after_delcopy_ram/1, 78 interrupted_after_delcopy_disc/1, 79 interrupted_after_delcopy_do/1, 80 interrupted_after_delcopy_kill_copier/1, 81 interrupted_after_addindex_ram/1, 82 interrupted_after_addindex_disc/1, 83 interrupted_after_addindex_do/1, 84 interrupted_after_delindex_ram/1, 85 interrupted_after_delindex_disc/1, 86 interrupted_after_delindex_do/1, 87 interrupted_after_change_type_ram2disc/1, 88 interrupted_after_change_type_ram2do/1, 89 interrupted_after_change_type_disc2ram/1, 90 interrupted_after_change_type_disc2do/1, 91 interrupted_after_change_type_do2ram/1, 92 interrupted_after_change_type_do2disc/1, 93 interrupted_after_change_type_other_node/1, 94 interrupted_after_change_schema_type/1]). 95 96 97-include("mnesia_test_lib.hrl"). 98 99init_per_testcase(Func, Conf) -> 100 mnesia_test_lib:init_per_testcase(Func, Conf). 101 102end_per_testcase(Func, Conf) -> 103 mnesia_test_lib:end_per_testcase(Func, Conf). 104 105-define(receive_messages(Msgs), receive_messages(Msgs, ?FILE, ?LINE)). 106 107% First Some debug logging 108-define(dgb, true). 109-ifdef(dgb). 110-define(dl(X, Y), ?verbose("**TRACING: " ++ X ++ "**~n", Y)). 111-else. 112-define(dl(X, Y), ok). 113-endif. 114 115%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 116 117all() -> 118 [{group, interrupted_before_log_dump}, 119 {group, interrupted_after_log_dump}]. 120 121groups() -> 122 [{interrupted_before_log_dump, [], 123 [interrupted_before_create_ram, 124 interrupted_before_create_disc, 125 interrupted_before_create_do, 126 interrupted_before_create_nostore, 127 interrupted_before_delete_ram, 128 interrupted_before_delete_disc, 129 interrupted_before_delete_do, 130 interrupted_before_add_ram, 131 interrupted_before_add_disc, 132 interrupted_before_add_do, 133 interrupted_before_add_kill_copier, 134 interrupted_before_move_ram, 135 interrupted_before_move_disc, 136 interrupted_before_move_do, 137 interrupted_before_move_kill_copier, 138 interrupted_before_delcopy_ram, 139 interrupted_before_delcopy_disc, 140 interrupted_before_delcopy_do, 141 interrupted_before_delcopy_kill_copier, 142 interrupted_before_addindex_ram, 143 interrupted_before_addindex_disc, 144 interrupted_before_addindex_do, 145 interrupted_before_delindex_ram, 146 interrupted_before_delindex_disc, 147 interrupted_before_delindex_do, 148 interrupted_before_change_type_ram2disc, 149 interrupted_before_change_type_ram2do, 150 interrupted_before_change_type_disc2ram, 151 interrupted_before_change_type_disc2do, 152 interrupted_before_change_type_do2ram, 153 interrupted_before_change_type_do2disc, 154 interrupted_before_change_type_other_node, 155 interrupted_before_change_schema_type]}, 156 {interrupted_after_log_dump, [], 157 [interrupted_after_create_ram, 158 interrupted_after_create_disc, 159 interrupted_after_create_do, 160 interrupted_after_create_nostore, 161 interrupted_after_delete_ram, 162 interrupted_after_delete_disc, 163 interrupted_after_delete_do, 164 interrupted_after_add_ram, 165 interrupted_after_add_disc, 166 interrupted_after_add_do, 167 interrupted_after_add_kill_copier, 168 interrupted_after_move_ram, 169 interrupted_after_move_disc, 170 interrupted_after_move_do, 171 interrupted_after_move_kill_copier, 172 interrupted_after_delcopy_ram, 173 interrupted_after_delcopy_disc, 174 interrupted_after_delcopy_do, 175 interrupted_after_delcopy_kill_copier, 176 interrupted_after_addindex_ram, 177 interrupted_after_addindex_disc, 178 interrupted_after_addindex_do, 179 interrupted_after_delindex_ram, 180 interrupted_after_delindex_disc, 181 interrupted_after_delindex_do, 182 interrupted_after_change_type_ram2disc, 183 interrupted_after_change_type_ram2do, 184 interrupted_after_change_type_disc2ram, 185 interrupted_after_change_type_disc2do, 186 interrupted_after_change_type_do2ram, 187 interrupted_after_change_type_do2disc, 188 interrupted_after_change_type_other_node, 189 interrupted_after_change_schema_type]}]. 190 191init_per_group(_GroupName, Config) -> 192 Config. 193 194end_per_group(_GroupName, Config) -> 195 Config. 196 197interrupted_before_create_ram(suite) -> []; 198interrupted_before_create_ram(Config) when is_list(Config) -> 199 KillAt = {mnesia_dumper, dump_schema_op}, 200 interrupted_create(Config, ram_copies, all, KillAt). 201 202interrupted_before_create_disc(suite) -> []; 203interrupted_before_create_disc(Config) when is_list(Config) -> 204 KillAt = {mnesia_dumper, dump_schema_op}, 205 interrupted_create(Config, disc_copies, all, KillAt). 206 207interrupted_before_create_do(suite) -> []; 208interrupted_before_create_do(Config) when is_list(Config) -> 209 KillAt = {mnesia_dumper, dump_schema_op}, 210 interrupted_create(Config, disc_only_copies, all, KillAt). 211 212interrupted_before_create_nostore(suite) -> []; 213interrupted_before_create_nostore(Config) when is_list(Config) -> 214 KillAt = {mnesia_dumper, dump_schema_op}, 215 interrupted_create(Config, ram_copies, one, KillAt). 216 217interrupted_after_create_ram(suite) -> []; 218interrupted_after_create_ram(Config) when is_list(Config) -> 219 KillAt = {mnesia_dumper, post_dump}, 220 interrupted_create(Config, ram_copies, all, KillAt). 221 222interrupted_after_create_disc(suite) -> []; 223interrupted_after_create_disc(Config) when is_list(Config) -> 224 KillAt = {mnesia_dumper, post_dump}, 225 interrupted_create(Config, disc_copies, all, KillAt). 226 227interrupted_after_create_do(suite) -> []; 228interrupted_after_create_do(Config) when is_list(Config) -> 229 KillAt = {mnesia_dumper, post_dump}, 230 interrupted_create(Config, disc_only_copies, all, KillAt). 231 232interrupted_after_create_nostore(suite) -> []; 233interrupted_after_create_nostore(Config) when is_list(Config) -> 234 KillAt = {mnesia_dumper, post_dump}, 235 interrupted_create(Config, ram_copies, one, KillAt). 236 237%%% After dump don't need debug point 238interrupted_create(Config, Type, _Where, {mnesia_dumper, post_dump}) -> 239 [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]), 240 ?match({atomic, ok},mnesia:create_table(itrpt, [{Type, Nodes}])), 241 ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 242 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 243 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 244 ?match(stopped, mnesia:stop()), 245 ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])), 246 %% Verify 247 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 248 case Type of 249 ram_copies -> 250 ?match([], mnesia:dirty_read({itrpt, before})); 251 _ -> 252 ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before})) 253 end, 254 ?verify_mnesia(Nodes, []); 255interrupted_create(Config, Type, Where, KillAt) -> 256 ?is_debug_compiled, 257 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 258 {success, [A]} = ?start_activities([Node2]), 259 setup_dbgpoint(KillAt, Node2), 260 261 if %% CREATE TABLE 262 Where == all -> % tables on both nodes 263 A ! fun() -> mnesia:create_table(itrpt, [{Type, Nodes}]) end; 264 true -> % no table on the killed node 265 A ! fun() -> mnesia:create_table(itrpt, [{Type, [Node1]}]) end 266 end, 267 268 kill_at_debug(), 269 ?match([], mnesia_test_lib:start_mnesia([Node2], [itrpt])), 270 %% Verify 271 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 272 verify_tab(Node1, Node2), 273 ?verify_mnesia(Nodes, []). 274 275interrupted_before_delete_ram(suite) -> []; 276interrupted_before_delete_ram(Config) when is_list(Config) -> 277 Debug_Point = {mnesia_dumper, dump_schema_op}, 278 interrupted_delete(Config, ram_copies, Debug_Point). 279interrupted_before_delete_disc(suite) -> []; 280interrupted_before_delete_disc(Config) when is_list(Config) -> 281 Debug_Point = {mnesia_dumper, dump_schema_op}, 282 interrupted_delete(Config, disc_copies, Debug_Point). 283interrupted_before_delete_do(suite) -> []; 284interrupted_before_delete_do(Config) when is_list(Config) -> 285 Debug_Point = {mnesia_dumper, dump_schema_op}, 286 interrupted_delete(Config, disc_only_copies, Debug_Point). 287 288interrupted_after_delete_ram(suite) -> []; 289interrupted_after_delete_ram(Config) when is_list(Config) -> 290 Debug_Point = {mnesia_dumper, post_dump}, 291 interrupted_delete(Config, ram_copies, Debug_Point). 292interrupted_after_delete_disc(suite) -> []; 293interrupted_after_delete_disc(Config) when is_list(Config) -> 294 Debug_Point = {mnesia_dumper, post_dump}, 295 interrupted_delete(Config, disc_copies, Debug_Point). 296interrupted_after_delete_do(suite) -> []; 297interrupted_after_delete_do(Config) when is_list(Config) -> 298 Debug_Point = {mnesia_dumper, post_dump}, 299 interrupted_delete(Config, disc_only_copies, Debug_Point). 300 301interrupted_delete(Config, Type, KillAt) -> 302 ?is_debug_compiled, 303 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 304 Tab = itrpt, 305 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node2]}])), 306 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 307 {_Alive, Kill} = {Node1, Node2}, 308 {success, [A]} = ?start_activities([Kill]), 309 310 setup_dbgpoint(KillAt, Kill), 311 A ! fun() -> mnesia:delete_table(Tab) end, 312 313 kill_at_debug(), 314 ?match([], mnesia_test_lib:start_mnesia([Node2], [])), 315 Bad = {badrpc, {'EXIT', {aborted,{no_exists, Tab, all}}}}, 316 ?match(Bad, rpc:call(Node1, mnesia, table_info, [Tab, all])), 317 ?match(Bad, rpc:call(Node2, mnesia, table_info, [Tab, all])), 318 ?verify_mnesia(Nodes, []). 319 320interrupted_before_add_ram(suite) -> []; 321interrupted_before_add_ram(Config) when is_list(Config) -> 322 Debug_Point = {mnesia_dumper, dump_schema_op}, 323 interrupted_add(Config, ram_copies, kill_reciever, Debug_Point). 324interrupted_before_add_disc(suite) -> []; 325interrupted_before_add_disc(Config) when is_list(Config) -> 326 Debug_Point = {mnesia_dumper, dump_schema_op}, 327 interrupted_add(Config, disc_copies, kill_reciever, Debug_Point). 328interrupted_before_add_do(suite) -> []; 329interrupted_before_add_do(Config) when is_list(Config) -> 330 Debug_Point = {mnesia_dumper, dump_schema_op}, 331 interrupted_add(Config, disc_only_copies, kill_reciever, Debug_Point). 332interrupted_before_add_kill_copier(suite) -> []; 333interrupted_before_add_kill_copier(Config) when is_list(Config) -> 334 Debug_Point = {mnesia_dumper, dump_schema_op}, 335 interrupted_add(Config, ram_copies, kill_copier, Debug_Point). 336 337interrupted_after_add_ram(suite) -> []; 338interrupted_after_add_ram(Config) when is_list(Config) -> 339 Debug_Point = {mnesia_dumper, post_dump}, 340 interrupted_add(Config, ram_copies, kill_reciever, Debug_Point). 341interrupted_after_add_disc(suite) -> []; 342interrupted_after_add_disc(Config) when is_list(Config) -> 343 Debug_Point = {mnesia_dumper, post_dump}, 344 interrupted_add(Config, disc_copies, kill_reciever, Debug_Point). 345interrupted_after_add_do(suite) -> []; 346interrupted_after_add_do(Config) when is_list(Config) -> 347 Debug_Point = {mnesia_dumper, post_dump}, 348 interrupted_add(Config, disc_only_copies, kill_reciever, Debug_Point). 349interrupted_after_add_kill_copier(suite) -> []; 350interrupted_after_add_kill_copier(Config) when is_list(Config) -> 351 Debug_Point = {mnesia_dumper, post_dump}, 352 interrupted_add(Config, ram_copies, kill_copier, Debug_Point). 353 354%%% After dump don't need debug point 355interrupted_add(Config, Type, _Where, {mnesia_dumper, post_dump}) -> 356 [Node1, Node2] = Nodes = 357 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 358 Tab = itrpt, 359 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node2]}, {local_content,true}])), 360 ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 361 ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node1, Type)), 362 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 363 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 364 ?match(stopped, mnesia:stop()), 365 ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])), 366 %% Verify 367 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 368 case Type of 369 ram_copies -> 370 ?match([], mnesia:dirty_read({itrpt, before})); 371 _ -> 372 ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before})) 373 end, 374 ?verify_mnesia(Nodes, []); 375interrupted_add(Config, Type, Who, KillAt) -> 376 ?is_debug_compiled, 377 [Node1, Node2] = Nodes = 378 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 379 {_Alive, Kill} = 380 if Who == kill_reciever -> 381 {Node1, Node2}; 382 true -> 383 {Node2, Node1} 384 end, 385 {success, [A]} = ?start_activities([Kill]), 386 Tab = itrpt, 387 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])), 388 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 389 390 setup_dbgpoint(KillAt, Kill), 391 392 A ! fun() -> mnesia:add_table_copy(Tab, Node2, Type) end, 393 kill_at_debug(), 394 ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])), 395 verify_tab(Node1, Node2), 396 ?verify_mnesia(Nodes, []). 397 398interrupted_before_move_ram(suite) -> []; 399interrupted_before_move_ram(Config) when is_list(Config) -> 400 Debug_Point = {mnesia_dumper, dump_schema_op}, 401 interrupted_move(Config, ram_copies, kill_reciever, Debug_Point). 402interrupted_before_move_disc(suite) -> []; 403interrupted_before_move_disc(Config) when is_list(Config) -> 404 Debug_Point = {mnesia_dumper, dump_schema_op}, 405 interrupted_move(Config, disc_copies, kill_reciever, Debug_Point). 406interrupted_before_move_do(suite) -> []; 407interrupted_before_move_do(Config) when is_list(Config) -> 408 Debug_Point = {mnesia_dumper, dump_schema_op}, 409 interrupted_move(Config, disc_only_copies, kill_reciever, Debug_Point). 410interrupted_before_move_kill_copier(suite) -> []; 411interrupted_before_move_kill_copier(Config) when is_list(Config) -> 412 Debug_Point = {mnesia_dumper, dump_schema_op}, 413 interrupted_move(Config, ram_copies, kill_copier, Debug_Point). 414 415interrupted_after_move_ram(suite) -> []; 416interrupted_after_move_ram(Config) when is_list(Config) -> 417 Debug_Point = {mnesia_dumper, post_dump}, 418 interrupted_move(Config, ram_copies, kill_reciever, Debug_Point). 419interrupted_after_move_disc(suite) -> []; 420interrupted_after_move_disc(Config) when is_list(Config) -> 421 Debug_Point = {mnesia_dumper, post_dump}, 422 interrupted_move(Config, disc_copies, kill_reciever, Debug_Point). 423interrupted_after_move_do(suite) -> []; 424interrupted_after_move_do(Config) when is_list(Config) -> 425 Debug_Point = {mnesia_dumper, post_dump}, 426 interrupted_move(Config, disc_only_copies, kill_reciever, Debug_Point). 427interrupted_after_move_kill_copier(suite) -> []; 428interrupted_after_move_kill_copier(Config) when is_list(Config) -> 429 Debug_Point = {mnesia_dumper, post_dump}, 430 interrupted_move(Config, ram_copies, kill_copier, Debug_Point). 431 432%%% After dump don't need debug point 433interrupted_move(Config, Type, _Where, {mnesia_dumper, post_dump}) -> 434 [Node1, Node2] = Nodes = 435 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 436 Tab = itrpt, 437 ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 438 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])), 439 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 440 ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)), 441 ?match(ok, mnesia:dirty_write({itrpt, aFter, 1})), 442 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 443 ?match(stopped, mnesia:stop()), 444 ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])), 445 %% Verify 446 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 447 ?match([{itrpt, before, 1}], mnesia:dirty_read({itrpt, before})), 448 ?match([{itrpt, aFter, 1}], mnesia:dirty_read({itrpt, aFter})), 449 ?verify_mnesia(Nodes, []); 450interrupted_move(Config, Type, Who, KillAt) -> 451 ?is_debug_compiled, 452 [Node1, Node2] = Nodes = 453 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 454 Tab = itrpt, 455 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])), 456 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 457 458 {_Alive, Kill} = 459 if Who == kill_reciever -> 460 if Type == ram_copies -> 461 {atomic, ok} = mnesia:dump_tables([Tab]); 462 true -> 463 ignore 464 end, 465 {Node1, Node2}; 466 true -> 467 {Node2, Node1} 468 end, 469 470 {success, [A]} = ?start_activities([Kill]), 471 472 setup_dbgpoint(KillAt, Kill), 473 A ! fun() -> mnesia:move_table_copy(Tab, Node1, Node2) end, 474 kill_at_debug(), 475 ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])), 476 verify_tab(Node1, Node2), 477 ?verify_mnesia(Nodes, []). 478 479interrupted_before_delcopy_ram(suite) -> []; 480interrupted_before_delcopy_ram(Config) when is_list(Config) -> 481 Debug_Point = {mnesia_dumper, dump_schema_op}, 482 interrupted_delcopy(Config, ram_copies, kill_reciever, Debug_Point). 483interrupted_before_delcopy_disc(suite) -> []; 484interrupted_before_delcopy_disc(Config) when is_list(Config) -> 485 Debug_Point = {mnesia_dumper, dump_schema_op}, 486 interrupted_delcopy(Config, disc_copies, kill_reciever, Debug_Point). 487interrupted_before_delcopy_do(suite) -> []; 488interrupted_before_delcopy_do(Config) when is_list(Config) -> 489 Debug_Point = {mnesia_dumper, dump_schema_op}, 490 interrupted_delcopy(Config, disc_only_copies, kill_reciever, Debug_Point). 491interrupted_before_delcopy_kill_copier(suite) -> []; 492interrupted_before_delcopy_kill_copier(Config) when is_list(Config) -> 493 Debug_Point = {mnesia_dumper, dump_schema_op}, 494 interrupted_delcopy(Config, ram_copies, kill_copier, Debug_Point). 495 496interrupted_after_delcopy_ram(suite) -> []; 497interrupted_after_delcopy_ram(Config) when is_list(Config) -> 498 Debug_Point = {mnesia_dumper, post_dump}, 499 interrupted_delcopy(Config, ram_copies, kill_reciever, Debug_Point). 500interrupted_after_delcopy_disc(suite) -> []; 501interrupted_after_delcopy_disc(Config) when is_list(Config) -> 502 Debug_Point = {mnesia_dumper, post_dump}, 503 interrupted_delcopy(Config, disc_copies, kill_reciever, Debug_Point). 504interrupted_after_delcopy_do(suite) -> []; 505interrupted_after_delcopy_do(Config) when is_list(Config) -> 506 Debug_Point = {mnesia_dumper, post_dump}, 507 interrupted_delcopy(Config, disc_only_copies, kill_reciever, Debug_Point). 508interrupted_after_delcopy_kill_copier(suite) -> []; 509interrupted_after_delcopy_kill_copier(Config) when is_list(Config) -> 510 Debug_Point = {mnesia_dumper, post_dump}, 511 interrupted_delcopy(Config, ram_copies, kill_copier, Debug_Point). 512 513 514%%% After dump don't need debug point 515interrupted_delcopy(Config, Type, _Where, {mnesia_dumper, post_dump}) -> 516 [Node1, Node2] = Nodes = 517 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 518 Tab = itrpt, 519 ?match({atomic, ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 520 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1,Node2]}])), 521 ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node1)), 522 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 523 ?match(stopped, mnesia:stop()), 524 ?match([], mnesia_test_lib:start_mnesia([Node1], [test])), 525 %% Verify 526 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 527 ?match([Node2], mnesia:table_info(itrpt,Type)), 528 ?verify_mnesia(Nodes, []); 529interrupted_delcopy(Config, Type, Who, KillAt) -> 530 ?is_debug_compiled, 531 [Node1, Node2] = Nodes = 532 ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 533 Tab = itrpt, 534 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1, Node2]}])), 535 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 536 537 {_Alive, Kill} = 538 if Who == kill_reciever -> 539 {Node1, Node2}; 540 true -> 541 if 542 Type == ram_copies -> 543 {atomic, ok} = mnesia:dump_tables([Tab]); 544 true -> 545 ignore 546 end, 547 {Node2, Node1} 548 end, 549 550 {success, [A]} = ?start_activities([Kill]), 551 setup_dbgpoint(KillAt, Kill), 552 A ! fun() -> mnesia:del_table_copy(Tab, Node2) end, 553 kill_at_debug(), 554 ?match([], mnesia_test_lib:start_mnesia([Kill], [itrpt])), 555 verify_tab(Node1, Node2), 556 ?verify_mnesia(Nodes, []). 557 558interrupted_before_addindex_ram(suite) -> []; 559interrupted_before_addindex_ram(Config) when is_list(Config) -> 560 Debug_Point = {mnesia_dumper, dump_schema_op}, 561 interrupted_addindex(Config, ram_copies, Debug_Point). 562interrupted_before_addindex_disc(suite) -> []; 563interrupted_before_addindex_disc(Config) when is_list(Config) -> 564 Debug_Point = {mnesia_dumper, dump_schema_op}, 565 interrupted_addindex(Config, disc_copies, Debug_Point). 566interrupted_before_addindex_do(suite) -> []; 567interrupted_before_addindex_do(Config) when is_list(Config) -> 568 Debug_Point = {mnesia_dumper, dump_schema_op}, 569 interrupted_addindex(Config, disc_only_copies, Debug_Point). 570 571interrupted_after_addindex_ram(suite) -> []; 572interrupted_after_addindex_ram(Config) when is_list(Config) -> 573 Debug_Point = {mnesia_dumper, post_dump}, 574 interrupted_addindex(Config, ram_copies, Debug_Point). 575interrupted_after_addindex_disc(suite) -> []; 576interrupted_after_addindex_disc(Config) when is_list(Config) -> 577 Debug_Point = {mnesia_dumper, post_dump}, 578 interrupted_addindex(Config, disc_copies, Debug_Point). 579interrupted_after_addindex_do(suite) -> []; 580interrupted_after_addindex_do(Config) when is_list(Config) -> 581 Debug_Point = {mnesia_dumper, post_dump}, 582 interrupted_addindex(Config, disc_only_copies, Debug_Point). 583 584 585%%% After dump don't need debug point 586interrupted_addindex(Config, Type, {mnesia_dumper, post_dump}) -> 587 [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]), 588 Tab = itrpt, 589 ?match({atomic,ok},mnesia:create_table(Tab, [{Type, Nodes}])), 590 ?match({atomic,ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 591 ?match({atomic,ok}, mnesia:add_table_index(Tab, val)), 592 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 593 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 594 ?match(stopped, mnesia:stop()), 595 ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])), 596 %% Verify 597 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 598 case Type of 599 ram_copies -> 600 ?match([], mnesia:dirty_index_read(itrpt, 1, val)); 601 _ -> 602 ?match([{itrpt, before, 1}], mnesia:dirty_index_read(itrpt, 1, val)) 603 end, 604 ?verify_mnesia(Nodes, []); 605interrupted_addindex(Config, Type, KillAt) -> 606 ?is_debug_compiled, 607 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 608 Tab = itrpt, 609 ?match({atomic, ok}, mnesia:create_table(Tab, [{Type, [Node1]}])), 610 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 611 {_Alive, Kill} = {Node1, Node2}, 612 {success, [A]} = ?start_activities([Kill]), 613 614 setup_dbgpoint(KillAt, Kill), 615 A ! fun() -> mnesia:add_table_index(Tab, val) end, 616 kill_at_debug(), 617 ?match([], mnesia_test_lib:start_mnesia([Node2], [])), 618 619 verify_tab(Node1, Node2), 620 ?match([{Tab, b, a}, {Tab, a, a}], 621 rpc:call(Node1, mnesia, dirty_index_read, [itrpt, a, val])), 622 ?match([{Tab, b, a}, {Tab, a, a}], 623 rpc:call(Node2, mnesia, dirty_index_read, [itrpt, a, val])), 624 ?verify_mnesia(Nodes, []). 625 626interrupted_before_delindex_ram(suite) -> []; 627interrupted_before_delindex_ram(Config) when is_list(Config) -> 628 Debug_Point = {mnesia_dumper, dump_schema_op}, 629 interrupted_delindex(Config, ram_copies, Debug_Point). 630interrupted_before_delindex_disc(suite) -> []; 631interrupted_before_delindex_disc(Config) when is_list(Config) -> 632 Debug_Point = {mnesia_dumper, dump_schema_op}, 633 interrupted_delindex(Config, disc_copies, Debug_Point). 634interrupted_before_delindex_do(suite) -> []; 635interrupted_before_delindex_do(Config) when is_list(Config) -> 636 Debug_Point = {mnesia_dumper, dump_schema_op}, 637 interrupted_delindex(Config, disc_only_copies, Debug_Point). 638 639interrupted_after_delindex_ram(suite) -> []; 640interrupted_after_delindex_ram(Config) when is_list(Config) -> 641 Debug_Point = {mnesia_dumper, post_dump}, 642 interrupted_delindex(Config, ram_copies, Debug_Point). 643interrupted_after_delindex_disc(suite) -> []; 644interrupted_after_delindex_disc(Config) when is_list(Config) -> 645 Debug_Point = {mnesia_dumper, post_dump}, 646 interrupted_delindex(Config, disc_copies, Debug_Point). 647interrupted_after_delindex_do(suite) -> []; 648interrupted_after_delindex_do(Config) when is_list(Config) -> 649 Debug_Point = {mnesia_dumper, post_dump}, 650 interrupted_delindex(Config, disc_only_copies, Debug_Point). 651 652%%% After dump don't need debug point 653interrupted_delindex(Config, Type, {mnesia_dumper, post_dump}) -> 654 [Node1] = Nodes = ?acquire_nodes(1, [{tc_timeout, timer:seconds(30)} | Config]), 655 Tab = itrpt, 656 ?match({atomic,ok},mnesia:create_table(Tab, [{Type, Nodes},{index,[val]}])), 657 ?match({atomic,ok},mnesia:create_table(test, [{disc_copies,[Node1]}])), 658 ?match({atomic,ok}, mnesia:del_table_index(Tab, val)), 659 ?match(ok, mnesia:dirty_write({itrpt, before, 1})), 660 ?match(ok, mnesia:dirty_write({test, found_in_log, 1})), 661 ?match(stopped, mnesia:stop()), 662 ?match([], mnesia_test_lib:start_mnesia([Node1], [itrpt,test])), 663 %% Verify 664 ?match([{test, found_in_log, 1}], mnesia:dirty_read({test, found_in_log})), 665 ?match({'EXIT',{aborted,{badarg,_}}}, mnesia:dirty_index_read(itrpt, 1, val)), 666 ?verify_mnesia(Nodes, []); 667 668interrupted_delindex(Config, Type, KillAt) -> 669 ?is_debug_compiled, 670 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 671 Tab = itrpt, 672 ?match({atomic, ok}, mnesia:create_table(Tab, [{index, [val]}, 673 {Type, [Node1]}])), 674 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 675 {_Alive, Kill} = {Node1, Node2}, 676 {success, [A]} = ?start_activities([Kill]), 677 setup_dbgpoint(KillAt, Kill), 678 A ! fun() -> mnesia:del_table_index(Tab, val) end, 679 kill_at_debug(), 680 ?match([], mnesia_test_lib:start_mnesia([Node2], [])), 681 verify_tab(Node1, Node2), 682 ?match({badrpc, _}, rpc:call(Node1, mnesia, dirty_index_read, [itrpt, a, val])), 683 ?match({badrpc, _}, rpc:call(Node2, mnesia, dirty_index_read, [itrpt, a, val])), 684 ?match([], rpc:call(Node1, mnesia, table_info, [Tab, index])), 685 ?match([], rpc:call(Node2, mnesia, table_info, [Tab, index])), 686 ?verify_mnesia(Nodes, []). 687 688interrupted_before_change_type_ram2disc(suite) -> []; 689interrupted_before_change_type_ram2disc(Config) when is_list(Config) -> 690 Debug_Point = {mnesia_dumper, dump_schema_op}, 691 interrupted_change_type(Config, ram_copies, disc_copies, changer, Debug_Point). 692interrupted_before_change_type_ram2do(suite) -> []; 693interrupted_before_change_type_ram2do(Config) when is_list(Config) -> 694 Debug_Point = {mnesia_dumper, dump_schema_op}, 695 interrupted_change_type(Config, ram_copies, disc_only_copies, changer, Debug_Point). 696interrupted_before_change_type_disc2ram(suite) -> []; 697interrupted_before_change_type_disc2ram(Config) when is_list(Config) -> 698 Debug_Point = {mnesia_dumper, dump_schema_op}, 699 interrupted_change_type(Config, disc_copies, ram_copies, changer, Debug_Point). 700interrupted_before_change_type_disc2do(suite) -> []; 701interrupted_before_change_type_disc2do(Config) when is_list(Config) -> 702 Debug_Point = {mnesia_dumper, dump_schema_op}, 703 interrupted_change_type(Config, disc_copies, disc_only_copies, changer, Debug_Point). 704interrupted_before_change_type_do2ram(suite) -> []; 705interrupted_before_change_type_do2ram(Config) when is_list(Config) -> 706 Debug_Point = {mnesia_dumper, dump_schema_op}, 707 interrupted_change_type(Config, disc_only_copies, ram_copies, changer, Debug_Point). 708interrupted_before_change_type_do2disc(suite) -> []; 709interrupted_before_change_type_do2disc(Config) when is_list(Config) -> 710 Debug_Point = {mnesia_dumper, dump_schema_op}, 711 interrupted_change_type(Config, disc_only_copies, disc_copies, changer, Debug_Point). 712interrupted_before_change_type_other_node(suite) -> []; 713interrupted_before_change_type_other_node(Config) when is_list(Config) -> 714 Debug_Point = {mnesia_dumper, dump_schema_op}, 715 interrupted_change_type(Config, ram_copies, disc_copies, the_other_one, Debug_Point). 716 717interrupted_after_change_type_ram2disc(suite) -> []; 718interrupted_after_change_type_ram2disc(Config) when is_list(Config) -> 719 Debug_Point = {mnesia_dumper, post_dump}, 720 interrupted_change_type(Config, ram_copies, disc_copies, changer, Debug_Point). 721interrupted_after_change_type_ram2do(suite) -> []; 722interrupted_after_change_type_ram2do(Config) when is_list(Config) -> 723 Debug_Point = {mnesia_dumper, post_dump}, 724 interrupted_change_type(Config, ram_copies, disc_only_copies, changer, Debug_Point). 725interrupted_after_change_type_disc2ram(suite) -> []; 726interrupted_after_change_type_disc2ram(Config) when is_list(Config) -> 727 Debug_Point = {mnesia_dumper, post_dump}, 728 interrupted_change_type(Config, disc_copies, ram_copies, changer, Debug_Point). 729interrupted_after_change_type_disc2do(suite) -> []; 730interrupted_after_change_type_disc2do(Config) when is_list(Config) -> 731 Debug_Point = {mnesia_dumper, post_dump}, 732 interrupted_change_type(Config, disc_copies, disc_only_copies, changer, Debug_Point). 733interrupted_after_change_type_do2ram(suite) -> []; 734interrupted_after_change_type_do2ram(Config) when is_list(Config) -> 735 Debug_Point = {mnesia_dumper, post_dump}, 736 interrupted_change_type(Config, disc_only_copies, ram_copies, changer, Debug_Point). 737interrupted_after_change_type_do2disc(suite) -> []; 738interrupted_after_change_type_do2disc(Config) when is_list(Config) -> 739 Debug_Point = {mnesia_dumper, post_dump}, 740 interrupted_change_type(Config, disc_only_copies, disc_copies, changer, Debug_Point). 741interrupted_after_change_type_other_node(suite) -> []; 742interrupted_after_change_type_other_node(Config) when is_list(Config) -> 743 Debug_Point = {mnesia_dumper, post_dump}, 744 interrupted_change_type(Config, ram_copies, disc_copies, the_other_one, Debug_Point). 745 746interrupted_change_type(Config, FromType, ToType, Who, KillAt) -> 747 ?is_debug_compiled, 748 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 749 Tab = itrpt, 750 ?match({atomic, ok}, mnesia:create_table(Tab, [{FromType, [Node2, Node1]}])), 751 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 752 753 {_Alive, Kill} = 754 if Who == changer -> {Node1, Node2}; 755 true -> {Node2, Node1} 756 end, 757 758 {success, [A]} = ?start_activities([Kill]), 759 setup_dbgpoint(KillAt, Kill), 760 A ! fun() -> mnesia:change_table_copy_type(Tab, Node2, ToType) end, 761 kill_at_debug(), 762 ?match([], mnesia_test_lib:start_mnesia(Nodes, [itrpt])), 763 verify_tab(Node1, Node2), 764 ?match(FromType, rpc:call(Node1, mnesia, table_info, [Tab, storage_type])), 765 ?match(ToType, rpc:call(Node2, mnesia, table_info, [Tab, storage_type])), 766 ?verify_mnesia(Nodes, []). 767 768interrupted_before_change_schema_type(suite) -> []; 769interrupted_before_change_schema_type(Config) when is_list(Config) -> 770 KillAt = {mnesia_dumper, dump_schema_op}, 771 interrupted_change_schema_type(Config, KillAt). 772 773interrupted_after_change_schema_type(suite) -> []; 774interrupted_after_change_schema_type(Config) when is_list(Config) -> 775 KillAt = {mnesia_dumper, post_dump}, 776 interrupted_change_schema_type(Config, KillAt). 777 778-define(cleanup(N, Config), 779 mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}], 780 N, Config, ?FILE, ?LINE)). 781 782interrupted_change_schema_type(Config, KillAt) -> 783 ?is_debug_compiled, 784 [Node1, Node2] = Nodes = ?acquire_nodes(2, [{tc_timeout, timer:seconds(30)} | Config]), 785 786 Tab = itrpt, 787 ?match({atomic, ok}, mnesia:create_table(Tab, [{ram_copies, [Node2, Node1]}])), 788 ?match(ok, mnesia:dirty_write({Tab, before, 1})), 789 790 {success, [A]} = ?start_activities([Node2]), 791 setup_dbgpoint(KillAt, Node2), 792 793 A ! fun() -> mnesia:change_table_copy_type(schema, Node2, ram_copies) end, 794 kill_at_debug(), 795 ?match(ok, rpc:call(Node2, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])), 796 ?match(ok, rpc:call(Node2, mnesia, wait_for_tables, [[itrpt, schema], 2000])), 797 ?match(disc_copies, rpc:call(Node1, mnesia, table_info, [schema, storage_type])), 798 ?match(ram_copies, rpc:call(Node2, mnesia, table_info, [schema, storage_type])), 799 800 %% Go back to disc_copies !! 801 {success, [B]} = ?start_activities([Node2]), 802 setup_dbgpoint(KillAt, Node2), 803 B ! fun() -> mnesia:change_table_copy_type(schema, Node2, disc_copies) end, 804 kill_at_debug(), 805 806 ?match(ok, rpc:call(Node2, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])), 807 ?match(ok, rpc:call(Node2, mnesia, wait_for_tables, [[itrpt, schema], 2000])), 808 ?match(disc_copies, rpc:call(Node1, mnesia, table_info, [schema, storage_type])), 809 ?match(disc_copies, rpc:call(Node2, mnesia, table_info, [schema, storage_type])), 810 811 ?verify_mnesia(Nodes, []), 812 ?cleanup(2, Config). 813 814%%% Helpers 815verify_tab(Node1, Node2) -> 816 ?match({atomic, ok}, 817 rpc:call(Node1, mnesia, transaction, [fun() -> mnesia:dirty_write({itrpt, a, a}) end])), 818 ?match({atomic, ok}, 819 rpc:call(Node2, mnesia, transaction, [fun() -> mnesia:dirty_write({itrpt, b, a}) end])), 820 ?match([{itrpt,a,a}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, a}])), 821 ?match([{itrpt,a,a}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, a}])), 822 ?match([{itrpt,b,a}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, b}])), 823 ?match([{itrpt,b,a}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, b}])), 824 ?match([{itrpt,before,1}], rpc:call(Node1, mnesia, dirty_read, [{itrpt, before}])), 825 ?match([{itrpt,before,1}], rpc:call(Node2, mnesia, dirty_read, [{itrpt, before}])). 826 827setup_dbgpoint(DbgPoint, Where) -> 828 Self = self(), 829 TestFun = fun(_, [InitBy]) -> 830 case InitBy of 831 schema_prepare -> 832 ignore; 833 schema_begin -> 834 ignore; 835 _Other -> 836 ?deactivate_debug_fun(DbgPoint), 837 unlink(Self), 838 Self ! {fun_done, node()}, 839 timer:sleep(infinity) 840 end 841 end, 842 %% Kill when debug has been reached 843 ?remote_activate_debug_fun(Where, DbgPoint, TestFun, []). 844 845kill_at_debug() -> 846 %% Wait till it's killed 847 receive 848 {fun_done, Node} -> 849 ?match([], mnesia_test_lib:kill_mnesia([Node])) 850 after 851 timer:minutes(1) -> ?error("Timeout in kill_at_debug", []) 852 end. 853 854