144
144
global:register_name(mnesia_global_logger, group_leader()),
147
fin_per_testcase(_Func, Config) ->
147
end_per_testcase(_Func, Config) ->
148
148
global:unregister_name(mnesia_global_logger),
149
149
%% Nodes = select_nodes(all, Config, ?FILE, ?LINE),
150
150
%% rpc:multicall(Nodes, mnesia, lkill, []),
248
248
slave_start_link(Host, Name, Retries) ->
249
249
Debug = atom_to_list(mnesia:system_info(debug)),
250
Args = "-mnesia debug " ++ Debug ++
252
filename:dirname(code:which(?MODULE)) ++
254
filename:dirname(code:which(mnesia)),
250
Args = "-mnesia debug " ++ Debug ++
252
filename:dirname(code:which(?MODULE)) ++
254
filename:dirname(code:which(mnesia)),
255
255
case starter(Host, Name, Args) of
257
257
?match(pong, net_adm:ping(NewNode)),
305
305
io:format(Fd, "<TITLE>Test specification for ~p</TITLE>.~n", [TestCases]),
306
306
io:format(Fd, "<H1>Test specification for ~p</H1>~n", [TestCases]),
307
307
io:format(Fd, "Test cases which not are implemented yet are written in <B>bold face</B>.~n~n", []),
309
309
io:format(Fd, "<BR><BR>~n", []),
310
310
io:format(Fd, "~n<DL>~n", []),
311
311
do_doc(Fd, TestCases, []),
414
414
test_driver({Module, TestCases}, Config) when is_list(TestCases)->
415
415
test_driver(default_module(Module, TestCases), Config);
416
test_driver({_, {Module, TestCase}}, Config) ->
417
test_driver({Module, TestCase}, Config);
416
test_driver({Module, all}, Config) ->
417
get_suite(Module, all, Config);
418
test_driver({Module, G={group, _}}, Config) ->
419
get_suite(Module, G, Config);
420
test_driver({_, {group, Module, Group}}, Config) ->
421
get_suite(Module, {group, Group}, Config);
418
423
test_driver({Module, TestCase}, Config) ->
419
424
Sec = timer:seconds(1) * 1000,
420
case get_suite(Module, TestCase) of
421
[] when Config == suite ->
422
427
{Module, TestCase, 'IMPL'};
424
429
log("Eval test case: ~w~n", [{Module, TestCase}]),
426
timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
427
log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
429
Suite when is_list(Suite), Config == suite ->
430
Res = test_driver(default_module(Module, Suite), Config),
431
{{Module, TestCase}, Res};
432
Suite when is_list(Suite) ->
433
log("Expand test case ~w~n", [{Module, TestCase}]),
434
Def = default_module(Module, Suite),
435
{T, Res} = timer:tc(?MODULE, test_driver, [Def, Config]),
436
{T div Sec, {{Module, TestCase}, Res}};
437
'NYI' when Config == suite ->
438
{Module, TestCase, 'NYI'};
440
log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
441
{0, {skip, {Module, TestCase}, "NYI"}}
430
try timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]) of
432
log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
434
catch error:function_clause ->
435
log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
436
{0, {skip, {Module, TestCase}, "NYI"}}
443
439
test_driver(TestCase, Config) ->
444
440
DefaultModule = mnesia_SUITE,
449
445
default_module(DefaultModule, TestCases) when is_list(TestCases) ->
448
{group, _} -> {true, {DefaultModule, T}};
453
450
T -> {true, {DefaultModule, T}}
456
453
lists:zf(Fun, TestCases).
455
get_suite(Module, TestCase, Config) ->
456
case get_suite(Module, TestCase) of
457
Suite when is_list(Suite), Config == suite ->
458
Res = test_driver(default_module(Module, Suite), Config),
459
{{Module, TestCase}, Res};
460
Suite when is_list(Suite) ->
461
log("Expand test case ~w~n", [{Module, TestCase}]),
462
Def = default_module(Module, Suite),
463
{T, Res} = timer:tc(?MODULE, test_driver, [Def, Config]),
464
Sec = timer:seconds(1) * 1000,
465
{T div Sec, {{Module, TestCase}, Res}};
466
'NYI' when Config == suite ->
467
{Module, TestCase, 'NYI'};
469
log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
470
{0, {skip, {Module, TestCase}, "NYI"}}
458
473
%% Returns a list (possibly empty) or the atom 'NYI'
459
get_suite(Mod, Fun) ->
460
case catch (apply(Mod, Fun, [suite])) of
474
get_suite(Mod, {group, Suite}) ->
476
Groups = Mod:groups(),
477
{_, _, TCList} = lists:keyfind(Suite, 1, Groups),
481
io:format("Not implemented ~p ~p (~p ~p)~n",
482
[Mod,Suite,Reason, erlang:get_stacktrace()]),
485
get_suite(Mod, all) ->
486
case catch (apply(Mod, all, [])) of
461
487
{'EXIT', _} -> 'NYI';
462
488
List when is_list(List) -> List
490
get_suite(_Mod, _Fun) ->
465
493
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
492
520
{'EXIT', Pid, {skipped, Reason}} ->
493
521
log("<WARNING> Test case ~w skipped, because ~p~n",
494
522
[{Mod, Fun}, Reason]),
495
Mod:fin_per_testcase(Fun, Config),
523
Mod:end_per_testcase(Fun, Config),
496
524
{skip, {Mod, Fun}, Reason};
497
525
{'EXIT', Pid, Reason} ->
498
526
log("<>ERROR<> Eval process ~w exited, because ~p~n",
499
527
[{Mod, Fun}, Reason]),
500
Mod:fin_per_testcase(Fun, Config),
528
Mod:end_per_testcase(Fun, Config),
501
529
{crash, {Mod, Fun}, Reason}
504
532
test_case_evaluator(Mod, Fun, [Config]) ->
505
533
NewConfig = Mod:init_per_testcase(Fun, Config),
506
R = apply(Mod, Fun, [NewConfig]),
507
Mod:fin_per_testcase(Fun, NewConfig),
508
exit({test_case_ok, R}).
535
R = apply(Mod, Fun, [NewConfig]),
536
Mod:end_per_testcase(Fun, NewConfig),
537
exit({test_case_ok, R})
538
catch error:function_clause ->
539
exit({skipped, 'NYI'})
510
542
activity_evaluator(Coordinator) ->
511
543
activity_evaluator_loop(Coordinator),
603
635
select_nodes(N, Config, File, Line) ->
604
636
prepare_test_case([], N, Config, File, Line).
606
638
prepare_test_case(Actions, N, Config, File, Line) ->
607
639
NodeList1 = lookup_config(nodes, Config),
608
640
NodeList2 = lookup_config(nodenames, Config), %% For testserver
719
751
pick_nodes(all, Nodes, File, Line) ->
720
752
pick_nodes(length(Nodes), Nodes, File, Line);
721
753
pick_nodes(N, [H | T], File, Line) when N > 0 ->
722
[H | pick_nodes(N - 1, T, File, Line)];
754
[H | pick_nodes(N - 1, T, File, Line)];
723
755
pick_nodes(0, _Nodes, _File, _Line) ->
725
757
pick_nodes(N, [], File, Line) ->
726
758
?skip("Test case (~p(~p)) ignored: ~p nodes missing~n",
727
759
[File, Line, N]).
729
761
init_nodes([Node | Nodes], File, Line) ->
730
762
case net_adm:ping(Node) of
810
842
%% Start Mnesia on all given nodes and wait for specified
811
843
%% tables to be accessible on each node. The atom all means
812
844
%% that we should wait for all tables to be loaded
814
846
%% Returns a list of error tuples {BadNode, mnesia, Reason}
815
847
start_mnesia(Nodes) ->
816
848
start_appls([mnesia], Nodes).
817
849
start_mnesia(Nodes, Tabs) when is_list(Nodes) ->
818
850
start_appls([mnesia], Nodes, [], Tabs).
820
852
%% Wait for the tables to be accessible from all nodes in the list
821
853
%% and that all nodes are aware of that the other nodes also ...
822
854
sync_tables(Nodes, Tabs) ->
892
924
mnesia:table_info(Tab, ram_copies),
893
925
Local = mnesia:table_info(Tab, local_content),
894
926
case Copies -- Nodes of
896
928
verify_nodes(Tabs, 0);
897
929
_Else when Local == true, Nodes /= [] ->
898
930
verify_nodes(Tabs, 0);
903
log("<>WARNING<> ~w Waiting for table: ~p on ~p ~n",
935
log("<>WARNING<> ~w Waiting for table: ~p on ~p ~n",
904
936
[node(), Tab, Else]),
908
940
timer:sleep(500),
909
941
verify_nodes([Tab| Tabs], N2)
913
945
%% Nicely stop Mnesia on all given nodes
915
947
%% Returns a list of error tuples {BadNode, Reason}
916
948
stop_mnesia(Nodes) when is_list(Nodes) ->
917
949
stop_appls([mnesia], Nodes).