aboutsummaryrefslogblamecommitdiffstats
path: root/lib/mnesia/test/mt.erl
blob: 322bd521300a8593dda4ce598afa5ab95807f02c (plain) (tree)
1
2
3
4


                   
                                                        









































































                                                                         
                                         



                                                              
                                          
                         
                                          


                                    






                                                       












































































































































































                                                                                    
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%

%%
%%% Author: Hakan Mattsson  [email protected]
%%% Purpose: Nice shortcuts intended for testing of Mnesia
%%%
%%% See the mnesia_SUITE module about the structure of
%%% the test suite.
%%%
%%% See the mnesia_test_lib module about the test case execution.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-module(mt).
-author('[email protected]').
-export([
	 t/0, t/1, t/2, t/3,                % Run test cases
	 loop/1, loop/2, loop/3,            % loop test cases
	 doc/0, doc/1,                      % Generate test case doc
	 struct/0, struct/1,                % View test suite struct
	 shutdown/0, ping/0, start_nodes/0, % Node admin
	 read_config/0, write_config/1      % Config admin
	]).

-include("mnesia_test_lib.hrl").

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Aliases for the (sub) test suites
alias(all) -> mnesia_SUITE;
alias(atomicity) -> mnesia_atomicity_test;
alias(backup) -> mnesia_evil_backup;
alias(config) -> mnesia_config_test;
alias(consistency) -> mnesia_consistency_test;
alias(dirty) -> mnesia_dirty_access_test;
alias(durability) -> mnesia_durability_test;
alias(evil) -> mnesia_evil_coverage_test;
alias(qlc) -> mnesia_qlc_test;
alias(examples) -> mnesia_examples_test;
alias(frag) -> mnesia_frag_test;
alias(heavy) -> {mnesia_SUITE, heavy};
alias(install) -> mnesia_install_test;
alias(isolation) -> mnesia_isolation_test;
alias(light) -> {mnesia_SUITE, light};
alias(measure) -> mnesia_measure_test;
alias(medium) -> {mnesia_SUITE, medium};
alias(nice) -> mnesia_nice_coverage_test;
alias(recover) -> mnesia_recover_test;
alias(recovery) -> mnesia_recovery_test;
alias(registry) -> mnesia_registry_test;
alias(suite) -> mnesia_SUITE;
alias(trans) -> mnesia_trans_access_test;
alias(Other) -> Other.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Resolves the name of test suites and test cases
%% according to the alias definitions. Single atoms
%% are assumed to be the name of a test suite. 
resolve(Suite0) when is_atom(Suite0) ->
    case alias(Suite0) of
	Suite when is_atom(Suite) ->
	    {Suite, all};
	{Suite, Case} ->
	    {Suite, is_group(Suite,Case)}
    end;
resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
    case alias(Suite0) of
	Suite when is_atom(Suite) ->
	    {Suite, is_group(Suite,Case)};
	{Suite, Case2} ->
	    {Suite, is_group(Suite,Case2)}
    end;
resolve(List) when is_list(List) ->
    [resolve(Case) || Case <- List].

is_group(Mod, Case) ->
    try {_,_,_} = lists:keyfind(Case, 1, Mod:groups()),
	 {group, Case}
    catch _:{badmatch,_} ->
	    Case
    end.
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Run one or more test cases

%% Run the default test case with default config
t() ->
    t(read_test_case()).

%% Resolve the test case name and run the test case
%% The test case is noted as default test case
%% and the outcome of the tests are written to
%% to a file.
t(silly) ->
    mnesia_install_test:silly();
t(diskless) ->
    %% Run the default test case with default config,
    %% but diskless
    t(read_test_case(), diskless);
t(Case) ->
    %% Use the default config
    t(Case, read_config()).

t(Case, Config) when Config == diskless ->
    %% Run the test case with default config, but diskless
    Config2 = [{diskless, true} | read_config()],
    t(Case, Config2);
t(Mod, Fun) when is_atom(Mod), is_atom(Fun) ->
    %% Run the test case with default config
    t({Mod, Fun}, read_config());
t(RawCase, Config) when is_list(Config) ->
    %% Resolve the test case name and run the test case
    Case = resolve(RawCase),
    write_test_case(Case),
    Res = mnesia_test_lib:test(Case, Config),
    append_test_case_info(Case, Res).

