aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/compile_SUITE_data/big.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/compiler/test/compile_SUITE_data/big.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/compiler/test/compile_SUITE_data/big.erl')
-rw-r--r--lib/compiler/test/compile_SUITE_data/big.erl742
1 files changed, 742 insertions, 0 deletions
diff --git a/lib/compiler/test/compile_SUITE_data/big.erl b/lib/compiler/test/compile_SUITE_data/big.erl
new file mode 100644
index 0000000000..4cd8e15f13
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/big.erl
@@ -0,0 +1,742 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. 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%
+%%
+-module(big).
+-compile([export_all]).
+
+compiler_1() -> ok.
+
+-define(log(Format,Args),mnesia_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args),?log("<WARNING> " ++ Format,Args)).
+-define(error(Format,Args),
+ mnesia_test_lib:note_error(Format,Args,?FILE,?LINE),
+ ?log("<ERROR> " ++ Format,Args)).
+
+-define(match(ExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?log("ok, result as expected: ~p~n",[AcTuAlReS]),
+ {success,AcTuAlReS};
+ _ ->
+ ?error("actual result was: ~p~n",[AcTuAlReS]),
+ {fail,AcTuAlReS}
+ end
+ end()).
+
+-define(match_inverse(NotExpectedRes,Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ NotExpectedRes ->
+ ?error("actual result was: ~p~n",[AcTuAlReS]),
+ {fail,AcTuAlReS};
+ _ ->
+ ?log("ok, result as expected: ~p~n",[AcTuAlReS]),
+ {success,AcTuAlReS}
+ end
+ end()).
+
+-define(match_receive(ExpectedMsg),
+ ?match(ExpectedMsg,mnesia_test_lib:pick_msg())).
+
+%% ExpectedMsgs must be completely bound
+-define(match_multi_receive(ExpectedMsgs),
+ fun() ->
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ ?match(TmPeXpCtEdMsGs,
+ lists:sort(lists:map(fun(_) ->
+ mnesia_test_lib:pick_msg()
+ end,
+ TmPeXpCtEdMsGs)))
+ end()).
+
+-define(setup(), mnesia_test_lib:setup(?FILE,?LINE)).
+
+-define(start_activities(Nodes),
+ fun() ->
+ AcTiViTyPiDs =
+ lists:map(fun(Node) ->
+ spawn_link(Node,
+ mnesia_test_lib,
+ activity_evaluator,
+ [self()])
+ end,
+ Nodes),
+ ?match_multi_receive(AcTiViTyPiDs)
+ end()).
+
+-define(start_transactions(Pids),
+ ?match_multi_receive(lists:map(fun(Pid) ->
+ Pid ! begin_trans,
+ {Pid,begin_trans}
+ end,
+ Pids))).
+
+-define(acquire_nodes(N,Nodes),
+ mnesia_test_lib:acquire_nodes(N,Nodes,?FILE,?LINE)).
+
+
+
+%%% Copyright (C) 1996, Ellemtel Telecommunications Systems Laboratories
+%%% Author: Hakan Mattsson [email protected]
+%%% Purpose: Evil usage of the API
+%%%
+%%% Invoke all functions in the API and try to cover all legal uses
+%%% cases as well the illegal dito. This is a complement to the
+%%% other more explicit test cases.
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% show/0
+%%%
+%%% Prints out the complete test case structure
+%%%
+%%% show/1
+%%%
+%%% Prints out parts of the test case structure
+%%%
+%%% test/0
+%%%
+%%% Run the complete test suite.
+%%% Reads Nodes from nodes.profile and starts them if neccessary.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%% test/1
+%%%
+%%% Run parts of the test suite.
+%%% Reads Nodes from nodes.profile and starts them if neccessary.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%% test/2
+%%%
+%%% Run parts of the test suite on the given Nodes,
+%%% assuming that the nodes are up and running.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%% test/3
+%%%
+%%% Run parts of the test suite on permutations of the given Nodes,
+%%% assuming that the nodes are up and running. Uses test/2.
+%%% Kills Mnesia and wipes out the Mnesia directories as a starter.
+%%%
+%%% See the module mnesia_test_lib for further information.
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+show() -> mnesia_test_lib:show([{?MODULE,all}]).
+show(TestCases) -> mnesia_test_lib:show([{?MODULE,TestCases}]).
+test() -> mnesia_test_lib:test([{?MODULE,all}]).
+test(TestCases) -> mnesia_test_lib:test([{?MODULE,TestCases}]).
+test(TestCases,Nodes) -> mnesia_test_lib:test([{?MODULE,TestCases}],Nodes).
+test(TestCases,Nodes,Config) -> mnesia_test_lib:test([{?MODULE,TestCases}],Nodes,Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+old_all(suite) ->
+ [
+ system_info, table_info, error_description,
+ db_node_lifecycle, start_and_stop, transaction, checkpoint, backup,
+ table_lifecycle, replica_management, replica_location, index_lifecycle,
+ trans_access, dirty_access, table_sync, snmp_access, debug_support
+ ].
+
+trans_access(suite) ->
+ [ {mnesia_dirty_access_test,all} ].
+
+dirty_access(suite) ->
+ [ {mnesia_trans_access_test,all} ].
+
+%% Get meta info about Mnesia
+system_info(suite) -> [];
+system_info(Nodes) ->
+ ?match(yes,mnesia:system_info(is_running)),
+ ?match(Nodes,mnesia:system_info(db_nodes)),
+ ?match(Nodes,mnesia:system_info(running_db_nodes)),
+ ?match(true,mnesia:system_info(have_disc)),
+ ?match(A when atom(A),mnesia:system_info(debug)),
+ ?match(L when list(L),mnesia:system_info(directory)),
+ ?match(L when list(L),mnesia:system_info(log_version)),
+ ?match({_,_},mnesia:system_info(schema_version)),
+ ?match(L when list(L),mnesia:system_info(tables)),
+ ?match(L when list(L),mnesia:system_info(local_tables)),
+ ?match(L when list(L),mnesia:system_info(held_locks)),
+ ?match(L when list(L),mnesia:system_info(lock_queue)),
+ ?match(L when list(L),mnesia:system_info(transactions)),
+ ?match(I when integer(I),mnesia:system_info(transaction_failures)),
+ ?match(I when integer(I),mnesia:system_info(transaction_commits)),
+ ?match(I when integer(I),mnesia:system_info(transaction_restarts)),
+ ?match(L when list(L),mnesia:system_info(checkpoints)),
+ ?match(A when atom(A),mnesia:system_info(backup_module)),
+ ?match(true,mnesia:system_info(auto_repair)),
+ ?match({_,_},mnesia:system_info(dump_log_interval)),
+ ?match(A when atom(A),mnesia:system_info(dump_log_update_in_place)),
+ ?match(I when integer(I),mnesia:system_info(transaction_log_writes)),
+ ?match({'EXIT',{aborted,badarg}},mnesia:system_info(ali_baba)),
+ done.
+
+%% Get meta info about table
+table_info(suite) -> [];
+table_info(Nodes) ->
+ [Node1,Node2,Node3] = ?acquire_nodes(3,Nodes),
+
+ Tab = table_info,
+ Type = bag,
+ ValPos = 3,
+ Attrs = [k,v],
+ Arity = length(Attrs) +1,
+ Schema = [{name,Tab},{type,Type},{attributes,Attrs},{index,[ValPos]},
+ {disc_only_copies,[Node1]},{ram_copies,[Node2]},{disc_copies,[Node3]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+
+ Size = 10,
+ Keys = lists:seq(1,Size),
+ Records = [{Tab,A,7} || A <- Keys],
+ lists:foreach(fun(Rec) -> ?match(ok,mnesia:dirty_write(Rec)) end,Records),
+ ?match(Mem when integer(Mem),mnesia:table_info(Tab,memory)),
+ ?match(Size,mnesia:table_info(Tab,size)),
+ ?match(Type,mnesia:table_info(Tab,type)),
+ ?match([Node3],mnesia:table_info(Tab,disc_copies)),
+ ?match([Node2],mnesia:table_info(Tab,ram_copies)),
+ ?match([Node1],mnesia:table_info(Tab,disc_only_copies)),
+ Read = [Node1,Node2,Node3],
+ ?match(true,lists:member(mnesia:table_info(Tab,where_to_read),Read)),
+ Write = lists:sort([Node1,Node2,Node3]),
+ ?match(Write,lists:sort(mnesia:table_info(Tab,where_to_write))),
+ WriteLock = lists:sort([Node2,Node3]),
+ ?match([ValPos],mnesia:table_info(Tab,index)),
+ ?match(Arity,mnesia:table_info(Tab,arity)),
+ ?match(Attrs,mnesia:table_info(Tab,attributes)),
+ ?match({Tab,'_','_'},mnesia:table_info(Tab,wild_pattern)),
+ ?match({atomic,Attrs}, mnesia:transaction(fun() ->
+ mnesia:table_info(Tab,attributes) end)),
+
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add and drop db nodes
+
+db_node_lifecycle(suite) -> [];
+db_node_lifecycle(Nodes) ->
+ [Node1,Node2] = ?acquire_nodes(2,Nodes),
+ Tab = db_node_lifecycle,
+
+ Schema = [{name,Tab},{ram_copies,[Node1,Node2]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ ?match({aborted,active}, rpc:call(Node1,mnesia,del_db_node,[Node2])),
+
+ ?match([], mnesia_test_lib:stop_mnesia(Nodes)),
+ ?match(ok, mnesia:delete_schema(Nodes)),
+ ?match({error,_}, mnesia:create_schema(foo)),
+ ?match({error,_}, mnesia:create_schema([foo])),
+ ?match({error,_}, mnesia:create_schema([foo@bar])),
+ ?match({error,_}, mnesia:start()),
+
+ ?match(ok, mnesia:create_schema(Nodes)),
+ ?match([],mnesia_test_lib:start_mnesia(Nodes)),
+ ?match({atomic,ok}, rpc:call(Node1,mnesia,del_db_node,[Node2])),
+ ?match({aborted,no_exists}, rpc:call(Node1,mnesia,del_db_node,[Node2])),
+ ?match({aborted,no_exists}, rpc:call(Node1,mnesia,del_db_node,[foo])),
+ ?match({aborted,no_exists}, rpc:call(Node1,mnesia,del_db_node,[foo@bar])),
+
+ ?match([], mnesia_test_lib:stop_mnesia([Node2])),
+ ?match(ok,mnesia:delete_schema([Node2])),
+ AddFun = fun() -> ?match({aborted,nested_transaction},
+ mnesia:add_db_node(Node2)), ok end,
+ ?match({atomic,ok},rpc:call(Node1,mnesia,transaction,[AddFun])),
+ DelFun = fun() -> ?match({aborted,nested_transaction},
+ mnesia:del_db_node(Node2)), ok end,
+ ?match({atomic,ok},rpc:call(Node1,mnesia,transaction,[DelFun])),
+
+ ?match({atomic,ok}, rpc:call(Node1,mnesia,add_db_node,[Node2])),
+ ?match({aborted,already_exists}, rpc:call(Node1,mnesia,add_db_node,[Node2])),
+ ?match([],mnesia_test_lib:start_mnesia([Node2])),
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Start and stop the system
+
+start_and_stop(suite) -> [];
+start_and_stop(Nodes) ->
+ [Node1] = ?acquire_nodes(1,Nodes),
+
+ ?match(stopped, rpc:call(Node1,mnesia,stop,[])),
+ ?match(stopped, rpc:call(Node1,mnesia,stop,[])),
+ ?match({started,_}, rpc:call(Node1,mnesia,start,[])),
+ ?match({started,_}, rpc:call(Node1,mnesia,start,[])),
+ ?match(stopped, rpc:call(Node1,mnesia,stop,[])),
+ ?match([],mnesia_test_lib:start_mnesia(Nodes)),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Checkpoints and backup management
+
+checkpoint(suite) -> [];
+checkpoint(Nodes) ->
+ OneNode = ?acquire_nodes(1,Nodes),
+ checkpoint(OneNode,Nodes),
+ TwoNodes = ?acquire_nodes(2,Nodes),
+ checkpoint(TwoNodes,Nodes).
+
+checkpoint(TabNodes,Nodes) ->
+ [Node1] = ?acquire_nodes(1,TabNodes),
+ CreateTab = fun(Type,N,Ns) ->
+ Tab0 = lists:concat(["local_checkpoint_",Type,N]),
+ Tab = list_to_atom(Tab0),
+ Schema = [{name,Tab},{Type,Ns}],
+ ?match({atomic,ok},mnesia:delete_table(Tab)),
+ ?match({atomic,ok},mnesia:create_table(Schema)),
+ Tab
+ end,
+ CreateTabs = fun(Type) ->
+ CreateTab(Type,1,hd(TabNodes)),
+ CreateTab(Type,2,TabNodes),
+ CreateTab(Type,3,lists:last(TabNodes))
+ end,
+ Types = [ram_copies,disc_copies,disc_only_copies],
+ Tabs = lists:append(lists:map(CreateTabs,Types)),
+ Recs = lists:sort([{T,N,N} || T <- Tabs,N <- lists:seq(1,10)]),
+ lists:foreach(fun(R) -> ?match(ok,mnesia:dirty_write(R)) end,Recs),
+
+ CpName = a_checkpoint_name,
+ MinArgs = [{name,CpName},{min,Tabs},{allow_remote,false}],
+ ?match({ok,CpName,[Node1]},
+ rpc:call(Node1,mnesia,activate_checkpoint,[MinArgs])),
+ ?match(ok,rpc:call(Node1,mnesia,deactivate_checkpoint,[CpName])),
+
+ MaxArgs = [{name,CpName},{max,Tabs},{allow_remote,true}],
+ ?match({ok,CpName,[Node1]},
+ rpc:call(Node1,mnesia,activate_checkpoint,[MaxArgs])),
+ ?match(ok,rpc:call(Node1,mnesia,deactivate_checkpoint,[CpName])),
+
+ Args = [{name,CpName},{min,Tabs},{allow_remote,false}],
+ ?match({ok,CpName,[Node1]},
+ rpc:call(Node1,mnesia,activate_checkpoint,[Args])),
+ Recs2 = lists:sort([{T,K,0} || {T,K,_} <- Recs]),
+ lists:foreach(fun(R) -> ?match(ok,mnesia:dirty_write(R)) end,Recs2),
+ ?match({atomic,ok},rpc:call(Node1,mnesia,deactivate_checkpoint,[CpName])),
+
+ ?match({error,no_exists},mnesia:deactivate_checkpoint(CpName)),
+ ?match({error,badarg},mnesia:activate_checkpoint(foo)),
+ ?match({error,badarg},mnesia:activate_checkpoint([{foo,foo}])),
+ ?match({error,badarg},mnesia:activate_checkpoint([{max,foo}])),
+ ?match({error,badarg},mnesia:activate_checkpoint([{min,foo}])),
+ ?match({error,no_exists},mnesia:activate_checkpoint([{min,[foo@bar]}])),
+ ?match({error,badarg},mnesia:activate_checkpoint([{allow_remote,foo}])),
+
+ Fun = fun(Tab) -> ?match({atomic,ok},mnesia:delete_table(Tab)) end,
+ lists:foreach(Fun,Tabs),
+ done.
+
+backup(suite) ->
+ [
+ backup_schema, restore_schema, backup_checkpoint, restore_tables
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Use and misuse transactions
+
+transaction(suite) -> [];
+transaction(Nodes) ->
+ [Node1] = ?acquire_nodes(1,Nodes),
+ ?match({atomic,ali_baba}, mnesia:transaction(fun() -> ali_baba end)),
+ ?match({aborted,_}, mnesia:transaction(no_fun)),
+ ?match({aborted,_}, mnesia:transaction(?MODULE,no_fun,[foo])),
+
+ {success,[A,B,C,D,E,F,G,H]} = ?start_activities(lists:duplicate(8,Node1)),
+ ?start_transactions([A,B,C,D,E,F,G,H]),
+
+ A ! fun() -> mnesia:abort(abort_bad_trans) end,
+ ?match_receive({A,{aborted,abort_bad_trans}}),
+
+ B ! fun() -> 1 = 2 end,
+ ?match_receive({B,{aborted,_}}),
+
+ C ! fun() -> throw(throw_bad_trans) end,
+ ?match_receive({C,{aborted,{throw,throw_bad_trans}}}),
+
+ D ! fun() -> exit(exit_bad_trans) end,
+ ?match_receive({D,{aborted,exit_bad_trans}}),
+
+ E ! fun() -> exit(normal) end,
+ ?match_receive({E,{aborted,normal}}),
+
+ F ! fun() -> exit(abnormal) end,
+ ?match_receive({F,{aborted,abnormal}}),
+
+ G ! fun() -> exit(G,abnormal) end,
+ ?match_receive({'EXIT',G,abnormal}),
+
+ H ! fun() -> exit(H,kill) end,
+ ?match_receive({'EXIT',H,killed}),
+
+ ?match({atomic,ali_baba},
+ mnesia:transaction(fun() -> ali_baba end,infinity)),
+ ?match({atomic,ali_baba},mnesia:transaction(fun() -> ali_baba end,1)),
+ ?match({atomic,ali_baba},mnesia:transaction(fun() -> ali_baba end,0)),
+ ?match({atomic,ali_baba},mnesia:transaction(fun() -> ali_baba end,-1)),
+ ?match({atomic,ali_baba},mnesia:transaction(fun() -> ali_baba end,foo)),
+ Fun = fun() -> ?match({aborted,nested_transaction},
+ mnesia:transaction(fun() -> ok end)), ok end,
+ ?match({atomic,ok},mnesia:transaction(Fun)),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Create and delete tables
+
+%% Get meta info about table
+
+replica_location(suite) -> [];
+replica_location(Nodes) ->
+ [Node1,Node2,Node3] = ?acquire_nodes(3,Nodes),
+ Tab = replica_location,
+
+ %% Create three replicas
+ Schema = [{name,Tab},{disc_only_copies,[Node1]},
+ {ram_copies,[Node2]},{disc_copies,[Node3]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node1],[Node2],[Node3],Nodes),
+
+ %% Delete one replica
+ ?match({atomic,ok}, mnesia:del_table_copy(Tab, Node2)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node1],[],[Node3],Nodes),
+
+ %% Move one replica
+ ?match({atomic,ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2],[],[Node3],Nodes),
+
+ %% Change replica type
+ ?match({atomic,ok}, mnesia:change_table_copy_type(Tab, Node2,ram_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[],[Node2],[Node3],Nodes),
+
+ done.
+
+table_lifecycle(suite) -> [];
+table_lifecycle(Nodes) ->
+ [Node1,Node2] = ?acquire_nodes(2,Nodes),
+
+ ?match({atomic,ok}, mnesia:create_table([{type,bag},
+ {ram_copies,[Node1]},
+ {attributes,[rajtan,tajtan]},
+ {name,order_of_args}])),
+ ?match([],mnesia:dirty_read({order_of_args,4711})),
+ ?match({atomic,ok}, mnesia:create_table([{name,already_exists},
+ {ram_copies,[Node1]}])),
+ ?match({aborted,already_exists},
+ mnesia:create_table([{name,already_exists},{ram_copies,[Node1]}])),
+ ?match({aborted,not_a_db_node},
+ mnesia:create_table([{name,no_node},{ram_copies,[foo]}])),
+ ?match({aborted,not_a_db_node},
+ mnesia:create_table([{name,no_host},{ram_copies,[foo@bar]}])),
+ ?match({aborted,badarg},
+ mnesia:create_table([{name,zero_arity},{attributes,[]}])),
+ ?match({aborted,badarg}, mnesia:create_table([])),
+ ?match({aborted,badarg}, mnesia:create_table(atom)),
+ ?match({aborted,badarg},
+ mnesia:create_table({cstruct,table_name_as_atom})),
+ ?match({aborted,bad_type},
+ mnesia:create_table([{name,no_host},{ram_copies,foo}])),
+ ?match({aborted,bad_type},
+ mnesia:create_table([{name,no_host},{disc_only_copies,foo}])),
+ ?match({aborted,bad_type},
+ mnesia:create_table([{name,no_host},{disc_copies,foo}])),
+
+ CreateFun =
+ fun() -> ?match({aborted,nested_transaction},
+ mnesia:create_table([{name,nested_trans}])), ok
+ end,
+ ?match({atomic,ok},mnesia:transaction(CreateFun)),
+ ?match({atomic,ok},mnesia:create_table([{name,remote_tab},
+ {ram_copies,[Node2]}])),
+
+ ?match({atomic,ok}, mnesia:create_table([{name,a_brand_new_tab},
+ {ram_copies,[Node1]}])),
+ ?match([],mnesia:dirty_read({a_brand_new_tab,4711})),
+ ?match({atomic,ok}, mnesia:delete_table(a_brand_new_tab)),
+ ?match({'EXIT',{aborted,no_exists}},
+ mnesia:dirty_read({a_brand_new_tab,4711})),
+ ?match({aborted,no_exists}, mnesia:delete_table(a_brand_new_tab)),
+ ?match({aborted,badarg}, mnesia:create_table([])),
+
+ ?match({atomic,ok}, mnesia:create_table([{name,nested_del_trans},
+ {ram_copies,[Node1]}])),
+ DeleteFun = fun() -> ?match({aborted,nested_transaction},
+ mnesia:delete_table(nested_del_trans)), ok end,
+ ?match({atomic,ok}, mnesia:transaction(DeleteFun)),
+
+ ?match({aborted,bad_type},
+ mnesia:create_table([{name,create_with_index},{index,2}])),
+ ?match({aborted,bad_index},
+ mnesia:create_table([{name,create_with_index},{index,[-1]}])),
+ ?match({aborted,bad_index},
+ mnesia:create_table([{name,create_with_index},{index,[0]}])),
+ ?match({aborted,bad_index},
+ mnesia:create_table([{name,create_with_index},{index,[1]}])),
+ ?match({aborted,bad_index},
+ mnesia:create_table([{name,create_with_index},{index,[2]}])),
+ ?match({atomic,ok},
+ mnesia:create_table([{name,create_with_index},{index,[3]},
+ {ram_copies,[Node1]}])),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add, drop and move replicas, change storage types
+%% Change table layout (only arity change supported)
+
+replica_management(suite) -> [];
+replica_management(Nodes) ->
+ %% add_table_copy/3, del_table_copy/2, move_table_copy/3,
+ %% change_table_copy_type/3, transform_table/3
+
+ [Node1,Node2,Node3] = ?acquire_nodes(3,Nodes),
+
+ Tab = replica_management,
+ Attrs = [k,v],
+
+ %%
+ %% Add, delete and change replicas
+ %%
+ ?match({atomic,ok},
+ mnesia:create_table([{name,Tab},{attributes,Attrs},
+ {ram_copies,[Node1]}])),
+ mnesia_test_lib:verify_replica_location(Tab,[],[Node1],[],Nodes),
+ %% R - -
+ ?match({aborted,combine_error},
+ mnesia:add_table_copy(Tab, Node2, disc_copies)),
+ ?match({aborted,combine_error},
+ mnesia:change_table_copy_type(Tab, Node1, disc_copies)),
+ ?match({atomic,ok}, mnesia:del_table_copy(Tab,Node1)),
+ mnesia_test_lib:verify_replica_location(Tab,[],[],[],Nodes),
+ %% - - -
+ ?match({aborted,no_exists},
+ mnesia:add_table_copy(Tab, Node3, ram_copies)),
+
+ ?match({atomic,ok}, mnesia:create_table([{name,Tab},
+ {attributes,Attrs},
+ {disc_copies,[Node1]}])),
+ mnesia_test_lib:verify_replica_location(Tab,[],[],[Node1],Nodes),
+ %% D - -
+ ?match({aborted,badarg},
+ mnesia:add_table_copy(Tab, Node2, bad_storage_type)),
+ ?match({atomic,ok}, mnesia:add_table_copy(Tab, Node2, disc_only_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2],[],[Node1],Nodes),
+ %% D DO -
+ ?match({atomic,ok}, mnesia:add_table_copy(Tab, Node3, ram_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2],[Node3],[Node1],Nodes),
+ %% D DO R
+ ?match({atomic,ok},
+ mnesia:change_table_copy_type(Tab, Node1, disc_only_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node1,Node2],[Node3],[],Nodes),
+ %% DO DO R
+ ?match({aborted,already_exists},
+ mnesia:add_table_copy(Tab, Node3, ram_copies)),
+ ?match({atomic,ok}, mnesia:del_table_copy(Tab, Node1)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2],[Node3],[],Nodes),
+ %% - DO R
+ ?match({aborted,_}, mnesia:del_table_copy(Tab, Node1)),
+ ?match({atomic,ok}, mnesia:add_table_copy(Tab, Node1, disc_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2],[Node3],[Node1],Nodes),
+ %% D DO R
+ ?match({atomic,ok},
+ mnesia:change_table_copy_type(Tab, Node3, disc_only_copies)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node2,Node3],[],[Node1],Nodes),
+ %% D DO DO
+ ?match({atomic,ok}, mnesia:del_table_copy(Tab, Node2)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node3],[],[Node1],Nodes),
+ %% D - DO
+ ?match({aborted,already_exists},
+ mnesia:change_table_copy_type(Tab, Node1, disc_copies)),
+
+ %%
+ %% Move replica
+ %%
+ ?match({atomic,ok}, mnesia:move_table_copy(Tab,Node1,Node2)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node3],[],[Node2],Nodes),
+ %% - D DO
+ ?match({aborted,_}, mnesia:move_table_copy(Tab,Node1,Node2)),
+ ?match([], mnesia_test_lib:stop_mnesia([Node3])),
+ mnesia_test_lib:verify_replica_location(Tab,[Node3],[],[Node2],
+ Nodes -- [Node3]),
+ %% - D DO
+ ?match({atomic,ok}, mnesia:move_table_copy(Tab,Node3,Node1)),
+ mnesia_test_lib:verify_replica_location(Tab,[Node1],[],[Node2],
+ Nodes -- [Node3]),
+ %% DO D -
+ ?match([],mnesia_test_lib:start_mnesia([Node3])),
+ mnesia_test_lib:verify_replica_location(Tab,[Node1],[],[Node2],Nodes),
+ %% DO D -
+
+ %%
+ %% Transformer
+ %%
+
+ NewAttrs = Attrs ++ [extra],
+ Transformer =
+ fun(Rec) -> list_to_tuple(tuple_to_list(Rec) ++ [initial_value]) end,
+ ?match({atomic,ok}, mnesia:transform_table(Tab, Transformer,NewAttrs)),
+ ?match({atomic,ok}, mnesia:transform_table(Tab, fun(R) -> R end, Attrs)),
+ ?match({aborted,bad_type}, mnesia:transform_table(Tab, Transformer, 0)),
+ ?match({aborted,bad_type}, mnesia:transform_table(Tab, Transformer, -1)),
+ ?match({aborted,badarg}, mnesia:transform_table(Tab, Transformer, [])),
+ ?match({aborted,bad_type}, mnesia:transform_table(Tab, no_fun, NewAttrs)),
+
+ NestedFun =
+ fun() ->
+ ?match({aborted,_},
+ mnesia:move_table_copy(Tab,Node1,Node2)),
+ ?match({aborted,_},
+ mnesia:add_table_copy(Tab,Node1,ram_copies)),
+ ?match({aborted,_},
+ mnesia:del_table_copy(Tab,Node1)),
+ T = fun(_) -> 4711 end,
+ ?match({aborted,_},
+ mnesia:transform_table(Tab,Transformer, T)),
+ ok
+ end,
+ ?match({atomic,ok},mnesia:transaction(NestedFun)),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Add and drop indecies
+
+index_lifecycle(suite) ->
+ [ add_table_index, create_live_table_index, del_table_index ].
+
+%% Add table index
+
+add_table_index(suite) -> [];
+add_table_index(Nodes) ->
+ [Node1] = ?acquire_nodes(1,Nodes),
+ Tab = add_table_index,
+ Schema = [{name,Tab},{attributes,[k,v]},{ram_copies,[Node1]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ ?match({aborted,bad_index}, mnesia:add_table_index(Tab,BadValPos)),
+ ?match({aborted,bad_index}, mnesia:add_table_index(Tab,2)),
+ ?match({aborted,bad_index}, mnesia:add_table_index(Tab,1)),
+ ?match({aborted,bad_index}, mnesia:add_table_index(Tab,0)),
+ ?match({aborted,bad_index}, mnesia:add_table_index(Tab,-1)),
+ ?match({atomic,ok}, mnesia:add_table_index(Tab,ValPos)),
+ ?match({aborted,already_exists}, mnesia:add_table_index(Tab,ValPos)),
+
+ NestedFun = fun() ->
+ ?match({aborted,nested_transaction},
+ mnesia:add_table_index(Tab,ValPos)),
+
+ ok
+ end,
+ ?match({atomic,ok},mnesia:transaction(NestedFun)),
+ done.
+
+create_live_table_index(suite) -> [];
+create_live_table_index(Nodes) ->
+ [Node1] = ?acquire_nodes(1,Nodes),
+ Tab = create_live_table_index,
+ Schema = [{name,Tab},{attributes,[k,v]},{ram_copies,[Node1]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ mnesia:dirty_write({Tab,1,2}),
+
+ Fun = fun() ->
+ ?match(ok, mnesia:write({Tab,2,2})),
+ ok
+ end,
+ ?match({atomic,ok},mnesia:transaction(Fun)),
+ ?match({atomic,ok}, mnesia:add_table_index(Tab,ValPos)),
+ done.
+
+%% Drop table index
+
+del_table_index(suite) ->[];
+del_table_index(Nodes) ->
+ [Node1] = ?acquire_nodes(1,Nodes),
+ Tab = del_table_index,
+ Schema = [{name,Tab},{attributes,[k,v]},{ram_copies,[Node1]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+ ValPos = 3,
+ BadValPos = ValPos + 1,
+ ?match({atomic,ok}, mnesia:add_table_index(Tab,ValPos)),
+ ?match({aborted,no_exists},
+ mnesia:del_table_index(Tab,BadValPos)),
+ ?match({atomic,ok}, mnesia:del_table_index(Tab,ValPos)),
+
+ NestedFun =
+ fun() ->
+ ?match({aborted,nested_transaction},
+ mnesia:del_table_index(Tab,ValPos)),
+ ok
+ end,
+ ?match({atomic,ok},mnesia:transaction(NestedFun)),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Syncronize table with log or disc
+%%
+table_sync(suite) ->
+ [ dump_tables, dump_log, change_dump_log_config, wait_for_tables, force_load_table ].
+
+%% Dump ram tables on disc
+dump_tables(suite) -> [];
+dump_tables(Nodes) ->
+ [Node1,Node2] = ?acquire_nodes(2,Nodes),
+ Tab = dump_tables,
+ Schema = [{name,Tab},{attributes,[k,v]},{ram_copies,[Node2]}],
+ ?match({atomic,ok}, mnesia:create_table(Schema)),
+
+ %% Dump 10 records
+ Size = 10,
+ Keys = lists:seq(1,Size),
+ Records = [{Tab,A,7} || A <- Keys],
+ lists:foreach(fun(Rec) -> ?match(ok,mnesia:dirty_write(Rec)) end,Records),
+ AllKeys = fun() -> lists:sort(mnesia:all_keys(Tab)) end,
+
+ ?match({atomic,Keys}, mnesia:transaction(AllKeys)),
+ ?match(ok, mnesia:dump_tables(Tab)),
+
+ %% Delete one record
+ ?match(ok,mnesia:dirty_delete({Tab,5})),
+ Keys2 = lists:delete(5,Keys),
+ ?match({atomic,Keys2}, mnesia:transaction(AllKeys)),
+
+ %% Check that all 10 is restored after a stop
+ ?match([], mnesia_test_lib:stop_mnesia([Node1,Node2])),
+ ?match([],mnesia_test_lib:start_mnesia([Node1,Node2])),
+ ?match(ok,mnesia:wait_for_tables([Tab],infinity)),
+ ?match({atomic,Keys}, mnesia:transaction(AllKeys)),
+
+ ?match(ok, mnesia:dump_tables([foo])),
+ done.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Make Mnesia table accessible via SNMP
+
+snmp_access(suite) ->
+ [
+ snmp_open_table, snmp_close_table,
+ snmp_get_row, snmp_get_next_index, snmp_get_mnesia_key
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Check that the debug support has not decayed
+
+debug_support(suite) ->
+ [ info, schema, schema, kill, lkill ].
+