1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22-module(mnesia_registry_test).
23-author('hakan@erix.ericsson.se').
24-export([init_per_testcase/2, end_per_testcase/2,
25         init_per_group/2, end_per_group/2,
26         all/0, groups/0]).
27
28-export([good_dump/1, bad_dump/1, dump_registry/2, restore_registry/2]).
29
30-include("mnesia_test_lib.hrl").
31
32init_per_testcase(Func, Conf) ->
33    mnesia_test_lib:init_per_testcase(Func, Conf).
34
35end_per_testcase(Func, Conf) ->
36    mnesia_test_lib:end_per_testcase(Func, Conf).
37
38%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39all() ->
40    [good_dump, bad_dump].
41
42groups() ->
43    [].
44
45init_per_group(_GroupName, Config) ->
46    Config.
47
48end_per_group(_GroupName, Config) ->
49    Config.
50
51
52%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53good_dump(doc) ->
54    ["Dump a faked C-node registry"];
55good_dump(suite) -> [];
56good_dump(Config) when is_list(Config) ->
57    [Node] = Nodes = ?acquire_nodes(1, Config),
58    T1 = gordon,
59    ?match(ok, mnesia_registry:create_table(T1)),
60    One = {T1, 1, 0, integer, 0, 10},
61    Two = {T1, "two", 3, integer, 0, 20},
62    Three = {T1, 3, 0, string, 6, "thirty"},
63    ?match(ok, mnesia:dirty_write(One)),
64    ?match(ok, mnesia:dirty_write(Two)),
65    ?match(ok, mnesia:dirty_write(Three)),
66    ?match([One], mnesia:dirty_read({T1, 1})),
67    ?match([_ | _], dump_registry(Node, T1)),
68
69    NewOne = {T1, 1, 0, integer, 0, 1},
70    NewFour = {T1, "4", 1, string, 4, "four"},
71
72    ?match([NewOne], mnesia:dirty_read({T1, 1})),
73    ?match([Two], mnesia:dirty_read({T1, "two"})),
74    ?match([], mnesia:dirty_read({T1, 3})),
75    ?match([NewFour], mnesia:dirty_read({T1, "4"})),
76
77    T2 = blixt,
78    ?match({'EXIT', {aborted, {no_exists, _}}},
79	   mnesia:dirty_read({T2, 1})),
80    ?match([_ |_], dump_registry(Node, T2)),
81
82    NewOne2 = setelement(1, NewOne, T2),
83    NewFour2 = setelement(1, NewFour, T2),
84
85    ?match([NewOne2], mnesia:dirty_read({T2, 1})),
86    ?match([], mnesia:dirty_read({T2, "two"})),
87    ?match([], mnesia:dirty_read({T2, 3})),
88    ?match([NewFour2], mnesia:dirty_read({T2, "4"})),
89    ?match([_One2, NewFour2], lists:sort(restore_registry(Node, T2))),
90
91    ?verify_mnesia(Nodes, []).
92
93dump_registry(Node, Tab) ->
94    case rpc:call(Node, mnesia_registry, start_dump, [Tab, self()]) of
95	Pid when is_pid(Pid) ->
96	    Pid ! {write, 1, 0, integer, 0, 1},
97	    Pid ! {delete, 3},
98	    Pid ! {write, "4", 1, string, 4, "four"},
99	    Pid ! {commit, self()},
100	    receive
101		{ok, Pid} ->
102		    [{Tab, "4", 1, string, 4, "four"},
103		     {Tab, 1, 0, integer, 0, 1}];
104		{'EXIT', Pid, Reason} ->
105		    exit(Reason)
106	    end;
107	{badrpc, Reason} ->
108	    exit(Reason)
109    end.
110
111restore_registry(Node, Tab) ->
112    case rpc:call(Node, mnesia_registry, start_restore, [Tab, self()]) of
113	{size, Pid, N, _LargestKeySize, _LargestValSize} ->
114	    Pid ! {send_records, self()},
115	    receive_records(Tab, N);
116	{badrpc, Reason} ->
117	    exit(Reason)
118    end.
119
120receive_records(Tab, N) when N > 0 ->
121    receive
122	{restore, KeySize, ValSize, ValType, Key, Val} ->
123	    [{Tab, Key, KeySize, ValType, ValSize, Val} | receive_records(Tab, N -1)];
124	{'EXIT', _Pid, Reason} ->
125	    exit(Reason)
126    end;
127receive_records(_Tab, 0) ->
128    [].
129
130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131bad_dump(doc) ->
132    ["Intentionally fail with the dump of a faked C-node registry"];
133bad_dump(suite) -> [];
134bad_dump(Config) when is_list(Config) ->
135    [Node] = Nodes = ?acquire_nodes(1, Config),
136
137    OldTab = ming,
138    ?match({'EXIT', {aborted, _}}, mnesia_registry:start_restore(no_tab, self())),
139    ?match({atomic, ok}, mnesia:create_table(OldTab, [{attributes, [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]}])),
140    ?match({'EXIT',{aborted,{bad_type,_}}}, dump_registry(Node, OldTab)),
141    ?match(stopped, mnesia:stop()),
142
143    ?match({'EXIT', {aborted, _}}, mnesia_registry:create_table(down_table)),
144    ?match({'EXIT', {aborted, _}}, mnesia_registry:start_restore(no_tab, self())),
145    ?match({'EXIT', {aborted, _}}, dump_registry(Node, down_dump)),
146
147    ?verify_mnesia([], Nodes).
148
149