t(Mod, Fun, Config) when Config == diskless ->
    t({Mod, Fun}, diskless).

config_fname() ->
    "mnesia_test_case_config".

%% Read default config file
read_config() ->
    Fname = config_fname(),
    mnesia_test_lib:log("Consulting file ~s...~n", [Fname]),
    case file:consult(Fname) of
        {ok, Config} ->
	    mnesia_test_lib:log("Read config ~w~n", [Config]),
            Config;
        _Error ->
	    Config = mnesia_test_lib:default_config(),
            mnesia_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
            Config
    end.

%% Write new default config file
write_config(Config) when is_list(Config) ->
    Fname = config_fname(),
    {ok, Fd} = file:open(Fname, write),
    write_list(Fd, Config),
    file:close(Fd).
	    
write_list(Fd, [H | T]) ->
    ok = io:format(Fd, "~p.~n",[H]),
    write_list(Fd, T);
write_list(_, []) ->
    ok.

test_case_fname() ->
    "mnesia_test_case_info".

%% Read name of test case
read_test_case() ->
    Fname = test_case_fname(),
    case file:open(Fname, [read]) of
	{ok, Fd} ->
	    Res = io:read(Fd, []),
	    file:close(Fd),
	    case Res of
		{ok, TestCase} ->
		    mnesia_test_lib:log("Using test case ~w from file ~s~n",
					[TestCase, Fname]),
		    TestCase;
		{error, _} ->
		    default_test_case(Fname)
	    end;
	{error, _} ->
	    default_test_case(Fname)
    end.

default_test_case(Fname) ->
    TestCase = all, 
    mnesia_test_lib:log("<>WARNING<> Cannot read file ~s, "
			"using default test case: ~w~n",
			[Fname, TestCase]),
    TestCase.

write_test_case(TestCase) ->
    Fname = test_case_fname(),
    {ok, Fd} = file:open(Fname, write),
    ok = io:format(Fd, "~p.~n",[TestCase]),
    file:close(Fd).
	    
append_test_case_info(TestCase, TestCaseInfo) ->
    Fname = test_case_fname(),
    {ok, Fd} = file:open(Fname, [read, write]),
    ok = io:format(Fd, "~p.~n",[TestCase]),
    ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
    file:close(Fd),
    TestCaseInfo.
	    
%% Generate HTML pages from the test case structure
doc() ->
    doc(suite).

doc(Case) ->
    mnesia_test_lib:doc(resolve(Case)).

%% Display out the test case structure
struct() ->
    struct(suite).

struct(Case) ->
    mnesia_test_lib:struct([resolve(Case)]).

%% Shutdown all nodes with erlang:halt/0
shutdown() ->
    mnesia_test_lib:shutdown().

%% Ping all nodes in config spec
ping() ->
    Config = read_config(),
    Nodes = mnesia_test_lib:select_nodes(all, Config, ?FILE, ?LINE),
    [{N, net_adm:ping(N)} || N <- Nodes].

%% Slave start all nodes in config spec
start_nodes() ->
    Config = read_config(),
    Nodes = mnesia_test_lib:select_nodes(all, Config, ?FILE, ?LINE),
    mnesia_test_lib:init_nodes(Nodes, ?FILE, ?LINE),
    ping().

%% loop one testcase /suite until it fails

loop(Case) ->
    loop_1(Case,-1,read_config()).

loop(M,F) when is_atom(F) ->
    loop_1({M,F},-1,read_config());
loop(Case,N) when is_integer(N) ->
    loop_1(Case, N,read_config()).

loop(M,F,N) when is_integer(N) ->
    loop_1({M,F},N,read_config()).

loop_1(Case,N,Config) when N /= 0 ->
    io:format("Loop test ~p ~n", [abs(N)]),
    case ok_result(Res = t(Case,Config)) of
	true ->
	    loop_1(Case,N-1,Config);
	error ->
	    Res
    end;
loop_1(_,_,_) ->
    ok.
	    
ok_result([{_T,{ok,_,_}}|R]) -> 
    ok_result(R);
ok_result([{_T,{TC,List}}|R]) when is_tuple(TC), is_list(List) -> 
    ok_result(List) andalso ok_result(R);
ok_result([]) -> true;
ok_result(_) -> error.