aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mnesia/test')
-rw-r--r--lib/mnesia/test/Makefile26
-rw-r--r--lib/mnesia/test/ext_test.erl237
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl21
-rw-r--r--lib/mnesia/test/mnesia_atomicity_test.erl43
-rw-r--r--lib/mnesia/test/mnesia_bench_SUITE.erl21
-rw-r--r--lib/mnesia/test/mnesia_config_backup.erl26
-rw-r--r--lib/mnesia/test/mnesia_config_event.erl23
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl75
-rw-r--r--lib/mnesia/test/mnesia_consistency_test.erl83
-rw-r--r--lib/mnesia/test/mnesia_cost.erl33
-rw-r--r--lib/mnesia/test/mnesia_dbn_meters.erl76
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl164
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl52
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl177
-rw-r--r--lib/mnesia/test/mnesia_examples_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_frag_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_inconsistent_database_test.erl23
-rw-r--r--lib/mnesia/test/mnesia_install_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl98
-rw-r--r--lib/mnesia/test/mnesia_majority_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl23
-rw-r--r--lib/mnesia/test/mnesia_meter.erl21
-rw-r--r--lib/mnesia/test/mnesia_nice_coverage_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_recovery_test.erl36
-rw-r--r--lib/mnesia/test/mnesia_registry_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_schema_recovery_test.erl21
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl36
-rw-r--r--lib/mnesia/test/mnesia_test_lib.hrl23
-rw-r--r--lib/mnesia/test/mnesia_tpcb.erl92
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl32
-rwxr-xr-xlib/mnesia/test/mt21
-rw-r--r--lib/mnesia/test/mt.erl23
34 files changed, 1091 insertions, 583 deletions
diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile
index 45ce5b1983..5b61b1af65 100644
--- a/lib/mnesia/test/Makefile
+++ b/lib/mnesia/test/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2012. All Rights Reserved.
+# Copyright Ericsson AB 1996-2016. 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.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
@@ -51,7 +52,8 @@ MODULES= \
mnesia_schema_recovery_test \
mnesia_measure_test \
mnesia_cost \
- mnesia_dbn_meters
+ mnesia_dbn_meters \
+ ext_test
DocExamplesDir := ../doc/src/
diff --git a/lib/mnesia/test/ext_test.erl b/lib/mnesia/test/ext_test.erl
new file mode 100644
index 0000000000..45ddb148bc
--- /dev/null
+++ b/lib/mnesia/test/ext_test.erl
@@ -0,0 +1,237 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ext_test).
+
+%% Initializations
+-export([init_backend/0, add_aliases/1, remove_aliases/1,
+ check_definition/4, semantics/2]).
+
+-export([
+ create_table/3, load_table/4,
+ delete_table/2, close_table/2, sync_close_table/2,
+
+ sender_init/4,
+ receiver_first_message/4, receive_data/5, receive_done/4,
+
+ index_is_consistent/3, is_index_consistent/2,
+
+ real_suffixes/0, tmp_suffixes/0,
+
+ info/3,
+ fixtable/3,
+ validate_key/6, validate_record/6,
+
+ first/2, last/2, next/3, prev/3, slot/3,
+
+ insert/3, update_counter/4,
+ lookup/3,
+ delete/3, match_delete/3,
+ select/1, select/3, select/4, repair_continuation/2
+ ]).
+
+-ifdef(DEBUG).
+-define(DBG(DATA), io:format("~p:~p: ~p~n",[?MODULE, ?LINE, DATA])).
+-define(DBG(FORMAT, ARGS), io:format("~p:~p: " ++ FORMAT,[?MODULE, ?LINE] ++ ARGS)).
+-else.
+-define(DBG(DATA), ok).
+-define(DBG(FORMAT, ARGS), ok).
+-endif.
+
+%% types() ->
+%% [{fs_copies, ?MODULE},
+%% {raw_fs_copies, ?MODULE}].
+
+semantics(ext_ets, storage) -> ram_copies;
+semantics(ext_ets, types ) -> [set, ordered_set, bag];
+semantics(ext_ets, index_types) -> [ordered];
+semantics(_Alias, _) ->
+ undefined.
+
+%% valid_op(_, _) ->
+%% true.
+
+init_backend() ->
+ ?DBG(init_backend),
+ ok.
+
+add_aliases(_As) ->
+ ?DBG(_As),
+ ok.
+
+remove_aliases(_) ->
+ ok.
+
+
+%% Table operations
+
+check_definition(ext_ets, _Tab, _Nodes, _Props) ->
+ ?DBG("~p ~p ~p~n", [_Tab, _Nodes, _Props]),
+ ok.
+
+create_table(ext_ets, Tab, Props) when is_atom(Tab) ->
+ Tid = ets:new(Tab, [public, proplists:get_value(type, Props, set), {keypos, 2}]),
+ ?DBG("~p Create: ~p(~p) ~p~n", [self(), Tab, Tid, Props]),
+ mnesia_lib:set({?MODULE, Tab}, Tid),
+ ok;
+create_table(_, Tag={Tab, index, {_Where, Type0}}, _Opts) ->
+ Type = case Type0 of
+ ordered -> ordered_set;
+ _ -> Type0
+ end,
+ Tid = ets:new(Tab, [public, Type]),
+ ?DBG("~p(~p) ~p~n", [Tab, Tid, Tag]),
+ mnesia_lib:set({?MODULE, Tag}, Tid),
+ ok;
+create_table(_, Tag={_Tab, retainer, ChkPName}, _Opts) ->
+ Tid = ets:new(ChkPName, [set, public, {keypos, 2}]),
+ ?DBG("~p(~p) ~p~n", [_Tab, Tid, Tag]),
+ mnesia_lib:set({?MODULE, Tag}, Tid),
+ ok.
+
+delete_table(ext_ets, Tab) ->
+ try
+ ets:delete(mnesia_lib:val({?MODULE,Tab})),
+ mnesia_lib:unset({?MODULE,Tab}),
+ ok
+ catch _:_ ->
+ ?DBG({double_delete, Tab}),
+ ok
+ end.
+
+load_table(ext_ets, _Tab, init_index, _Cs) -> ok;
+load_table(ext_ets, _Tab, _LoadReason, _Cs) ->
+ ?DBG("Load ~p ~p~n", [_Tab, _LoadReason]),
+ ok.
+%% mnesia_monitor:unsafe_create_external(Tab, ext_ets, ?MODULE, Cs).
+
+sender_init(Alias, Tab, _RemoteStorage, _Pid) ->
+ KeysPerTransfer = 100,
+ {standard,
+ fun() -> mnesia_lib:db_init_chunk({ext,Alias,?MODULE}, Tab, KeysPerTransfer) end,
+ fun(Cont) -> mnesia_lib:db_chunk({ext,Alias,?MODULE}, Cont) end}.
+
+receiver_first_message(Sender, {first, Size}, _Alias, Tab) ->
+ ?DBG({first,Size}),
+ {Size, {Tab, Sender}}.
+
+receive_data(Data, ext_ets, Name, _Sender, {Name, Tab, _Sender}=State) ->
+ ?DBG({Data,State}),
+ true = ets:insert(Tab, Data),
+ {more, State};
+receive_data(Data, Alias, Tab, Sender, {Name, Sender}) ->
+ receive_data(Data, Alias, Tab, Sender, {Name, mnesia_lib:val({?MODULE,Tab}), Sender}).
+
+receive_done(_Alias, _Tab, _Sender, _State) ->
+ ?DBG({done,_State}),
+ ok.
+
+close_table(Alias, Tab) -> sync_close_table(Alias, Tab).
+
+sync_close_table(ext_ets, _Tab) ->
+ ?DBG(_Tab).
+
+fixtable(ext_ets, Tab, Bool) ->
+ ?DBG({Tab,Bool}),
+ ets:safe_fixtable(mnesia_lib:val({?MODULE,Tab}), Bool).
+
+info(ext_ets, Tab, Type) ->
+ ?DBG({Tab,Type}),
+ Tid = mnesia_lib:val({?MODULE,Tab}),
+ try ets:info(Tid, Type) of
+ Val -> Val
+ catch _:_ ->
+ undefined
+ end.
+
+real_suffixes() ->
+ [".dat"].
+
+tmp_suffixes() ->
+ [].
+
+%% Index
+
+index_is_consistent(_Alias, _Ix, _Bool) -> ok. % Ignore for now
+is_index_consistent(_Alias, _Ix) -> false. % Always rebuild
+
+%% Record operations
+
+validate_record(_Alias, _Tab, RecName, Arity, Type, _Obj) ->
+ {RecName, Arity, Type}.
+
+validate_key(_Alias, _Tab, RecName, Arity, Type, _Key) ->
+ {RecName, Arity, Type}.
+
+insert(ext_ets, Tab, Obj) ->
+ ?DBG({Tab,Obj}),
+ try
+ ets:insert(mnesia_lib:val({?MODULE,Tab}), Obj),
+ ok
+ catch _:Reason ->
+ io:format("CRASH ~p ~p~n",[Reason, mnesia_lib:val({?MODULE,Tab})])
+ end.
+
+lookup(ext_ets, Tab, Key) ->
+ ets:lookup(mnesia_lib:val({?MODULE,Tab}), Key).
+
+delete(ext_ets, Tab, Key) ->
+ ets:delete(mnesia_lib:val({?MODULE,Tab}), Key).
+
+match_delete(ext_ets, Tab, Pat) ->
+ ets:match_delete(mnesia_lib:val({?MODULE,Tab}), Pat).
+
+first(ext_ets, Tab) ->
+ ets:first(mnesia_lib:val({?MODULE,Tab})).
+
+last(Alias, Tab) -> first(Alias, Tab).
+
+next(ext_ets, Tab, Key) ->
+ ets:next(mnesia_lib:val({?MODULE,Tab}), Key).
+
+prev(Alias, Tab, Key) ->
+ next(Alias, Tab, Key).
+
+slot(ext_ets, Tab, Pos) ->
+ ets:slot(mnesia_lib:val({?MODULE,Tab}), Pos).
+
+update_counter(ext_ets, Tab, C, Val) ->
+ ets:update_counter(mnesia_lib:val({?MODULE,Tab}), C, Val).
+
+select('$end_of_table' = End) -> End;
+select({ext_ets, C}) -> ets:select(C).
+
+select(Alias, Tab, Ms) ->
+ Res = select(Alias, Tab, Ms, 100000),
+ select_1(Res).
+
+select_1('$end_of_table') -> [];
+select_1({Acc, C}) ->
+ case ets:select(C) of
+ '$end_of_table' -> Acc;
+ {New, Cont} ->
+ select_1({New ++ Acc, Cont})
+ end.
+
+select(ext_ets, Tab, Ms, Limit) when is_integer(Limit); Limit =:= infinity ->
+ ets:select(mnesia_lib:val({?MODULE,Tab}), Ms, Limit).
+
+repair_continuation({Alias, Cont}, Ms) ->
+ {Alias, ets:repair_continuation(Cont, Ms)}.
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
index 921ebb71e9..3ec4847c5d 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_atomicity_test.erl b/lib/mnesia/test/mnesia_atomicity_test.erl
index 06c4d16d71..cc32ba3826 100644
--- a/lib/mnesia/test/mnesia_atomicity_test.erl
+++ b/lib/mnesia/test/mnesia_atomicity_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -556,8 +557,8 @@ start_lock_waiter(BlockOpA, BlockOpB, Config) ->
?verify_mnesia([N1], [N2]).
mk_tab_name(Prefix) ->
- {Mega, Sec, Micro} = erlang:now(),
- list_to_atom(lists:concat([Prefix , Mega, '_', Sec, '_', Micro])).
+ Count = erlang:unique_integer([monotonic,positive]),
+ list_to_atom(lists:concat([Prefix , '_', Count])).
lock_waiter_fun(Op, TabName, Val) ->
case Op of
@@ -699,11 +700,19 @@ start_restart_check(RestartOp, ReplicaNeed, Config) ->
%% mnesia shall be killed at that node, where A is reading
%% the information from
- kill_where_to_read(TabName, N1, [N2, N3]),
+ Read = kill_where_to_read(TabName, N1, [N2, N3]),
%% wait some time to let mnesia go down and spread those news around
%% fun A shall be able to finish its job before being restarted
- wait(500),
+ Wait = fun(Loop) ->
+ wait(300),
+ sys:get_status(mnesia_monitor),
+ case lists:member(Read, mnesia_lib:val({current, db_nodes})) of
+ true -> Loop(Loop);
+ false -> ok
+ end
+ end,
+ Wait(Wait),
A ! go_ahead,
%% the sticky write doesnt work on remote nodes !!!
@@ -771,10 +780,12 @@ kill_where_to_read(TabName, N1, Nodes) ->
Read = rpc:call(N1,mnesia,table_info, [TabName, where_to_read]),
case lists:member(Read, Nodes) of
true ->
- mnesia_test_lib:kill_mnesia([Read]);
+ mnesia_test_lib:kill_mnesia([Read]),
+ Read;
false ->
?error("Fault while killing Mnesia: ~p~n", [Read]),
- mnesia_test_lib:kill_mnesia(Nodes)
+ mnesia_test_lib:kill_mnesia(Nodes),
+ Read
end.
sync_tid_release() ->
diff --git a/lib/mnesia/test/mnesia_bench_SUITE.erl b/lib/mnesia/test/mnesia_bench_SUITE.erl
index 7cbf77f046..7c86db383d 100644
--- a/lib/mnesia/test/mnesia_bench_SUITE.erl
+++ b/lib/mnesia/test/mnesia_bench_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_config_backup.erl b/lib/mnesia/test/mnesia_config_backup.erl
index 0916e255e2..239101ca92 100644
--- a/lib/mnesia/test/mnesia_config_backup.erl
+++ b/lib/mnesia/test/mnesia_config_backup.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -90,7 +91,8 @@ open_read(Name) ->
List = lists:reverse(ReverseList),
{ok, #backup{name = Name, mode = read, items = List}};
{error, Reason} ->
- {error, {open_read, Reason}}
+ %% {error, {open_read, Reason}}
+ {Reason, error} %% Testing error handling in mnesia
end.
read(Opaque) when Opaque#backup.mode == read ->
diff --git a/lib/mnesia/test/mnesia_config_event.erl b/lib/mnesia/test/mnesia_config_event.erl
index 832bf94eb9..4299b14f36 100644
--- a/lib/mnesia/test/mnesia_config_event.erl
+++ b/lib/mnesia/test/mnesia_config_event.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_config_test.erl b/lib/mnesia/test/mnesia_config_test.erl
index c495bce63f..45da909264 100644
--- a/lib/mnesia/test/mnesia_config_test.erl
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -37,7 +38,6 @@
dump_log_update_in_place/1,
event_module/1,
- ignore_fallback_at_startup/1,
inconsistent_database/1,
max_wait_for_decision/1,
send_compressed/1,
@@ -104,7 +104,7 @@ all() ->
[access_module, auto_repair, backup_module, debug, dir,
dump_log_load_regulation, {group, dump_log_thresholds},
dump_log_update_in_place,
- event_module, ignore_fallback_at_startup,
+ event_module,
inconsistent_database, max_wait_for_decision,
send_compressed, app_test, {group, schema_config},
unknown_config].
@@ -317,11 +317,17 @@ backup_module(Config) when is_list(Config) ->
?match([], mnesia_test_lib:start_mnesia(Nodes, [test_table, test_table2])),
%% Now check newly started tables
- ?match({atomic, [1,2]},
+ ?match({atomic, [1,2]},
mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table)) end)),
- ?match({atomic, [3,4]},
+ ?match({atomic, [3,4]},
mnesia:transaction(fun() -> lists:sort(mnesia:all_keys(test_table2)) end)),
-
+
+ %% Test some error cases
+ mnesia:set_debug_level(debug),
+ ?match({error, _}, mnesia:install_fallback("NonExisting.FILE")),
+ ?match({error, _}, mnesia:install_fallback(filename:join(mnesia_lib:dir(), "LATEST.LOG"))),
+
+ %% Cleanup
file:delete(File),
?verify_mnesia(Nodes, []),
?cleanup(1, Config),
@@ -609,13 +615,6 @@ dump_log_load_regulation(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ignore_fallback_at_startup(doc) ->
- ["Start Mnesia without rollback of the database to the fallback. ",
- "Once Mnesia has been (re)started the installed fallback should",
- "be handled as a normal active fallback.",
- "Install a customized event module which disables the termination",
- "of Mnesia when mnesia_down occurrs with an active fallback."].
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
max_wait_for_decision(doc) ->
@@ -694,9 +693,9 @@ event_module(Config) when is_list(Config) ->
end,
?match({[ok, ok], []}, rpc:multicall(Nodes, mnesia, start, [Def])),
- receive after 1000 -> ok end,
+ receive after 2000 -> ok end,
mnesia_event ! {get_log, self()},
- DebugLog1 = receive
+ DebugLog1 = receive
{log, L1} -> L1
after 10000 -> [timeout]
end,
@@ -707,9 +706,9 @@ event_module(Config) when is_list(Config) ->
?match({[ok], []}, rpc:multicall([N2], mnesia, start, [])),
- receive after 1000 -> ok end,
+ receive after 2000 -> ok end,
mnesia_event ! {get_log, self()},
- DebugLog = receive
+ DebugLog = receive
{log, L} -> L
after 10000 -> [timeout]
end,
@@ -1101,8 +1100,8 @@ dynamic_basic(Config) when is_list(Config) ->
?match(ok, mnesia:dirty_write({tab1, 1, 1})),
?match(ok, mnesia:dirty_write({tab2, 1, 1})),
-
- ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}]])),
+
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}, {schema, ?BACKEND}]])),
?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1,tab2],5000])),
io:format("Here ~p ~n",[?LINE]),
check_storage(N2, N1, [N3]),
@@ -1113,7 +1112,7 @@ dynamic_basic(Config) when is_list(Config) ->
?match(ok, mnesia:delete_schema([N3])),
io:format("T1 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
- ?match(ok, rpc:call(N3, mnesia, start, [])),
+ ?match(ok, rpc:call(N3, mnesia, start, [[{schema, ?BACKEND}]])),
io:format("T2 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
timer:sleep(2000),
io:format("T3 ~p ~n",[rpc:call(N3,?MODULE,c_nodes,[])]),
@@ -1128,7 +1127,7 @@ dynamic_basic(Config) when is_list(Config) ->
?match([], mnesia_test_lib:kill_mnesia([N3])),
?match(ok, mnesia:delete_schema([N3])),
- ?match(ok, rpc:call(N3, mnesia, start, [])),
+ ?match(ok, rpc:call(N3, mnesia, start, [[{schema, ?BACKEND}]])),
?match({ok, [N3]}, sort(?rpc_connect(N1, [N3]))),
?match(ok, rpc:call(N3, mnesia, wait_for_tables, [[tab1,tab2],5000])),
io:format("Here ~p ~n",[?LINE]),
@@ -1144,7 +1143,7 @@ dynamic_basic(Config) when is_list(Config) ->
% mnesia should come up now.
?match({atomic, ok}, mnesia:add_table_copy(tab1, N2, ram_copies)),
- ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema, ?BACKEND}]])),
?match({ok, _}, sort(?rpc_connect(N2, [N3]))),
?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
@@ -1163,7 +1162,7 @@ dynamic_basic(Config) when is_list(Config) ->
?match([N3,N1], sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
?match([N3,N1], sort(rpc:call(N3, mnesia, system_info, [running_db_nodes]))),
- ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema, ?BACKEND}]])),
?match({ok, _}, sort(?rpc_connect(N3, [N2]))),
?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
@@ -1193,7 +1192,7 @@ dynamic_ext(Config) when is_list(Config) ->
mnesia_test_lib:kill_mnesia([N2]),
?match(ok, mnesia:delete_schema([N2])),
- ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}]])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes, [N1]}, {schema, ?BACKEND}]])),
?match(SNs, sort(rpc:call(N1, mnesia, system_info, [running_db_nodes]))),
?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
@@ -1207,14 +1206,14 @@ dynamic_ext(Config) when is_list(Config) ->
end,
[Check(Test) || Test <- [{tab1, ram_copies},{tab2, disc_copies},{tab3, disc_only_copies}]],
- T = now(),
+ T = erlang:unique_integer(),
?match(ok, mnesia:dirty_write({tab0, 42, T})),
?match(ok, mnesia:dirty_write({tab1, 42, T})),
?match(ok, mnesia:dirty_write({tab2, 42, T})),
?match(ok, mnesia:dirty_write({tab3, 42, T})),
?match(stopped, rpc:call(N2, mnesia, stop, [])),
- ?match(ok, rpc:call(N2, mnesia, start, [])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{schema, ?BACKEND}]])),
?match(SNs, sort(rpc:call(N2, mnesia, system_info, [running_db_nodes]))),
?match(ok, mnesia:wait_for_tables([tab0,tab1,tab2,tab3], 10000)),
?match(ok, rpc:call(N2, mnesia, wait_for_tables, [[tab1,tab2,tab3], 100])),
@@ -1227,7 +1226,7 @@ dynamic_ext(Config) when is_list(Config) ->
?match(stopped, rpc:call(N1, mnesia, stop, [])),
- ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1,N2]}]])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1,N2]}, {schema, ?BACKEND}]])),
?match({timeout,[tab0]}, rpc:call(N2, mnesia, wait_for_tables, [[tab0], 500])),
?match(ok, rpc:call(N1, mnesia, start, [[{extra_db_nodes, [N1,N2]}]])),
@@ -1239,7 +1238,7 @@ dynamic_ext(Config) when is_list(Config) ->
?match(stopped, rpc:call(N1, mnesia, stop, [])),
mnesia_test_lib:kill_mnesia([N2]),
?match(ok, mnesia:delete_schema([N2])),
- ?match(ok, rpc:call(N1, mnesia, start, [[{extra_db_nodes, [N1,N2]}]])),
+ ?match(ok, rpc:call(N1, mnesia, start, [[{extra_db_nodes, [N1,N2]}, {schema, ?BACKEND}]])),
?match({timeout,[tab0]}, rpc:call(N1, mnesia, wait_for_tables, [[tab0], 500])),
?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1,N2]}]])),
@@ -1285,7 +1284,7 @@ check_storage(Me, Orig, Other) ->
mnesia_test_lib:kill_mnesia([Orig]),
mnesia_test_lib:kill_mnesia(Other),
- T = now(),
+ T = erlang:unique_integer(),
?match(ok, rpc:call(Me, mnesia, dirty_write, [{tab2, 42, T}])),
?match(stopped, rpc:call(Me, mnesia, stop, [])),
?match(ok, rpc:call(Me, mnesia, start, [])),
diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl
index a76a0116d5..2fe1bd34e6 100644
--- a/lib/mnesia/test/mnesia_consistency_test.erl
+++ b/lib/mnesia/test/mnesia_consistency_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -564,6 +565,7 @@ consistency_after_fallback_3_disc_only(Config) when is_list(Config) ->
consistency_after_fallback(disc_only_copies, 3, Config).
consistency_after_fallback(ReplicaType, NodeConfig, Config) ->
+ put(mnesia_test_verbose, true),
%%?verbose("Starting consistency_after_fallback2 at ~p~n", [self()]),
Delay = 5,
Nodes = ?acquire_nodes(NodeConfig, [{tc_timeout, timer:minutes(10)} | Config]),
@@ -593,10 +595,11 @@ consistency_after_fallback(ReplicaType, NodeConfig, Config) ->
?match(ok, mnesia_tpcb:verify_tabs()),
%% Stop and then start mnesia and check table consistency
- %%?verbose("Restarting Mnesia~n", []),
+ ?verbose("Kill Mnesia~n", []),
mnesia_test_lib:kill_mnesia(Nodes),
+ ?verbose("Start Mnesia~n", []),
mnesia_test_lib:start_mnesia(Nodes,[account,branch,teller,history]),
-
+ ?verbose("Verify tabs~n", []),
?match(ok, mnesia_tpcb:verify_tabs()),
if
ReplicaType == ram_copies ->
@@ -662,10 +665,10 @@ consistency_after_restore(ReplicaType, Op, Config) ->
[lists:foreach(fun(E) -> ok = mnesia:dirty_write({Tab, E, 2}) end, NList) ||
Tab <- Tabs],
- Pids1 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carA, Op]), ok} || _ <- lists:seq(1, 5)],
- Pids2 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carB, Op]), ok} || _ <- lists:seq(1, 5)],
- Pids3 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carC, Op]), ok} || _ <- lists:seq(1, 5)],
- Pids4 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carD, Op]), ok} || _ <- lists:seq(1, 5)],
+ Pids1 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carA, Op]), carA} || _ <- lists:seq(1, 5)],
+ Pids2 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carB, Op]), carB} || _ <- lists:seq(1, 5)],
+ Pids3 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carC, Op]), carC} || _ <- lists:seq(1, 5)],
+ Pids4 = [{'EXIT', spawn_link(?MODULE, change_tab, [self(), carD, Op]), carD} || _ <- lists:seq(1, 5)],
AllPids = Pids1 ++ Pids2 ++ Pids3 ++ Pids4,
@@ -675,19 +678,38 @@ consistency_after_restore(ReplicaType, Op, Config) ->
Else -> Else
end
end,
-
+
timer:sleep(timer:seconds(Delay)), %% Let changers grab locks
?verbose("Doing restore~n", []),
?match(Tabs, Restore(File, [{default_op, Op}])),
- timer:sleep(timer:seconds(Delay)), %% Let em die
+ Collect = fun(Msg, Acc) ->
+ receive Msg -> Acc
+ after 10000 -> [Msg|Acc]
+ end
+ end,
- ?match_multi_receive(AllPids),
+ Failed1 = lists:foldl(Collect, [], AllPids),
+ Failed = lists:foldl(Collect, [], Failed1),
+
+ case Failed of
+ [] -> ok;
+ _ ->
+ ?match([], Failed),
+ io:format("TIME: ~p sec~n", [erlang:system_time(seconds) band 16#FF]),
+ Dbg = fun({_, Pid, Tab}) ->
+ io:format("Tab ~p: ~p~n",[Tab, process_info(Pid, current_stacktrace)]),
+ [io:format(" ~p~n", [Rec]) || Rec <- mnesia:dirty_match_object({Tab, '_', '_'})]
+ end,
+ [Dbg(Msg) || Msg <- Failed],
+ io:format(" Held: ~p~n", [mnesia_locker:get_held_locks()]),
+ io:format("Queue: ~p~n", [mnesia_locker:get_lock_queue()])
+ end,
- case ?match(ok, restore_verify_tabs(Tabs)) of
- {success, ok} ->
+ case ?match(ok, restore_verify_tabs(Tabs)) of
+ {success, ok} ->
file:delete(File);
- _ ->
+ _ ->
{T, M, S} = time(),
File2 = ?flat_format("consistency_error~w~w~w.BUP", [T, M, S]),
file:rename(File, File2)
@@ -695,19 +717,22 @@ consistency_after_restore(ReplicaType, Op, Config) ->
?verify_mnesia(Nodes, []).
change_tab(Father, Tab, Test) ->
- Key = random:uniform(20),
+ Key = rand:uniform(20),
Update = fun() ->
+ Time = erlang:system_time(seconds) band 16#FF,
+ case put(time, Time) of
+ Time -> ok;
+ _ -> io:format("~p ~p ~p sec~n", [self(), Tab, Time])
+ end,
case mnesia:read({Tab, Key}) of
- [{Tab, Key, 1}] ->
- quit;
- [{Tab, Key, _N}] ->
- mnesia:write({Tab, Key, 3})
+ [{Tab, Key, 1}] -> quit;
+ [{Tab, Key, _N}] -> mnesia:write({Tab, Key, 3})
end
end,
case mnesia:transaction(Update) of
{atomic, quit} ->
- exit(ok);
- {aborted, {no_exists, Tab}} when Test == recreate_tables ->%% I'll allow this
+ exit(Tab);
+ {aborted, {no_exists, Tab}} when Test == recreate_tables -> %% I'll allow this
change_tab(Father, Tab, Test);
{atomic, ok} ->
change_tab(Father, Tab, Test)
diff --git a/lib/mnesia/test/mnesia_cost.erl b/lib/mnesia/test/mnesia_cost.erl
index 3221f46f61..a3fc8dfe20 100644
--- a/lib/mnesia/test/mnesia_cost.erl
+++ b/lib/mnesia/test/mnesia_cost.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -107,11 +108,11 @@ run(What, OtherInfo, Ops, F) ->
run(t, What, OtherInfo, Ops, F).
run(How, What, OtherInfo, Ops, F) ->
- T1 = erlang:now(),
+ T1 = erlang:monotonic_time(),
statistics(runtime),
do_times(How, ?TIMES, F),
{_, RunTime} = statistics(runtime),
- T2 = erlang:now(),
+ T2 = erlang:monotonic_time(),
RealTime = subtr(T1, T2),
report(How, What, OtherInfo, Ops, RunTime, RealTime).
@@ -139,11 +140,7 @@ report(dirty, What, OtherInfo, Ops, RunTime, RealTime) ->
subtr(Before, After) ->
- E =(element(1,After)*1000000000000
- +element(2,After)*1000000+element(3,After)) -
- (element(1,Before)*1000000000000
- +element(2,Before)*1000000+element(3,Before)),
- E div 1000.
+ erlang:convert_time_unit(After-Before, native, milli_seconds).
do_times(t, I, F) ->
do_trans_times(I, F);
diff --git a/lib/mnesia/test/mnesia_dbn_meters.erl b/lib/mnesia/test/mnesia_dbn_meters.erl
index feaf90ee75..407d7c65b8 100644
--- a/lib/mnesia/test/mnesia_dbn_meters.erl
+++ b/lib/mnesia/test/mnesia_dbn_meters.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -92,7 +93,7 @@ some_meters() ->
report_meter(Meter) ->
Times = 100,
Micros = repeat_meter(Meter,{atomic,{0,ignore}},Times) div Times,
- io:format("\t~-30w ~-10w micro seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]).
+ io:format("\t~-30w ~-10w nano seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]).
repeat_meter(_Meter,{atomic,{Micros,_Result}},0) ->
Micros;
@@ -109,9 +110,9 @@ meter(create) ->
Key = 1,
mnesia:transaction(fun() -> mnesia:delete({simple,Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:write(#simple{key=Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -120,9 +121,9 @@ meter(open_safe_read) ->
Key = 2,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:read({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -131,9 +132,9 @@ meter(open_dirty_read) ->
Key = 21,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:dirty_read({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -143,9 +144,9 @@ meter(get_int) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:read({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Int = Simple#simple.val,
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,Int)
end,
mnesia:transaction(Fun);
@@ -154,9 +155,9 @@ meter(open_update) ->
Key = 3,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:wread({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -166,9 +167,9 @@ meter(put_int) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:wread({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = Simple#simple{val=7},
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -178,10 +179,10 @@ meter(put_int_and_copy) ->
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
[Simple] = mnesia:wread({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Simple2 = Simple#simple{val=17},
R = mnesia:write(Simple2),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -190,15 +191,15 @@ meter(dirty_put_int_and_copy) ->
Key = 55,
mnesia:dirty_write(#simple{key=Key}),
[Simple] = mnesia:dirty_read({simple,Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
Simple2 = Simple#simple{val=17},
R = mnesia:dirty_write(Simple2),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic,elapsed_time(BeforeT,AfterT,R)};
meter(start_trans) ->
- BeforeT = erlang:now(),
- {atomic,AfterT} = mnesia:transaction(fun() -> erlang:now() end),
+ BeforeT = erlang:monotonic_time(),
+ {atomic,AfterT} = mnesia:transaction(fun() -> erlang:monotonic_time() end),
{atomic,elapsed_time(BeforeT,AfterT,ok)};
meter(commit_one_update) ->
@@ -208,19 +209,19 @@ meter(commit_one_update) ->
[Simple] = mnesia:wread({simple,Key}),
Simple2 = Simple#simple{val=27},
_R = mnesia:write(Simple2),
- erlang:now()
+ erlang:monotonic_time()
end,
{atomic,BeforeT} = mnesia:transaction(Fun),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic,elapsed_time(BeforeT,AfterT,ok)};
meter(delete) ->
Key = 7,
mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end),
Fun = fun() ->
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:delete({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
elapsed_time(BeforeT,AfterT,R)
end,
mnesia:transaction(Fun);
@@ -228,15 +229,12 @@ meter(delete) ->
meter(dirty_delete) ->
Key = 75,
mnesia:dirty_write(#simple{key=Key}),
- BeforeT = erlang:now(),
+ BeforeT = erlang:monotonic_time(),
R = mnesia:dirty_delete({simple,Key}),
- AfterT = erlang:now(),
+ AfterT = erlang:monotonic_time(),
{atomic, elapsed_time(BeforeT,AfterT,R)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Calculate the elapsed time
elapsed_time(BeforeT,AfterT,Result) ->
- {(element(1,AfterT)*1000000000000
- +element(2,AfterT)*1000000+element(3,AfterT)) -
- (element(1,BeforeT)*1000000000000
- +element(2,BeforeT)*1000000+element(3,BeforeT)),Result}.
+ {erlang:convert_time_unit(AfterT-BeforeT, native, nano_seconds),Result}.
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
index 519b4bb052..6d970ac990 100644
--- a/lib/mnesia/test/mnesia_dirty_access_test.erl
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -39,43 +40,40 @@ all() ->
groups() ->
[{dirty_write, [],
- [dirty_write_ram, dirty_write_disc,
- dirty_write_disc_only]},
+ [dirty_write_ram, dirty_write_disc, dirty_write_disc_only,
+ dirty_write_xets]},
{dirty_read, [],
- [dirty_read_ram, dirty_read_disc,
- dirty_read_disc_only]},
+ [dirty_read_ram, dirty_read_disc, dirty_read_disc_only, dirty_read_xets]},
{dirty_update_counter, [],
[dirty_update_counter_ram, dirty_update_counter_disc,
- dirty_update_counter_disc_only]},
+ dirty_update_counter_disc_only, dirty_update_counter_xets]},
{dirty_delete, [],
[dirty_delete_ram, dirty_delete_disc,
- dirty_delete_disc_only]},
+ dirty_delete_disc_only, dirty_delete_xets]},
{dirty_delete_object, [],
[dirty_delete_object_ram, dirty_delete_object_disc,
- dirty_delete_object_disc_only]},
+ dirty_delete_object_disc_only, dirty_delete_object_xets]},
{dirty_match_object, [],
[dirty_match_object_ram, dirty_match_object_disc,
- dirty_match_object_disc_only]},
+ dirty_match_object_disc_only, dirty_match_object_xets]},
{dirty_index, [],
[{group, dirty_index_match_object},
{group, dirty_index_read},
{group, dirty_index_update}]},
{dirty_index_match_object, [],
- [dirty_index_match_object_ram,
- dirty_index_match_object_disc,
- dirty_index_match_object_disc_only]},
+ [dirty_index_match_object_ram, dirty_index_match_object_disc,
+ dirty_index_match_object_disc_only, dirty_index_match_object_xets]},
{dirty_index_read, [],
[dirty_index_read_ram, dirty_index_read_disc,
- dirty_index_read_disc_only]},
+ dirty_index_read_disc_only, dirty_index_read_xets]},
{dirty_index_update, [],
- [dirty_index_update_set_ram,
- dirty_index_update_set_disc,
- dirty_index_update_set_disc_only,
+ [dirty_index_update_set_ram, dirty_index_update_set_disc,
+ dirty_index_update_set_disc_only, dirty_index_update_set_xets,
dirty_index_update_bag_ram, dirty_index_update_bag_disc,
- dirty_index_update_bag_disc_only]},
+ dirty_index_update_bag_disc_only, dirty_index_update_bag_xets]},
{dirty_iter, [],
- [dirty_iter_ram, dirty_iter_disc,
- dirty_iter_disc_only]},
+ [dirty_iter_ram, dirty_iter_disc, dirty_iter_disc_only,
+ dirty_iter_xets]},
{admin_tests, [],
[del_table_copy_1, del_table_copy_2, del_table_copy_3,
add_table_copy_1, add_table_copy_2, add_table_copy_3,
@@ -105,6 +103,9 @@ dirty_write_disc_only(suite) -> [];
dirty_write_disc_only(Config) when is_list(Config) ->
dirty_write(Config, disc_only_copies).
+dirty_write_xets(Config) when is_list(Config) ->
+ dirty_write(Config, ext_ets).
+
dirty_write(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_write,
@@ -136,6 +137,9 @@ dirty_read_disc_only(suite) -> [];
dirty_read_disc_only(Config) when is_list(Config) ->
dirty_read(Config, disc_only_copies).
+dirty_read_xets(Config) when is_list(Config) ->
+ dirty_read(Config, ext_ets).
+
dirty_read(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_read,
@@ -179,6 +183,9 @@ dirty_update_counter_disc_only(suite) -> [];
dirty_update_counter_disc_only(Config) when is_list(Config) ->
dirty_update_counter(Config, disc_only_copies).
+dirty_update_counter_xets(Config) when is_list(Config) ->
+ dirty_update_counter(Config, ext_ets).
+
dirty_update_counter(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_update_counter,
@@ -221,6 +228,9 @@ dirty_delete_disc_only(suite) -> [];
dirty_delete_disc_only(Config) when is_list(Config) ->
dirty_delete(Config, disc_only_copies).
+dirty_delete_xets(Config) when is_list(Config) ->
+ dirty_delete(Config, ext_ets).
+
dirty_delete(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_delete,
@@ -258,6 +268,9 @@ dirty_delete_object_disc_only(suite) -> [];
dirty_delete_object_disc_only(Config) when is_list(Config) ->
dirty_delete_object(Config, disc_only_copies).
+dirty_delete_object_xets(Config) when is_list(Config) ->
+ dirty_delete_object(Config, ext_ets).
+
dirty_delete_object(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_delete_object,
@@ -301,6 +314,9 @@ dirty_match_object_disc_only(suite) -> [];
dirty_match_object_disc_only(Config) when is_list(Config) ->
dirty_match_object(Config, disc_only_copies).
+dirty_match_object_xets(Config) when is_list(Config) ->
+ dirty_match_object(Config, ext_ets).
+
dirty_match_object(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_match,
@@ -325,7 +341,6 @@ dirty_match_object(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty read matching records by using an index
-
dirty_index_match_object_ram(suite) -> [];
dirty_index_match_object_ram(Config) when is_list(Config) ->
dirty_index_match_object(Config, ram_copies).
@@ -338,6 +353,9 @@ dirty_index_match_object_disc_only(suite) -> [];
dirty_index_match_object_disc_only(Config) when is_list(Config) ->
dirty_index_match_object(Config, disc_only_copies).
+dirty_index_match_object_xets(Config) when is_list(Config) ->
+ dirty_index_match_object(Config, ext_ets).
+
dirty_index_match_object(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_index_match_object,
@@ -375,6 +393,9 @@ dirty_index_read_disc_only(suite) -> [];
dirty_index_read_disc_only(Config) when is_list(Config) ->
dirty_index_read(Config, disc_only_copies).
+dirty_index_read_xets(Config) when is_list(Config) ->
+ dirty_index_read(Config, ext_ets).
+
dirty_index_read(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_index_read,
@@ -400,9 +421,26 @@ dirty_index_read(Config, Storage) ->
?match({'EXIT', _}, mnesia:dirty_index_read(Tab, 2, BadValPos)),
?match({'EXIT', _}, mnesia:dirty_index_read(foo, 2, ValPos)),
?match({'EXIT', _}, mnesia:dirty_index_read([], 2, ValPos)),
-
+
+ mnesia:dirty_write({Tab, 5, 1}),
+ ?match(ok, index_read_loop(Tab, 0)),
+
?verify_mnesia(Nodes, []).
+
+index_read_loop(Tab, N) when N =< 1000 ->
+ spawn_link(fun() ->
+ mnesia:transaction(fun() -> mnesia:write({Tab, 5, 1}) end)
+ end),
+ case mnesia:dirty_match_object({Tab, '_', 1}) of
+ [{Tab, 5, 1}] ->
+ index_read_loop(Tab, N+1);
+ Other -> {N, Other}
+ end;
+index_read_loop(_, _) ->
+ ok.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -419,78 +457,85 @@ dirty_index_update_set_disc_only(suite) -> [];
dirty_index_update_set_disc_only(Config) when is_list(Config) ->
dirty_index_update_set(Config, disc_only_copies).
+dirty_index_update_set_xets(Config) when is_list(Config) ->
+ dirty_index_update_set(Config, ext_ets).
+
dirty_index_update_set(Config, Storage) ->
- [Node1] = Nodes = ?acquire_nodes(1, Config),
- Tab = index_test,
- ValPos = v1,
+ [Node1] = Nodes = ?acquire_nodes(1, Config),
+ Tab = index_test,
+ ValPos = v1,
ValPos2 = v3,
Def = [{attributes, [k, v1, v2, v3]},
{Storage, [Node1]},
- {index, [ValPos]}],
- ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
-
+ {index, [ValPos]}],
+ ?match({atomic, ok}, mnesia:create_table(Tab, Def)),
+
Pat1 = {Tab, '$1', 2, '$2', '$3'},
- Pat2 = {Tab, '$1', '$2', '$3', '$4'},
-
- Rec1 = {Tab, 1, 2, 3, 4},
+ Pat2 = {Tab, '$1', '$2', '$3', '$4'},
+ Pat3 = {Tab, '_', '_', '_', {4, 14}},
+
+ Rec1 = {Tab, 1, 2, 3, {4, 14}},
Rec2 = {Tab, 2, 2, 13, 14},
- Rec3 = {Tab, 1, 12, 13, 14},
- Rec4 = {Tab, 4, 2, 13, 14},
-
+ Rec3 = {Tab, 1, 12, 13, 14},
+ Rec4 = {Tab, 4, 2, 13, 14},
+
?match([], mnesia:dirty_index_read(Tab, 2, ValPos)),
?match(ok, mnesia:dirty_write(Rec1)),
?match([Rec1], mnesia:dirty_index_read(Tab, 2, ValPos)),
-
+
?match(ok, mnesia:dirty_write(Rec2)),
R1 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec1, Rec2], lists:sort(R1)),
-
+
?match(ok, mnesia:dirty_write(Rec3)),
R2 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec2], lists:sort(R2)),
?match([Rec2], mnesia:dirty_index_match_object(Pat1, ValPos)),
-
- {atomic, R3} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
+
+ {atomic, R3} = mnesia:transaction(fun() -> mnesia:match_object(Pat2) end),
?match([Rec3, Rec2], lists:sort(R3)),
-
+
?match(ok, mnesia:dirty_write(Rec4)),
R4 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec2, Rec4], lists:sort(R4)),
-
+
?match(ok, mnesia:dirty_delete({Tab, 4})),
?match([Rec2], mnesia:dirty_index_read(Tab, 2, ValPos)),
-
+
?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec4) end)),
?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos2)),
-
+
R5 = mnesia:dirty_match_object(Pat2),
?match([Rec3, Rec2, Rec4], lists:sort(R5)),
-
+
R6 = mnesia:dirty_index_read(Tab, 2, ValPos),
- ?match([Rec2, Rec4], lists:sort(R6)),
- ?match([], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([Rec2, Rec4], lists:sort(R6)),
+ ?match([], mnesia:dirty_index_read(Tab, {4,14}, ValPos2)),
R7 = mnesia:dirty_index_read(Tab, 14, ValPos2),
?match([Rec3, Rec2, Rec4], lists:sort(R7)),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec1) end)),
R8 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec1, Rec2, Rec4], lists:sort(R8)),
- ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, {4,14}, ValPos2)),
+ ?match([Rec1], mnesia:dirty_match_object(Pat3)),
+ ?match([Rec1], mnesia:dirty_index_match_object(Pat3, ValPos2)),
+
R9 = mnesia:dirty_index_read(Tab, 14, ValPos2),
?match([Rec2, Rec4], lists:sort(R9)),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec2) end)),
R10 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec1, Rec4], lists:sort(R10)),
- ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, {4,14}, ValPos2)),
?match([Rec4], mnesia:dirty_index_read(Tab, 14, ValPos2)),
?match(ok, mnesia:dirty_delete({Tab, 4})),
R11 = mnesia:dirty_index_read(Tab, 2, ValPos),
?match([Rec1], lists:sort(R11)),
- ?match([Rec1], mnesia:dirty_index_read(Tab, 4, ValPos2)),
+ ?match([Rec1], mnesia:dirty_index_read(Tab, {4,14}, ValPos2)),
?match([], mnesia:dirty_index_read(Tab, 14, ValPos2)),
?verify_mnesia(Nodes, []).
@@ -507,6 +552,9 @@ dirty_index_update_bag_disc_only(suite) -> [];
dirty_index_update_bag_disc_only(Config)when is_list(Config) ->
dirty_index_update_bag(Config, disc_only_copies).
+dirty_index_update_bag_xets(Config) when is_list(Config) ->
+ dirty_index_update_bag(Config, ext_ets).
+
dirty_index_update_bag(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = index_test,
@@ -613,7 +661,6 @@ dirty_index_update_bag(Config, Storage) ->
%% Dirty iteration
%% dirty_slot, dirty_first, dirty_next
-
dirty_iter_ram(suite) -> [];
dirty_iter_ram(Config) when is_list(Config) ->
dirty_iter(Config, ram_copies).
@@ -626,6 +673,9 @@ dirty_iter_disc_only(suite) -> [];
dirty_iter_disc_only(Config) when is_list(Config) ->
dirty_iter(Config, disc_only_copies).
+dirty_iter_xets(Config) when is_list(Config) ->
+ dirty_iter(Config, ext_ets).
+
dirty_iter(Config, Storage) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
Tab = dirty_iter,
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
index 366fda7044..97bc84a2d8 100644
--- a/lib/mnesia/test/mnesia_durability_test.erl
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
index 9e0a8db1ae..e745ec9b04 100644
--- a/lib/mnesia/test/mnesia_evil_backup.erl
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -142,6 +143,9 @@ restore_errors(Config) when is_list(Config) ->
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{skip_tables, xxx}])),
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{recreate_tables, [schema]}])),
?match({aborted, {badarg, _}}, mnesia:restore(notAfile, [{default_op, asdklasd}])),
+ MnesiaDir = mnesia_lib:dir(),
+ ?match({aborted, {not_a_log_file, _}}, mnesia:restore(filename:join(MnesiaDir, "schema.DAT"), [])),
+ ?match({aborted, _}, mnesia:restore(filename:join(MnesiaDir, "LATEST.LOG"), [])),
ok.
restore_clear(suite) -> [];
@@ -225,10 +229,16 @@ restore(Config, Op) ->
[mnesia:dirty_write({Tab1, N, N+1}) || N <- lists:seq(1, 11)],
[mnesia:dirty_write({Tab2, N, N+1}) || N <- lists:seq(1, 11)],
[mnesia:dirty_write({Tab3, N, N+1}) || N <- lists:seq(1, 11)],
- _Res11 = [{Tab1, N, N+1} || N <- lists:seq(1, 11)],
+
Res21 = [{Tab2, N, N+1} || N <- lists:seq(1, 11)],
Res31 = [[{Tab3, N, N+1}, {Tab3, N, N+44}] || N <- lists:seq(1, 10)],
-
+ Check = fun() ->
+ [disk_log:pid2name(X) ||
+ X <- processes(), Data <- [process_info(X, [current_function])],
+ Data =/= undefined,
+ element(1, element(2, lists:keyfind(current_function, 1, Data)))=:= disk_log]
+ end,
+ Before = Check(),
?match({atomic, [Tab1]}, Restore(File1, [{Op, [Tab1]},
{skip_tables, Tabs -- [Tab1]}])),
case Op of
@@ -315,6 +325,8 @@ restore(Config, Op) ->
end,
?match(ok, file:delete(File1)),
?match(ok, file:delete(File2)),
+ ?match([], Check() -- (Before ++ [{ok, latest_log}, {ok, previous_log}])),
+
?verify_mnesia(Nodes, []).
@@ -488,6 +500,14 @@ install_fallback(Config) when is_list(Config) ->
mnesia_test_lib:kill_mnesia([Node1, Node2]),
timer:sleep(timer:seconds(1)), % Let it die!
+ ok = mnesia:start([{ignore_fallback_at_startup, true}]),
+ ok = mnesia:wait_for_tables([Tab, Tab2, Tab3], 10000),
+ ?match([{Tab, 6, test_nok}], mnesia:dirty_read({Tab, 6})),
+ mnesia_test_lib:kill_mnesia([Node1]),
+ application:set_env(mnesia, ignore_fallback_at_startup, false),
+
+ timer:sleep(timer:seconds(1)), % Let it die!
+
?match([], mnesia_test_lib:start_mnesia([Node1, Node2], [Tab, Tab2, Tab3])),
% Verify
@@ -510,6 +530,13 @@ install_fallback(Config) when is_list(Config) ->
file:delete(File3),
?match({error, _}, mnesia:install_fallback(File3)),
?match({error, _}, mnesia:install_fallback(File2, mnesia_badmod)),
+ ?match({error, _}, mnesia:install_fallback(File2, {foo, foo})),
+ ?match({error, _}, mnesia:install_fallback(File2, [{foo, foo}])),
+ ?match({error, {badarg, {skip_tables, _}}},
+ mnesia:install_fallback(File2, [{default_op, skip_tables},
+ {default_op, keep_tables},
+ {keep_tables, [Tab, Tab2, Tab3]},
+ {skip_tables, [foo,{asd}]}])),
?match(ok, mnesia:install_fallback(File2, mnesia_backup)),
?match(ok, file:delete(File)),
?match(ok, file:delete(File2)),
@@ -535,6 +562,7 @@ uninstall_fallback(Config) when is_list(Config) ->
?match(ok, mnesia:install_fallback(File2)),
?match(ok, file:delete(File)),
?match(ok, file:delete(File2)),
+ ?match({error, _}, mnesia:uninstall_fallback([foobar])),
?match(ok, mnesia:uninstall_fallback()),
mnesia_test_lib:kill_mnesia([Node1, Node2]),
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
index 2d1623b6ca..6e34040bc4 100644
--- a/lib/mnesia/test/mnesia_evil_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -71,7 +72,9 @@ groups() ->
{record_name_dirty_access, [],
[record_name_dirty_access_ram,
record_name_dirty_access_disc,
- record_name_dirty_access_disc_only]}].
+ record_name_dirty_access_disc_only,
+ record_name_dirty_access_xets
+ ]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -111,6 +114,7 @@ system_info(Config) when is_list(Config) ->
?match(I when is_integer(I), mnesia:system_info(transaction_log_writes)),
?match(I when is_integer(I), mnesia:system_info(send_compressed)),
?match(L when is_list(L), mnesia:system_info(all)),
+ ?match(L when is_list(L), mnesia:system_info(backend_types)),
?match({'EXIT', {aborted, Reason }} when element(1, Reason) == badarg
, mnesia:system_info(ali_baba)),
?verify_mnesia(Nodes, []).
@@ -131,11 +135,11 @@ table_info(Config) when is_list(Config) ->
Schema =
case mnesia_test_lib:diskless(Config) of
true -> [{type, Type}, {attributes, Attrs}, {index, [ValPos]},
- {ram_copies, Nodes}];
+ {ram_copies, [Node1, Node2]}, {ext_ets, [Node3]}];
false ->
[{type, Type}, {attributes, Attrs}, {index, [ValPos]},
- {disc_only_copies, [Node1]}, {ram_copies, [Node2]},
- {disc_copies, [Node3]}]
+ {disc_only_copies, [Node1]}, {ram_copies, [Node2]},
+ {ext_ets, [Node3]}]
end,
?match({atomic, ok}, mnesia:create_table(Tab, Schema)),
@@ -143,28 +147,22 @@ table_info(Config) when is_list(Config) ->
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 is_integer(Mem), mnesia:table_info(Tab, memory)),
- ?match(Size, mnesia:table_info(Tab, size)),
- ?match(Type, mnesia:table_info(Tab, type)),
case mnesia_test_lib:diskless(Config) of
true ->
?match(Nodes, mnesia:table_info(Tab, ram_copies));
false ->
- ?match([Node3], mnesia:table_info(Tab, mnesia_test_lib:storage_type(disc_copies, Config))),
+ ?match([Node3], mnesia:table_info(Tab, ext_ets)),
?match([Node2], mnesia:table_info(Tab, ram_copies)),
?match([Node1], mnesia:table_info(Tab, mnesia_test_lib:storage_type(disc_only_copies, Config)))
end,
Read = [Node1, Node2, Node3],
- ?match(true, lists:member(mnesia:table_info(Tab, where_to_read), Read)),
Write = ?sort([Node1, Node2, Node3]),
- ?match(Write, ?sort(mnesia:table_info(Tab, where_to_write))),
- ?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)),
+
+ {[ok,ok,ok], []} = rpc:multicall(Nodes, ?MODULE, info_check,
+ [Tab, Read, Write, Size, Type, ValPos, Arity, Attrs]),
+
+ ?match({atomic, Attrs}, mnesia:transaction(fun() -> mnesia:table_info(Tab, attributes) end)),
?match(L when is_list(L), mnesia:table_info(Tab, all)),
@@ -178,6 +176,17 @@ table_info(Config) when is_list(Config) ->
?match(0, mnesia:table_info(tab_info, size)),
?verify_mnesia([Node1, Node3], [Node2]).
+info_check(Tab, Read, Write, Size, Type, ValPos, Arity, Attrs) ->
+ ?match(true, lists:member(mnesia:table_info(Tab, where_to_read), Read)),
+ ?match(Write, ?sort(mnesia:table_info(Tab, where_to_write))),
+ ?match(Mem when is_integer(Mem), mnesia:table_info(Tab, memory)),
+ ?match(Size, mnesia:table_info(Tab, size)),
+ ?match(Type, mnesia:table_info(Tab, type)),
+ ?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)),
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Check the error descriptions
@@ -215,11 +224,12 @@ db_node_lifecycle(Config) when is_list(Config) ->
[Node1, Node2, Node3] = AllNodes = ?acquire_nodes(3, Config),
Tab = db_node_lifecycle,
- Who = fun(T) ->
+ Who = fun(T) ->
L1 = mnesia:table_info(T, ram_copies),
L2 = mnesia:table_info(T, disc_copies),
L3 = mnesia:table_info(T, disc_only_copies),
- L1 ++ L2 ++ L3
+ L4 = mnesia:table_info(T, ext_ets),
+ L1 ++ L2 ++ L3 ++ L4
end,
SNs = ?sort(AllNodes),
@@ -234,6 +244,7 @@ db_node_lifecycle(Config) when is_list(Config) ->
?match({error, _}, mnesia:create_schema([foo@bar])),
?match(ok, mnesia:start()),
?match(false, mnesia:system_info(use_dir)),
+ ?match([ram_copies, disc_copies, disc_only_copies], mnesia:system_info(backend_types)),
?match({atomic, ok}, mnesia:create_table(Tab, [])),
?match({aborted, {has_no_disc, Node1}}, mnesia:dump_tables([Tab])),
?match({aborted, {has_no_disc, Node1}}, mnesia:change_table_copy_type(Tab, node(), disc_copies)),
@@ -241,7 +252,7 @@ db_node_lifecycle(Config) when is_list(Config) ->
?match(stopped, mnesia:stop()),
- ?match(ok, mnesia:create_schema(AllNodes)),
+ ?match(ok, mnesia:create_schema(AllNodes, ?BACKEND)),
?match([], mnesia_test_lib:start_mnesia(AllNodes)),
?match([SNs, SNs, SNs],
@@ -270,12 +281,15 @@ db_node_lifecycle(Config) when is_list(Config) ->
Tab3 = not_local,
Tab4 = local,
Tab5 = remote,
+ Tab6 = ext1,
Tabs = [Schema,
[{name, Tab2}, {disc_copies, AllNodes}],
[{name, Tab3}, {ram_copies, [Node2, Node3]}],
[{name, Tab4}, {disc_only_copies, [Node1]}],
- [{name, Tab5}, {disc_only_copies, [Node2]}]],
+ [{name, Tab5}, {disc_only_copies, [Node2]}],
+ [{name, Tab6}, {ext_ets, [Node1, Node2]}]
+ ],
[?match({atomic, ok}, mnesia:create_table(T)) || T <- Tabs ],
@@ -286,31 +300,28 @@ db_node_lifecycle(Config) when is_list(Config) ->
?match({aborted, {node_not_running, Node1}},
mnesia:del_table_copy(schema, Node2)),
- ?match([], mnesia_test_lib:start_mnesia([Node1],[Tab2,Tab4])),
+ ?match([], mnesia_test_lib:start_mnesia([Node1],[Tab2,Tab4,Tab6])),
?match([], mnesia_test_lib:stop_mnesia([Node2])),
- ?match({atomic, ok},
- mnesia:del_table_copy(schema, Node2)),
+ ?match({atomic, ok}, mnesia:del_table_copy(schema, Node2)),
- %% Check
+ %% Check
RemNodes = AllNodes -- [Node2],
- ?match(RemNodes, mnesia:system_info(db_nodes)),
+ ?match(RemNodes, mnesia:system_info(db_nodes)),
?match([Node1], Who(Tab)),
?match(RemNodes, Who(Tab2)),
?match([Node3], Who(Tab3)),
?match([Node1], Who(Tab4)),
?match({'EXIT', {aborted, {no_exists, _, _}}}, Who(Tab5)),
+ ?match([Node1], Who(Tab6)),
- ?match({atomic, ok},
- mnesia:change_table_copy_type(Tab2, Node3, ram_copies)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab2, Node3, ram_copies)),
- ?match({atomic, ok},
- mnesia:change_table_copy_type(schema, Node3, ram_copies)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(schema, Node3, ram_copies)),
?match([], mnesia_test_lib:stop_mnesia([Node3])),
- ?match({atomic, ok},
- mnesia:del_table_copy(schema, Node3)),
- ?match([Node1], mnesia:system_info(db_nodes)),
+ ?match({atomic, ok}, mnesia:del_table_copy(schema, Node3)),
+ ?match([Node1], mnesia:system_info(db_nodes)),
?match([Node1], Who(Tab)),
?match([Node1], Who(Tab2)),
?match({'EXIT', {aborted, {no_exists, _, _}}}, Who(Tab3)),
@@ -362,7 +373,8 @@ start_and_stop(Config) when is_list(Config) ->
checkpoint(suite) -> [];
checkpoint(Config) when is_list(Config) ->
checkpoint(2, Config),
- checkpoint(3, Config).
+ checkpoint(3, Config),
+ ok.
checkpoint(NodeConfig, Config) ->
[Node1 | _] = TabNodes = ?acquire_nodes(NodeConfig, Config),
@@ -380,7 +392,7 @@ checkpoint(NodeConfig, Config) ->
CreateTab(Type, 3, [lists:last(TabNodes)])] ++
Acc
end,
- Types = [ram_copies, disc_copies, disc_only_copies],
+ Types = [ram_copies, disc_copies, disc_only_copies, ext_ets],
Tabs = lists:foldl(CreateTabs, [], Types),
Recs = ?sort([{T, N, N} || T <- Tabs, N <- lists:seq(1, 10)]),
lists:foreach(fun(R) -> ?match(ok, mnesia:dirty_write(R)) end, Recs),
@@ -429,25 +441,29 @@ checkpoint(NodeConfig, Config) ->
replica_location(suite) -> [];
replica_location(Config) when is_list(Config) ->
[Node1, Node2, Node3] = Nodes = ?acquire_nodes(3, Config),
- 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)),
- ?match([], ?vrl(Tab, [Node1], [Node2], [Node3], Nodes)),
+ Check = fun(Tab, Schema) ->
+ ?match({atomic, ok}, mnesia:create_table([{name, Tab}|Schema])),
+ ?match([], ?vrl(Tab, [Node1], [Node2], [Node3], Nodes)),
- %% Delete one replica
- ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node2)),
- ?match([], ?vrl(Tab, [Node1], [], [Node3], Nodes)),
+ %% Delete one replica
+ ?match({atomic, ok}, mnesia:del_table_copy(Tab, Node2)),
+ ?match([], ?vrl(Tab, [Node1], [], [Node3], Nodes)),
- %% Move one replica
- ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
- ?match([], ?vrl(Tab, [Node2], [], [Node3], Nodes)),
+ %% Move one replica
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match([], ?vrl(Tab, [Node2], [], [Node3], Nodes)),
+
+ %% Change replica type
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node2, ram_copies)),
+ ?match([], ?vrl(Tab, [], [Node2], [Node3], Nodes))
+ end,
+ Check(replica_location, [{disc_only_copies, [Node1]},
+ {ram_copies, [Node2]}, {disc_copies, [Node3]}]),
- %% Change replica type
- ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node2, ram_copies)),
- ?match([], ?vrl(Tab, [], [Node2], [Node3], Nodes)),
+ Check(ext_location, [{disc_only_copies, [Node1]},
+ {ext_ets, [Node2]}, {disc_copies, [Node3]}]),
?verify_mnesia(Nodes, []).
@@ -719,7 +735,7 @@ replica_management(Config) when is_list(Config) ->
%%
?match({atomic, ok},
mnesia:create_table([{name, Tab}, {attributes, Attrs},
- {ram_copies, [Node1, Node3]}])),
+ {ram_copies, [Node1]}, {ext_ets, [Node3]}])),
[?match(ok, mnesia:dirty_write({Tab, K, K + 2})) || K <-lists:seq(1, 10)],
?match([], ?vrl(Tab, [], [Node1, Node3], [], Nodes)),
%% R - -
@@ -756,7 +772,7 @@ replica_management(Config) when is_list(Config) ->
?match([], ?vrl(Tab, [Node2], [], [Node1], Nodes)),
?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
%% D DO -
- ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node3, ram_copies)),
+ ?match({atomic, ok}, mnesia:add_table_copy(Tab, Node3, ext_ets)),
?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
%% D DO R
@@ -783,7 +799,7 @@ replica_management(Config) when is_list(Config) ->
?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
%% D DO D0
- ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node3, ram_copies)),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node3, ext_ets)),
?match([], ?vrl(Tab, [Node2], [Node3], [Node1], Nodes)),
?match([10,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
%% D DO R
@@ -840,18 +856,31 @@ replica_management(Config) when is_list(Config) ->
?match([], ?vrl(Tab, [Node3], [], [Node2], Nodes)),
?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
%% - D DO
+ ?match({atomic, ok}, mnesia:change_table_copy_type(Tab, Node3, ext_ets)),
+ ?match([], ?vrl(Tab, [], [Node3], [Node2], Nodes)),
+ ?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% - D ER
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node3, Node1)),
+ ?match([], ?vrl(Tab, [], [Node1], [Node2], Nodes)),
+ ?match([0,10,10], ?SS(rpc:multicall(Nodes, mnesia, table_info, [Tab, size]))),
+ %% ER D -
+
?match({aborted, _}, mnesia:move_table_copy(Tab, Node1, Node2)),
+ ?match({aborted, _}, mnesia:move_table_copy(Tab, Node3, Node2)),
+ ?match({atomic, ok}, mnesia:move_table_copy(Tab, Node1, Node3)),
+ %% - D ER
?match([], mnesia_test_lib:stop_mnesia([Node3])),
?match({atomic,ok}, mnesia:transaction(fun() -> mnesia:write({Tab, 43, sync_me}) end)),
- ?match([], ?vrl(Tab, [Node3], [], [Node2],Nodes -- [Node3])),
- %% - D DO
+ ?match([], ?vrl(Tab, [], [Node3], [Node2],Nodes -- [Node3])),
+ %% - D ER
?match({aborted,Reason56} when element(1, Reason56) == not_active,
mnesia:move_table_copy(Tab, Node3, Node1)),
- ?match([], ?vrl(Tab, [Node3], [], [Node2],Nodes -- [Node3])),
- %% DO D -
+ ?match([], ?vrl(Tab, [], [Node3], [Node2],Nodes -- [Node3])),
+ %% - D ER
?match([], mnesia_test_lib:start_mnesia([Node3])),
- ?match([], ?vrl(Tab, [Node3], [], [Node2], Nodes)),
- %% DO D -
+ ?match([], ?vrl(Tab, [], [Node3], [Node2], Nodes)),
+ %% - D ER
+ ?match([{Tab,43,sync_me}], mnesia:dirty_read({Tab,43})),
%%
%% Transformer
@@ -989,7 +1018,7 @@ local_content(Config) when is_list(Config) ->
?match([], mnesia_test_lib:stop_mnesia([Node3])),
%% Added for OTP-44306
- ?match(ok, rpc:call(Node3, mnesia, start, [])),
+ ?match(ok, rpc:call(Node3, mnesia, start, [[{schema, ?BACKEND}]])),
?match({ok, _}, mnesia:change_config(extra_db_nodes, [Node3])),
mnesia_test_lib:sync_tables([Node3], [Tab1]),
@@ -1338,11 +1367,11 @@ user_properties(Config) when is_list(Config) ->
?match([], mnesia:table_info(Tab2, user_properties)),
?match([], mnesia:table_info(Tab3, user_properties)),
- ?match({'EXIT', {no_exists, {Tab1, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab1, user_property, PropKey}}}},
mnesia:read_table_property(Tab1, PropKey)),
- ?match({'EXIT', {no_exists, {Tab2, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab2, user_property, PropKey}}}},
mnesia:read_table_property(Tab2, PropKey)),
- ?match({'EXIT', {no_exists, {Tab3, user_property, PropKey}}},
+ ?match({'EXIT', {aborted, {no_exists, {Tab3, user_property, PropKey}}}},
mnesia:read_table_property(Tab3, PropKey)),
?match({atomic, ok}, mnesia:write_table_property(Tab1, Prop)),
@@ -1426,7 +1455,7 @@ unsupp_user_props(Config) when is_list(Config) ->
table_info, [silly1, user_properties])),
?match([{prop,propval2}], rpc:call(Node1, mnesia,
table_info, [silly2, user_properties])),
- ?match([{prop,propval3}], rpc:call(Node1, mnesia,
+ ?match([_,{prop,propval3}], rpc:call(Node1, mnesia,
table_info, [schema, user_properties])),
F2 = fun() ->
@@ -2261,6 +2290,10 @@ record_name_dirty_access_disc_only(suite) ->
record_name_dirty_access_disc_only(Config) when is_list(Config) ->
record_name_dirty_access(disc_only_copies, Config).
+record_name_dirty_access_xets(Config) when is_list(Config) ->
+ record_name_dirty_access(ext_ets, Config).
+
+
record_name_dirty_access(Storage, Config) ->
[Node1, _Node2] = Nodes = ?acquire_nodes(2, Config),
diff --git a/lib/mnesia/test/mnesia_examples_test.erl b/lib/mnesia/test/mnesia_examples_test.erl
index 219f358fdb..808e62d9c2 100644
--- a/lib/mnesia/test/mnesia_examples_test.erl
+++ b/lib/mnesia/test/mnesia_examples_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_frag_test.erl b/lib/mnesia/test/mnesia_frag_test.erl
index 6695fbc880..9f2102beb2 100644
--- a/lib/mnesia/test/mnesia_frag_test.erl
+++ b/lib/mnesia/test/mnesia_frag_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_inconsistent_database_test.erl b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
index c4b6257d5b..3fd2c6ad5b 100644
--- a/lib/mnesia/test/mnesia_inconsistent_database_test.erl
+++ b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl
index 06d53d3912..103f85b3d6 100644
--- a/lib/mnesia/test/mnesia_install_test.erl
+++ b/lib/mnesia/test/mnesia_install_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index 8468472cf2..63940ec05c 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -38,7 +39,7 @@ groups() ->
[{locking, [],
[no_conflict, simple_queue_conflict,
advanced_queue_conflict, simple_deadlock_conflict,
- advanced_deadlock_conflict, lock_burst,
+ advanced_deadlock_conflict, schema_deadlock, lock_burst,
{group, sticky_locks}, {group, unbound_locking},
{group, admin_conflict}, nasty]},
{sticky_locks, [], [basic_sticky_functionality]},
@@ -147,20 +148,32 @@ simple_queue_conflict(Config) when is_list(Config) ->
fun_loop(Fun, AllSharedLocks, OneExclusiveLocks),
ok.
-wait_for_lock(Pid, _Nodes, 0) ->
+wait_for_lock(Pid, Nodes, Retry) ->
+ wait_for_lock(Pid, Nodes, Retry, queue).
+
+wait_for_lock(Pid, _Nodes, 0, queue) ->
Queue = mnesia:system_info(lock_queue),
?error("Timeout while waiting for lock on Pid ~p in queue ~p~n", [Pid, Queue]);
-wait_for_lock(Pid, Nodes, N) ->
- rpc:multicall(Nodes, sys, get_status, [mnesia_locker]),
- List = [rpc:call(Node, mnesia, system_info, [lock_queue]) || Node <- Nodes],
+wait_for_lock(Pid, _Nodes, 0, held) ->
+ Held = mnesia:system_info(held_locks),
+ ?error("Timeout while waiting for lock on Pid ~p (held) ~p~n", [Pid, Held]);
+wait_for_lock(Pid, Nodes, N, Where) ->
+ rpc:multicall(Nodes, sys, get_status, [mnesia_locker]),
+ List = case Where of
+ queue ->
+ [rpc:call(Node, mnesia, system_info, [lock_queue]) || Node <- Nodes];
+ held ->
+ [rpc:call(Node, mnesia, system_info, [held_locks]) || Node <- Nodes]
+ end,
Q = lists:append(List),
- check_q(Pid, Q, Nodes, N).
+ check_q(Pid, Q, Nodes, N, Where).
-check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count) -> ok;
-check_q(Pid, [_ | Tail], N, Count) -> check_q(Pid, Tail, N, Count);
-check_q(Pid, [], N, Count) ->
- timer:sleep(500),
- wait_for_lock(Pid, N, Count - 1).
+check_q(Pid, [{_Oid, _Op, Pid, _Tid, _WFT} | _Tail], _N, _Count, _Where) -> ok;
+check_q(Pid, [{_Oid, _Op, {tid,_,Pid}} | _Tail], _N, _Count, _Where) -> ok;
+check_q(Pid, [_ | Tail], N, Count, Where) -> check_q(Pid, Tail, N, Count, Where);
+check_q(Pid, [], N, Count, Where) ->
+ timer:sleep(200),
+ wait_for_lock(Pid, N, Count - 1, Where).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -269,6 +282,43 @@ advanced_deadlock_conflict(Config) when is_list(Config) ->
?match([], mnesia:system_info(lock_queue)),
ok.
+%% Verify (and regression test) deadlock in del_table_copy(schema, Node)
+schema_deadlock(Config) when is_list(Config) ->
+ Ns = [Node1, Node2] = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(a, [{disc_copies, Ns}])),
+ ?match({atomic, ok}, mnesia:create_table(b, [{disc_copies, Ns}])),
+
+ Tester = self(),
+
+ Deadlocker = fun() ->
+ mnesia:write({a,1,1}), %% grab write lock on A
+ receive
+ continue ->
+ mnesia:write({b,1,1}), %% grab write lock on B
+ end_trans
+ end
+ end,
+
+ ?match(stopped, rpc:call(Node2, mnesia, stop, [])),
+ timer:sleep(500), %% Let Node1 reconfigure
+ sys:get_status(mnesia_monitor),
+
+ DoingTrans = spawn_link(fun() -> Tester ! {self(),mnesia:transaction(Deadlocker)} end),
+ wait_for_lock(DoingTrans, [Node1], 10, held),
+ %% Will grab write locks on schema, a, and b
+ DoingSchema = spawn_link(fun() -> Tester ! {self(), mnesia:del_table_copy(schema, Node2)} end),
+ timer:sleep(500), %% Let schema trans start, and try to grab locks
+ DoingTrans ! continue,
+
+ ?match(ok, receive {DoingTrans, {atomic, end_trans}} -> ok after 5000 -> timeout end),
+ ?match(ok, receive {DoingSchema, {atomic, ok}} -> ok after 5000 -> timeout end),
+
+ sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async
+ ?match([], mnesia:system_info(held_locks)),
+ ?match([], mnesia:system_info(lock_queue)),
+ ok.
+
+
one_oid(Tab) -> {Tab, 1}.
other_oid(Tab) -> {Tab, 2}.
@@ -1126,7 +1176,9 @@ update_shared(Tab, Me, Acc) ->
0 ->
case mnesia:transaction(Update) of
{atomic, {ok,Term,W2}} ->
- io:format("~p:~p:(~p,~p) ~w@~w~n", [erlang:now(),node(),Me,Acc,Term,W2]),
+ io:format("~p:~p:(~p,~p) ~w@~w~n",
+ [erlang:unique_integer([monotonic,positive]),
+ node(),Me,Acc,Term,W2]),
update_shared(Tab, Me, Acc+1);
Else ->
?error("Trans failed on ~p with ~p~n"
diff --git a/lib/mnesia/test/mnesia_majority_test.erl b/lib/mnesia/test/mnesia_majority_test.erl
index 41ba0fd601..9811de6ae7 100644
--- a/lib/mnesia/test/mnesia_majority_test.erl
+++ b/lib/mnesia/test/mnesia_majority_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
index 8854854570..ad71fafecb 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_meter.erl b/lib/mnesia/test/mnesia_meter.erl
index 68094c4431..c278dfde93 100644
--- a/lib/mnesia/test/mnesia_meter.erl
+++ b/lib/mnesia/test/mnesia_meter.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
index 4b28ac634f..ffbe36e48d 100644
--- a/lib/mnesia/test/mnesia_nice_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
index 9886754710..5067e86521 100644
--- a/lib/mnesia/test/mnesia_qlc_test.erl
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_recovery_test.erl b/lib/mnesia/test/mnesia_recovery_test.erl
index 946a9f97ba..130b87346f 100644
--- a/lib/mnesia/test/mnesia_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_recovery_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -503,12 +504,21 @@ with_checkpoint(Config, Type) when is_list(Config) ->
?match(ok, mnesia:deactivate_checkpoint(sune)),
?match([], check_chkp(Nodes)),
+ Wait = fun(Loop) ->
+ timer:sleep(300),
+ sys:get_status(mnesia_monitor),
+ case lists:member(Kill, mnesia_lib:val({current, db_nodes})) of
+ true -> Loop(Loop);
+ false -> ok
+ end
+ end,
+
case Kill of
Node1 ->
ignore;
Node2 ->
mnesia_test_lib:kill_mnesia([Kill]),
- timer:sleep(500), %% Just to help debugging
+ Wait(Wait),
?match({ok, sune, _}, mnesia:activate_checkpoint([{name, sune},
{max, mnesia:system_info(tables)},
{ram_overrides_dump, true}])),
@@ -575,7 +585,7 @@ delete_during_start(Config) when is_list(Config) ->
mnesia_test_lib:kill_mnesia([N2,N3]),
%% timer:sleep(500),
?match({[ok,ok],[]}, rpc:multicall([N2,N3], mnesia,start,
- [[{extra_db_nodes,[N1]}]])),
+ [[{extra_db_nodes,[N1]}, {schema, ?BACKEND}]])),
[Tab1,Tab2,Tab3|_] = Tabs,
?match({atomic, ok}, mnesia:delete_table(Tab1)),
?match({atomic, ok}, mnesia:delete_table(Tab2)),
@@ -1541,7 +1551,7 @@ disc_less(Config) when is_list(Config) ->
?match(ok, rpc:call(Node2, mnesia, start, [])),
timer:sleep(500),
- ?match(ok, rpc:call(Node3, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}]])),
+ ?match(ok, rpc:call(Node3, mnesia, start, [[{extra_db_nodes, [Node1, Node2]}, {schema, ?BACKEND}]])),
?match(ok, rpc:call(Node3, mnesia, wait_for_tables, [[Tab1, Tab2, Tab3], 20000])),
?match(ok, rpc:call(Node1, mnesia, wait_for_tables, [[Tab1, Tab2, Tab3], 20000])),
diff --git a/lib/mnesia/test/mnesia_registry_test.erl b/lib/mnesia/test/mnesia_registry_test.erl
index cf8da38632..3df37a2c8c 100644
--- a/lib/mnesia/test/mnesia_registry_test.erl
+++ b/lib/mnesia/test/mnesia_registry_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_schema_recovery_test.erl b/lib/mnesia/test/mnesia_schema_recovery_test.erl
index 2301b291c2..ca2dd74b34 100644
--- a/lib/mnesia/test/mnesia_schema_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_schema_recovery_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 6a51aefdf0..6e84a27ec9 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -141,6 +142,9 @@
%% included for test server compatibility
%% assume that all test cases only takes Config as sole argument
init_per_testcase(_Func, Config) ->
+ Env = application:get_all_env(mnesia),
+ [application:unset_env(mnesia, Key, [{timeout, infinity}]) ||
+ {Key, _} <- Env, Key /= included_applications],
global:register_name(mnesia_global_logger, group_leader()),
Config.
@@ -237,8 +241,8 @@ slave_start_link() ->
slave_start_link(Node) ->
[Local, Host] = node_to_name_and_host(Node),
- {Mega, Sec, Micro} = erlang:now(),
- List = [Local, "_", Mega, "_", Sec, "_", Micro],
+ Count = erlang:unique_integer([positive]),
+ List = [Local, "_", Count],
Name = list_to_atom(lists:concat(List)),
slave_start_link(list_to_atom(Host), Name).
@@ -667,11 +671,13 @@ do_prepare([delete_schema | Actions], Selected, All, Config, File, Line) ->
end,
do_prepare(Actions, Selected, All, Config, File, Line);
do_prepare([create_schema | Actions], Selected, All, Config, File, Line) ->
+ Ext = ?BACKEND,
case diskless(Config) of
true ->
+ rpc:multicall(Selected, application, set_env, [mnesia, schema, Ext]),
skip;
_Else ->
- case mnesia:create_schema(Selected) of
+ case mnesia:create_schema(Selected, Ext) of
ok ->
ignore;
BadNodes ->
@@ -974,7 +980,6 @@ reload_appls([Appl | Appls], Selected) ->
{Ok2temp, Empty} = rpc:multicall(Selected, application, unload, [Appl]),
Conv = fun({error,{not_loaded,mnesia}}) -> ok; (Else) -> Else end,
Ok2 = {lists:map(Conv, Ok2temp), Empty},
-
Ok3 = rpc:multicall(Selected, application, load, [Appl]),
if
Ok /= Ok2 ->
@@ -1039,7 +1044,8 @@ verify_replica_location(Tab, DiscOnly0, Ram0, Disc0, AliveNodes0) ->
S1 = ?match(AliveNodes, lists:sort(mnesia:system_info(running_db_nodes))),
S2 = ?match(DiscOnly, lists:sort(mnesia:table_info(Tab, disc_only_copies))),
- S3 = ?match(Ram, lists:sort(mnesia:table_info(Tab, ram_copies))),
+ S3 = ?match(Ram, lists:sort(mnesia:table_info(Tab, ram_copies) ++
+ mnesia:table_info(Tab, ext_ets))),
S4 = ?match(Disc, lists:sort(mnesia:table_info(Tab, disc_copies))),
S5 = ?match(Write, lists:sort(mnesia:table_info(Tab, where_to_write))),
S6 = case lists:member(This, Read) of
diff --git a/lib/mnesia/test/mnesia_test_lib.hrl b/lib/mnesia/test/mnesia_test_lib.hrl
index cd76377df6..ba7eb10ea2 100644
--- a/lib/mnesia/test/mnesia_test_lib.hrl
+++ b/lib/mnesia/test/mnesia_test_lib.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -149,3 +150,5 @@
-define(verify_mnesia(Ups, Downs),
mnesia_test_lib:verify_mnesia(Ups, Downs, ?FILE, ?LINE)).
+
+-define(BACKEND, [{backend_types, [{ext_ets, ext_test},{ext_dets, ext_test}]}]).
diff --git a/lib/mnesia/test/mnesia_tpcb.erl b/lib/mnesia/test/mnesia_tpcb.erl
index 595412ff24..fb39ee321d 100644
--- a/lib/mnesia/test/mnesia_tpcb.erl
+++ b/lib/mnesia/test/mnesia_tpcb.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -99,9 +100,13 @@
replica_test/1,
sticky_replica_test/1,
remote_test/1,
- remote_frag2_test/1
+ remote_frag2_test/1,
+
+ conflict_benchmark/1
]).
+-include_lib("common_test/include/ct_event.hrl").
+
-define(SECOND, 1000000).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -159,7 +164,7 @@
-record(history,
{
history_id = {0, 0}, % {DriverId, DriverLocalHistoryid}
- time_stamp = now(), % Time point during active transaction
+ time_stamp = erlang:system_time(), % Time point during active transaction
branch_id = 0, % Branch associated with teller
teller_id = 0, % Teller invlolved in transaction
account_id = 0, % Account updated by transaction
@@ -191,8 +196,10 @@
driver_nodes = [node()],
n_drivers_per_node = 1,
use_running_mnesia = false,
+ seed,
stop_after = timer:minutes(15), % Minimum 15 min
report_interval = timer:minutes(1),
+ send_bench_report = false,
use_sticky_locks = false,
spawn_near_branch = false,
activity_type = transaction,
@@ -397,8 +404,29 @@ config(remote_frag2_test, ReplicaType) ->
{stop_after, timer:minutes(1)},
{report_interval, timer:seconds(10)},
{reuse_history_id, true}
+ ];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Ten drivers per node, tables replicated to all nodes, single branch
+
+config(conflict_benchmark, ReplicaType) ->
+ Remote = nodes(),
+ Local = node(),
+ Nodes = [Local | Remote],
+ [{db_nodes, Nodes},
+ {driver_nodes, Nodes},
+ {replica_nodes, Nodes},
+ {n_drivers_per_node, 10},
+ {n_branches, 1},
+ {n_accounts_per_branch, 10},
+ {replica_type, ReplicaType},
+ {stop_after, timer:minutes(1)},
+ {report_interval, timer:seconds(10)},
+ {send_bench_report, true},
+ {reuse_history_id, true}
].
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
start(What, ReplicaType) ->
@@ -422,6 +450,9 @@ remote_test(ReplicaType) ->
remote_frag2_test(ReplicaType) ->
start(remote_frag2_test, ReplicaType).
+conflict_benchmark(ReplicaType) ->
+ start(config(conflict_benchmark, ReplicaType)).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Args is a list of {Key, Val} tuples where Key is a field name
%% in either the record tab_config or run_config. Unknown keys are ignored.
@@ -726,7 +757,7 @@ reporter_init(Starter, RC) ->
replica_type = Type
},
Drivers = start_drivers(RC, TC),
- Now = now_to_micros(erlang:now()),
+ Now = erlang:monotonic_time(),
State = #reporter_state{driver_pids = Drivers,
run_config = RC,
starter_pid = Starter,
@@ -864,8 +895,9 @@ add_time(Acc, New) ->
-define(AVOID_DIV_ZERO(_What_), try (_What_) catch _:_ -> 0 end).
show_report(State) ->
- Now = now_to_micros(erlang:now()),
+ Now = erlang:timestamp(),
Iters = State#reporter_state.n_iters,
+ Cfg = State#reporter_state.run_config,
Time = State#reporter_state.curr,
Max = Time#time.max_time,
N = Time#time.n_trans,
@@ -888,6 +920,16 @@ show_report(State) ->
"duration of longest transaction was ~p milliseconds~n",
[Tps, BruttoTps, Max div 1000])
end,
+ case Cfg#run_config.send_bench_report of
+ true ->
+ ct_event:notify(
+ #event{name = benchmark_data,
+ data = [{suite,"mnesia_tpcb"},
+ {value,Tps}]});
+ _ ->
+ ok
+ end,
+
State#reporter_state{prev_tps = Tps, prev_micros = Now}.
signed_diff(Iters, Curr, Prev) ->
@@ -898,11 +940,6 @@ signed_diff(Iters, Curr, Prev) ->
sign(N) when N > 0 -> {"+", N};
sign(N) -> {"", N}.
-
-now_to_micros({Mega, Secs, Micros}) ->
- DT = calendar:now_to_datetime({Mega, Secs, 0}),
- S = calendar:datetime_to_gregorian_seconds(DT),
- (S * ?SECOND) + Micros.
start_drivers(RC, TC) ->
LastHistoryId = table_info(history, size),
@@ -955,7 +992,11 @@ alloc_local_branches([], Specs, OrphanBranches) ->
{Specs, OrphanBranches}.
driver_init(DS, AllBranches) ->
- Seed = erlang:now(),
+ Seed = case (DS#driver_state.run_config)#run_config.seed of
+ undefined -> rand:seed(exsplus);
+ ExpSeed -> rand:seed(ExpSeed)
+ end,
+
DS2 =
if
DS#driver_state.n_local_branches =:= 0 ->
@@ -1009,14 +1050,7 @@ calc_trans(DS) ->
%% Generate teller_id, account_id and delta
%% Time the TPC-B transaction
time_trans(DS) ->
- OldSeed = get(random_seed), % Avoid interference with Mnesia
- put(random_seed, DS#driver_state.seed),
- Random = random:uniform(),
- NewSeed = get(random_seed),
- case OldSeed of
- undefined -> erase(random_seed);
- _ -> put(random_seed, OldSeed)
- end,
+ {Random, NewSeed} = rand:uniform_s(DS#driver_state.seed),
TC = DS#driver_state.tab_config,
RC = DS#driver_state.run_config,
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index 237984978e..aa50ee4cb1 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -930,20 +931,20 @@ index_update_bag(Config)when is_list(Config) ->
[IPos] = mnesia_lib:val({Tab,index}),
ITab = mnesia_lib:val({index_test,{index, IPos}}),
io:format("~n Index ~p @ ~p => ~p ~n~n",[IPos,ITab, ets:tab2list(ITab)]),
- ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+ %?match([{2,1},{2,2},{12,1}], lists:keysort(1,ets:tab2list(ITab))),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec5) end)),
{atomic, R60} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
?match([Rec1,Rec5,Rec2], lists:sort(R60)),
- ?match([{2,1},{2,2},{12,1}], ets:tab2list(ITab)),
+ %?match([{2,1},{2,2},{12,1}], lists:keysort(1,ets:tab2list(ITab))),
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:delete_object(Rec3) end)),
{atomic, R61} = mnesia:transaction(fun() -> mnesia:index_read(Tab, 2, ValPos) end),
?match([Rec1,Rec5,Rec2], lists:sort(R61)),
{atomic, R62} = mnesia:transaction(fun() -> mnesia:index_read(Tab,12, ValPos) end),
?match([], lists:sort(R62)),
- ?match([{2,1},{2,2}], ets:tab2list(ITab)),
+ %% ?match([{2,1},{2,2}], lists:keysort(1,ets:tab2list(ITab))),
%% reset for rest of testcase
?match({atomic, ok}, mnesia:transaction(fun() -> mnesia:write(Rec3) end)),
@@ -1141,8 +1142,9 @@ create_live_table_index(Config, Storage) ->
?match([{atomic,ok}|_], [Create(N) || N <- lists:seq(1,50)]),
?match([], mnesia_test_lib:stop_mnesia([N2,N3])),
- ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1]}]])),
- ?match(ok, rpc:call(N3, mnesia, start, [[{extra_db_nodes,[N1]}]])),
+ Ext = [{schema, ?BACKEND}],
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1]}|Ext]])),
+ ?match(ok, rpc:call(N3, mnesia, start, [[{extra_db_nodes,[N1]}|Ext]])),
?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
diff --git a/lib/mnesia/test/mt b/lib/mnesia/test/mt
index 25243f1149..a398ee0422 100755
--- a/lib/mnesia/test/mt
+++ b/lib/mnesia/test/mt
@@ -1,14 +1,15 @@
#! /bin/sh -f
-# ``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 via the world wide web 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.
+# ``Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
diff --git a/lib/mnesia/test/mt.erl b/lib/mnesia/test/mt.erl
index f1152a7bc4..5a981bf539 100644
--- a/lib/mnesia/test/mt.erl
+++ b/lib/mnesia/test/mt.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -79,6 +80,8 @@ resolve(Suite0) when is_atom(Suite0) ->
{Suite, Case} ->
{Suite, is_group(Suite,Case)}
end;
+resolve({Suite0, {group, Case}}) ->
+ resolve({Suite0, Case});
resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
case alias(Suite0) of
Suite when is_atom(Suite) ->