1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1998-2016. 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-module(global_group_SUITE).
22
23-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
24	 init_per_suite/1, end_per_suite/1]).
25-export([start_gg_proc/1, no_gg_proc/1, no_gg_proc_sync/1, compatible/1,
26	 one_grp/1, one_grp_x/1, two_grp/1, hidden_groups/1, test_exit/1]).
27-export([init/1, init/2, init2/2, start_proc/1, start_proc_rereg/1]).
28
29-export([init_per_testcase/2, end_per_testcase/2]).
30
31%%-compile(export_all).
32
33-include_lib("common_test/include/ct.hrl").
34
35-define(NODES, [node()|nodes()]).
36
37-define(UNTIL(Seq), loop_until_true(fun() -> Seq end)).
38
39suite() ->
40    [{ct_hooks,[ts_install_cth]},
41     {timetrap,{minutes,5}}].
42
43all() ->
44    [start_gg_proc, no_gg_proc, no_gg_proc_sync, compatible,
45     one_grp, one_grp_x, two_grp, test_exit, hidden_groups].
46
47groups() ->
48    [].
49
50init_per_group(_GroupName, Config) ->
51    Config.
52
53end_per_group(_GroupName, Config) ->
54    Config.
55
56
57init_per_suite(Config) ->
58
59    %% Copied from test_server_ctrl ln 647, we have to do this here as
60    %% the test_server only does this when run without common_test
61    global:sync(),
62    case global:whereis_name(test_server) of
63	undefined ->
64	    io:format(user, "Registering test_server globally!~n",[]),
65	    global:register_name(test_server, whereis(test_server_ctrl));
66	Pid ->
67	    case node() of
68		N when N == node(Pid) ->
69		    io:format(user, "Warning: test_server already running!\n", []),
70		    global:re_register_name(test_server,self());
71		_ ->
72		    ok
73	    end
74    end,
75    Config.
76
77end_per_suite(_Config) ->
78    global:unregister_name(test_server),
79    ok.
80
81-define(TESTCASE, testcase_name).
82-define(testcase, proplists:get_value(?TESTCASE, Config)).
83
84init_per_testcase(Case, Config) ->
85    Config.
86
87end_per_testcase(_Func, _Config) ->
88    ok.
89
90%%-----------------------------------------------------------------
91%% Test suites for global groups.
92%% Should be started in a CC view with:
93%% erl -sname XXX -rsh ctrsh where XXX not in [cp1 .. cpN]
94%%-----------------------------------------------------------------
95
96
97%% Check that the global_group processes are started automatically. .
98start_gg_proc(Config) when is_list(Config) ->
99    Dir = proplists:get_value(priv_dir, Config),
100    File = filename:join(Dir, "global_group.config"),
101    {ok, Fd}=file:open(File, [write]),
102    [Ncp1,Ncp2,Ncp3] = node_names([cp1, cp2, cp3], Config),
103    config(Fd, Ncp1, Ncp2, Ncp3, "cpx", "cpy", "cpz", "cpq"),
104
105    Cp1nn = node_at(Ncp1),
106    Cp2nn = node_at(Ncp2),
107    Cp3nn = node_at(Ncp3),
108
109    {ok, Cp1} = start_node(Ncp1, Config),
110    {ok, Cp2} = start_node(Ncp2, Config),
111    {ok, Cp3} = start_node(Ncp3, Config),
112
113    [] = rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}]),
114    [] = rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}]),
115    [] = rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}]),
116
117    %% stop the nodes, and make sure names are released.
118    stop_node(Cp1),
119    stop_node(Cp2),
120    stop_node(Cp3),
121
122    ?UNTIL(undefined =:= global:whereis_name(test)),
123    ok.
124
125
126
127%% Start a system without global groups. Nodes are not
128%% synced at start (sync_nodes_optional is not defined).
129no_gg_proc(Config) when is_list(Config) ->
130    Dir = proplists:get_value(priv_dir, Config),
131    File = filename:join(Dir, "no_global_group.config"),
132    {ok, Fd} = file:open(File, [write]),
133    config_no(Fd),
134
135    NN = node_name(atom_to_list(node())),
136    Cp1nn = list_to_atom("cp1@" ++ NN),
137    Cp2nn = list_to_atom("cp2@" ++ NN),
138    Cp3nn = list_to_atom("cp3@" ++ NN),
139    Cpxnn = list_to_atom("cpx@" ++ NN),
140    Cpynn = list_to_atom("cpy@" ++ NN),
141    Cpznn = list_to_atom("cpz@" ++ NN),
142
143    {ok, Cp1} = start_node_no(cp1, Config),
144    {ok, Cp2} = start_node_no(cp2, Config),
145    {ok, Cp3} = start_node_no(cp3, Config),
146    {ok, Cpx} = start_node_no(cpx, Config),
147    {ok, Cpy} = start_node_no(cpy, Config),
148    {ok, Cpz} = start_node_no(cpz, Config),
149
150    %% let the nodes know of each other
151    pong = rpc:call(Cp1, net_adm, ping, [Cp2nn]),
152    pong = rpc:call(Cp2, net_adm, ping, [Cp3nn]),
153    pong = rpc:call(Cp3, net_adm, ping, [Cpxnn]),
154    pong = rpc:call(Cpx, net_adm, ping, [Cpynn]),
155    pong = rpc:call(Cpy, net_adm, ping, [Cpznn]),
156
157    wait_for_ready_net(),
158
159    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}]),
160    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}]),
161    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}]),
162    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}]),
163    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}]),
164    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}]),
165
166
167    %% start a proc and register it
168    {Pid2, yes} = rpc:call(Cp2, ?MODULE, start_proc, [test2]),
169
170    RegNames = lists:sort([test2,test_server]),
171
172    RegNames =
173	lists:sort(
174	  rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}])),
175    RegNames =
176	lists:sort(
177	  rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}])),
178    RegNames =
179	lists:sort(
180	  rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}])),
181    RegNames =
182	lists:sort(
183	  rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}])),
184    RegNames =
185	lists:sort(
186	  rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}])),
187    RegNames =
188	lists:sort(
189	  rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}])),
190
191
192    undefined = rpc:call(Cp3, global_group, global_groups, []),
193
194    Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
195			Cpxnn, Cpynn, Cpznn],
196    Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
197    [] = (Own_nodes -- Own_nodes_should),
198    [] = (Own_nodes_should -- Own_nodes),
199
200    Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
201    receive
202	{pong, Cp2} -> ok
203    after
204	2000 -> ct:fail(timeout2)
205    end,
206    Pid2 = rpc:call(Cp2, global_group, send, [test2, {ping, self()}]),
207    receive
208	{pong, Cp2} -> ok
209    after
210	2000 -> ct:fail(timeout3)
211    end,
212    Pid2 = rpc:call(Cpz, global_group, send, [test2, {ping, self()}]),
213    receive
214	{pong, Cp2} -> ok
215    after
216	2000 -> ct:fail(timeout4)
217    end,
218
219
220    %% start a proc and register it
221    {PidX, yes} = rpc:call(Cpx, ?MODULE, start_proc, [test]),
222
223
224    %%------------------------------------
225    %% Test monitor nodes
226    %%------------------------------------
227    Pid2 = rpc:call(Cp1, global_group, send, [{node, Cp2nn}, test2, monitor]),
228    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, monitor]),
229
230
231    %% Kill node Cp1
232    Pid2 =
233	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cp1}]),
234    PidX =
235	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cp1}]),
236    ct:sleep(100),
237    stop_node(Cp1),
238    ct:sleep(1000),
239
240    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
241    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
242
243    %% Kill node Cpz
244    Pid2 =
245	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cpz}]),
246    PidX =
247	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cpz}]),
248    ct:sleep(100),
249    stop_node(Cpz),
250    ct:sleep(1000),
251
252    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
253    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
254
255    %% Restart node Cp1
256    Pid2 =
257	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cp1}]),
258    PidX =
259	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cp1}]),
260    {ok, Cp1} = start_node_no(cp1, Config),
261    pong = rpc:call(Cp2, net_adm, ping, [Cp1nn]),
262    pong = rpc:call(Cpx, net_adm, ping, [Cp1nn]),
263    wait_for_ready_net(),
264
265    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
266    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
267
268    %% Restart node Cpz
269    Pid2 =
270	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cpz}]),
271    PidX =
272	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cpz}]),
273    {ok, Cpz} = start_node_no(cpz, Config),
274    pong = rpc:call(Cp2, net_adm, ping, [Cpznn]),
275    pong = rpc:call(Cpx, net_adm, ping, [Cpznn]),
276    wait_for_ready_net(),
277
278    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
279    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
280
281    %% stop the nodes, and make sure names are released.
282    stop_node(Cp1),
283    stop_node(Cp2),
284    stop_node(Cp3),
285    stop_node(Cpx),
286    stop_node(Cpy),
287    stop_node(Cpz),
288
289    ?UNTIL(undefined =:= global:whereis_name(test)),
290    ok.
291
292
293
294
295%% Start a system without global groups, but syncing the nodes by using
296%% sync_nodes_optional.
297no_gg_proc_sync(Config) when is_list(Config) ->
298    Dir = proplists:get_value(priv_dir, Config),
299    File = filename:join(Dir, "no_global_group_sync.config"),
300    {ok, Fd} = file:open(File, [write]),
301
302    [Ncp1,Ncp2,Ncp3,Ncpx,Ncpy,Ncpz] =
303        node_names([cp1,cp2,cp3,cpx,cpy,cpz], Config),
304    config_sync(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz),
305
306    Cp1nn = node_at(Ncp1),
307    Cp2nn = node_at(Ncp2),
308    Cp3nn = node_at(Ncp3),
309    Cpxnn = node_at(Ncpx),
310    Cpynn = node_at(Ncpy),
311    Cpznn = node_at(Ncpz),
312
313    {ok, Cp1} = start_node_no2(Ncp1, Config),
314    {ok, Cp2} = start_node_no2(Ncp2, Config),
315    {ok, Cp3} = start_node_no2(Ncp3, Config),
316    {ok, Cpx} = start_node_no2(Ncpx, Config),
317    {ok, Cpy} = start_node_no2(Ncpy, Config),
318    {ok, Cpz} = start_node_no2(Ncpz, Config),
319
320    %% let the nodes know of each other
321    pong = rpc:call(Cp1, net_adm, ping, [Cp2nn]),
322    pong = rpc:call(Cp2, net_adm, ping, [Cp3nn]),
323    pong = rpc:call(Cp3, net_adm, ping, [Cpxnn]),
324    pong = rpc:call(Cpx, net_adm, ping, [Cpynn]),
325    pong = rpc:call(Cpy, net_adm, ping, [Cpznn]),
326
327    wait_for_ready_net(),
328
329    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}]),
330    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}]),
331    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}]),
332    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}]),
333    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}]),
334    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}]),
335
336
337    %% start a proc and register it
338    {Pid2, yes} = rpc:call(Cp2, ?MODULE, start_proc, [test2]),
339
340    RegNames = lists:sort([test2,test_server]),
341
342    RegNames =
343	lists:sort(
344	  rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}])),
345    RegNames =
346	lists:sort(
347	  rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}])),
348    RegNames =
349	lists:sort(
350	  rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}])),
351    RegNames =
352	lists:sort(
353	  rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}])),
354    RegNames =
355	lists:sort(
356	  rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}])),
357    RegNames =
358	lists:sort(
359	  rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}])),
360
361
362    undefined = rpc:call(Cp3, global_group, global_groups, []),
363
364    Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
365			Cpxnn, Cpynn, Cpznn],
366    Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
367    [] = (Own_nodes -- Own_nodes_should),
368    [] = (Own_nodes_should -- Own_nodes),
369
370    Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
371    receive
372	{pong, Cp2} -> ok
373    after
374	2000 -> ct:fail(timeout2)
375    end,
376    Pid2 = rpc:call(Cp2, global_group, send, [test2, {ping, self()}]),
377    receive
378	{pong, Cp2} -> ok
379    after
380	2000 -> ct:fail(timeout3)
381    end,
382    Pid2 = rpc:call(Cpz, global_group, send, [test2, {ping, self()}]),
383    receive
384	{pong, Cp2} -> ok
385    after
386	2000 -> ct:fail(timeout4)
387    end,
388
389
390    %% start a proc and register it
391    {PidX, yes} = rpc:call(Cpx, ?MODULE, start_proc, [test]),
392
393
394    %%------------------------------------
395    %% Test monitor nodes
396    %%------------------------------------
397    Pid2 = rpc:call(Cp1, global_group, send, [{node, Cp2nn}, test2, monitor]),
398    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, monitor]),
399
400
401    %% Kill node Cp1
402    Pid2 =
403	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cp1}]),
404    PidX =
405	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cp1}]),
406    ct:sleep(100),
407    stop_node(Cp1),
408    ct:sleep(1000),
409
410    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
411    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
412
413    %% Kill node Cpz
414    Pid2 =
415	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cpz}]),
416    PidX =
417	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cpz}]),
418    ct:sleep(100),
419    stop_node(Cpz),
420    ct:sleep(1000),
421
422    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
423    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
424
425    %% Restart node Cp1
426    Pid2 =
427	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cp1}]),
428    PidX =
429	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cp1}]),
430    {ok, Cp1} = start_node_no2(Ncp1, Config),
431    pong = rpc:call(Cp2, net_adm, ping, [Cp1nn]),
432    pong = rpc:call(Cpx, net_adm, ping, [Cp1nn]),
433    wait_for_ready_net(),
434
435    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
436    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
437
438    %% Restart node Cpz
439    Pid2 =
440	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cpz}]),
441    PidX =
442	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cpz}]),
443    {ok, Cpz} = start_node_no2(Ncpz, Config),
444    pong = rpc:call(Cp2, net_adm, ping, [Cpznn]),
445    pong = rpc:call(Cpx, net_adm, ping, [Cpznn]),
446    wait_for_ready_net(),
447
448    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
449    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
450
451    %% stop the nodes, and make sure names are released.
452    stop_node(Cp1),
453    stop_node(Cp2),
454    stop_node(Cp3),
455    stop_node(Cpx),
456    stop_node(Cpy),
457    stop_node(Cpz),
458
459    ?UNTIL(undefined =:= global:whereis_name(test)),
460    ok.
461
462
463
464
465%% Check that a system without global groups is compatible with the old R4 system.
466compatible(Config) when is_list(Config) ->
467    Dir = proplists:get_value(priv_dir, Config),
468    File = filename:join(Dir, "global_group_comp.config"),
469    {ok, Fd} = file:open(File, [write]),
470
471    [Ncp1,Ncp2,Ncp3,Ncpx,Ncpy,Ncpz] =
472        node_names([cp1,cp2,cp3,cpx,cpy,cpz], Config),
473    config_comp(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz),
474
475    Cp1nn = node_at(Ncp1),
476    Cp2nn = node_at(Ncp2),
477    Cp3nn = node_at(Ncp3),
478    Cpxnn = node_at(Ncpx),
479    Cpynn = node_at(Ncpy),
480    Cpznn = node_at(Ncpz),
481
482    {ok, Cp1} = start_node_comp(Ncp1, Config),
483    {ok, Cp2} = start_node_comp(Ncp2, Config),
484    {ok, Cp3} = start_node_comp(Ncp3, Config),
485    {ok, Cpx} = start_node_comp(Ncpx, Config),
486    {ok, Cpy} = start_node_comp(Ncpy, Config),
487    {ok, Cpz} = start_node_comp(Ncpz, Config),
488
489    %% let the nodes know of each other
490    pong = rpc:call(Cp1, net_adm, ping, [Cp2nn]),
491    pong = rpc:call(Cp2, net_adm, ping, [Cp3nn]),
492    pong = rpc:call(Cp3, net_adm, ping, [Cpxnn]),
493    pong = rpc:call(Cpx, net_adm, ping, [Cpynn]),
494    pong = rpc:call(Cpy, net_adm, ping, [Cpznn]),
495
496    wait_for_ready_net(),
497
498    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}]),
499    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}]),
500    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}]),
501    [test_server] = rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}]),
502    [test_server] = rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}]),
503    [test_server] = rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}]),
504
505
506    %% start a proc and register it
507    {Pid2, yes} = rpc:call(Cp2, ?MODULE, start_proc, [test2]),
508
509    RegNames = lists:sort([test2,test_server]),
510
511    RegNames =
512	lists:sort(
513	  rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}])),
514    RegNames =
515	lists:sort(
516	  rpc:call(Cp2, global_group, registered_names, [{node, Cp2nn}])),
517    RegNames =
518	lists:sort(
519	  rpc:call(Cp3, global_group, registered_names, [{node, Cp3nn}])),
520    RegNames =
521	lists:sort(
522	  rpc:call(Cp1, global_group, registered_names, [{node, Cpxnn}])),
523    RegNames =
524	lists:sort(
525	  rpc:call(Cp2, global_group, registered_names, [{node, Cpynn}])),
526    RegNames =
527	lists:sort(
528	  rpc:call(Cp3, global_group, registered_names, [{node, Cpznn}])),
529
530
531    undefined = rpc:call(Cp3, global_group, global_groups, []),
532
533    Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
534			Cpxnn, Cpynn, Cpznn],
535    Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
536    [] = (Own_nodes -- Own_nodes_should),
537    [] = (Own_nodes_should -- Own_nodes),
538
539    Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
540    receive
541	{pong, Cp2} -> ok
542    after
543	2000 -> ct:fail(timeout2)
544    end,
545    Pid2 = rpc:call(Cp2, global_group, send, [test2, {ping, self()}]),
546    receive
547	{pong, Cp2} -> ok
548    after
549	2000 -> ct:fail(timeout3)
550    end,
551    Pid2 = rpc:call(Cpz, global_group, send, [test2, {ping, self()}]),
552    receive
553	{pong, Cp2} -> ok
554    after
555	2000 -> ct:fail(timeout4)
556    end,
557
558
559    %% start a proc and register it
560    {PidX, yes} = rpc:call(Cpx, ?MODULE, start_proc, [test]),
561
562
563    %%------------------------------------
564    %% Test monitor nodes
565    %%------------------------------------
566    Pid2 = rpc:call(Cp1, global_group, send, [{node, Cp2nn}, test2, monitor]),
567    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, monitor]),
568
569
570    %% Kill node Cp1
571    Pid2 =
572	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cp1}]),
573    PidX =
574	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cp1}]),
575    ct:sleep(100),
576    stop_node(Cp1),
577    ct:sleep(1000),
578
579    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
580    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
581
582    %% Kill node Cpz
583    Pid2 =
584	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodedown, Cpz}]),
585    PidX =
586	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodedown, Cpz}]),
587    ct:sleep(100),
588    stop_node(Cpz),
589    ct:sleep(1000),
590
591    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
592    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
593
594    %% Restart node Cp1
595    Pid2 =
596	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cp1}]),
597    PidX =
598	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cp1}]),
599    {ok, Cp1} = start_node_comp(Ncp1, Config),
600    pong = rpc:call(Cp2, net_adm, ping, [Cp1nn]),
601    pong = rpc:call(Cpx, net_adm, ping, [Cp1nn]),
602    wait_for_ready_net(),
603
604    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
605    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
606
607    %% Restart node Cpz
608    Pid2 =
609	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, {wait_nodeup, Cpz}]),
610    PidX =
611	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, {wait_nodeup, Cpz}]),
612    {ok, Cpz} = start_node_comp(Ncpz, Config),
613    pong = rpc:call(Cp2, net_adm, ping, [Cpznn]),
614    pong = rpc:call(Cpx, net_adm, ping, [Cpznn]),
615    wait_for_ready_net(),
616
617    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
618    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
619
620    %% stop the nodes, and make sure names are released.
621    stop_node(Cp1),
622    stop_node(Cp2),
623    stop_node(Cp3),
624    stop_node(Cpx),
625    stop_node(Cpy),
626    stop_node(Cpz),
627
628    ?UNTIL(undefined =:= global:whereis_name(test)),
629    ok.
630
631
632
633
634%% Test a system with only one global group. .
635one_grp(Config) when is_list(Config) ->
636    Dir = proplists:get_value(priv_dir, Config),
637    File = filename:join(Dir, "global_group.config"),
638    {ok, Fd} = file:open(File, [write]),
639    [Ncp1,Ncp2,Ncp3] = node_names([cp1, cp2, cp3], Config),
640    config(Fd, Ncp1, Ncp2, Ncp3, "cpx", "cpy", "cpz", "cpq"),
641
642    {ok, Cp1} = start_node(Ncp1, Config),
643    {ok, Cp2} = start_node(Ncp2, Config),
644    {ok, Cp3} = start_node(Ncp3, Config),
645
646    %% sleep a while to make the global_group to sync...
647    ct:sleep(1000),
648
649    %% start a proc and register it
650    {Pid, yes} = rpc:call(Cp1, ?MODULE, start_proc, [test]),
651
652    %% test that it is registered at all nodes
653    Pid = rpc:call(Cp1, global, whereis_name, [test]),
654    Pid = rpc:call(Cp2, global, whereis_name, [test]),
655    Pid = rpc:call(Cp3, global, whereis_name, [test]),
656
657    %% try to register the same name
658    no = rpc:call(Cp1, global, register_name, [test, self()]),
659
660    %% let process exit, check that it is unregistered automatically
661    Pid ! die,
662        ?UNTIL(begin
663               (undefined =:= rpc:call(Cp1, global, whereis_name, [test])) and
664               (undefined =:= rpc:call(Cp2, global, whereis_name, [test])) and
665               (undefined =:= rpc:call(Cp3, global, whereis_name, [test]))
666           end),
667
668    %% test re_register
669    {Pid2, yes} = rpc:call(Cp1, ?MODULE, start_proc, [test]),
670    Pid2 = rpc:call(Cp3, global, whereis_name, [test]),
671    Pid3 = rpc:call(Cp3, ?MODULE, start_proc_rereg, [test]),
672    Pid3 = rpc:call(Cp3, global, whereis_name, [test]),
673
674    %% test sending
675    rpc:call(Cp1, global, send, [test, {ping, self()}]),
676    receive
677	{pong, Cp3} -> ok
678    after
679	2000 -> ct:fail(timeout1)
680    end,
681
682    rpc:call(Cp3, global, send, [test, {ping, self()}]),
683    receive
684	{pong, Cp3} -> ok
685    after
686	2000 -> ct:fail(timeout2)
687    end,
688
689    rpc:call(Cp3, global, unregister_name, [test]),
690    undefined = rpc:call(Cp1, global, whereis_name, [test]),
691    undefined = rpc:call(Cp2, global, whereis_name, [test]),
692    undefined = rpc:call(Cp3, global, whereis_name, [test]),
693
694    Pid3 ! die,
695    ?UNTIL(undefined =:= rpc:call(Cp3, global, whereis_name, [test])),
696
697    %% register a proc
698    {_, yes} = rpc:call(Cp3, ?MODULE, start_proc, [test]),
699
700    %% stop the nodes, and make sure names are released.
701    stop_node(Cp3),
702
703    ?UNTIL(undefined =:= rpc:call(Cp1, global, whereis_name, [test])),
704    Pid2 ! die,
705
706    stop_node(Cp1),
707    stop_node(Cp2),
708
709    ok.
710
711
712
713
714
715%% Check a system with only one global group.
716%% Start the nodes with different time intervals.
717one_grp_x(Config) when is_list(Config) ->
718    Dir = proplists:get_value(priv_dir, Config),
719    File = filename:join(Dir, "global_group.config"),
720    {ok, Fd} = file:open(File, [write]),
721    [Ncp1,Ncp2,Ncp3] = node_names([cp1, cp2, cp3], Config),
722    config(Fd, Ncp1, Ncp2, Ncp3, "cpx", "cpy", "cpz", "cpq"),
723
724    {ok, Cp1} = start_node(Ncp1, Config),
725    %% sleep a while to make the global_group to sync...
726    ct:sleep(1000),
727
728    %% start a proc and register it
729    {Pid, yes} = rpc:call(Cp1, ?MODULE, start_proc, [test]),
730
731    {ok, Cp2} = start_node(Ncp2, Config),
732    %% sleep a while to make the global_group to sync...
733    ct:sleep(1000),
734
735    %% test that it is registered at all nodes
736    Pid = rpc:call(Cp1, global, whereis_name, [test]),
737    Pid = rpc:call(Cp2, global, whereis_name, [test]),
738
739    {ok, Cp3} = start_node(Ncp3, Config),
740    %% sleep a while to make the global_group to sync...
741    ct:sleep(1000),
742
743    Pid = rpc:call(Cp3, global, whereis_name, [test]),
744
745    %% try to register the same name
746    no = rpc:call(Cp1, global, register_name, [test, self()]),
747
748    %% let process exit, check that it is unregistered automatically
749    Pid ! die,
750        ?UNTIL(begin
751               (undefined =:= rpc:call(Cp1, global, whereis_name, [test])) and
752               (undefined =:= rpc:call(Cp2, global, whereis_name, [test])) and
753               (undefined =:= rpc:call(Cp3, global, whereis_name, [test]))
754           end),
755
756    %% test re_register
757    {Pid2, yes} = rpc:call(Cp1, ?MODULE, start_proc, [test]),
758    Pid2 = rpc:call(Cp3, global, whereis_name, [test]),
759
760    Pid2 ! die,
761
762    stop_node(Cp1),
763    stop_node(Cp2),
764    stop_node(Cp3),
765
766    ok.
767
768
769
770
771
772
773%% Test a two global group system. .
774two_grp(Config) when is_list(Config) ->
775    Dir = proplists:get_value(priv_dir, Config),
776    File = filename:join(Dir, "global_group.config"),
777    {ok, Fd} = file:open(File, [write]),
778
779    [Ncp1,Ncp2,Ncp3,Ncpx,Ncpy,Ncpz,Ncpq] =
780        node_names([cp1,cp2,cp3,cpx,cpy,cpz,cpq], Config),
781    config(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz, Ncpq),
782
783    Cp1nn = node_at(Ncp1),
784    Cp2nn = node_at(Ncp2),
785    Cp3nn = node_at(Ncp3),
786    Cpxnn = node_at(Ncpx),
787    Cpynn = node_at(Ncpy),
788    Cpznn = node_at(Ncpz),
789
790    {ok, Cp1} = start_node(Ncp1, Config),
791    {ok, Cp2} = start_node(Ncp2, Config),
792    {ok, Cp3} = start_node(Ncp3, Config),
793    {ok, Cpx} = start_node(Ncpx, Config),
794    {ok, Cpy} = start_node(Ncpy, Config),
795    {ok, Cpz} = start_node(Ncpz, Config),
796
797    %% The groups (cpq not started):
798    %% [{nc1, [cp1,cp2,cp3]}, {nc2, [cpx,cpy,cpz]}, {nc3, [cpq]}]
799
800    %% sleep a while to make the global_groups to sync...
801    ct:sleep(1000),
802
803    %% check the global group names
804    {nc1, [nc2, nc3]} = rpc:call(Cp1, global_group, global_groups, []),
805    {nc1, [nc2, nc3]} = rpc:call(Cp2, global_group, global_groups, []),
806    {nc1, [nc2, nc3]} = rpc:call(Cp3, global_group, global_groups, []),
807    {nc2, [nc1, nc3]} = rpc:call(Cpx, global_group, global_groups, []),
808    {nc2, [nc1, nc3]} = rpc:call(Cpy, global_group, global_groups, []),
809    {nc2, [nc1, nc3]} = rpc:call(Cpz, global_group, global_groups, []),
810
811    %% check the global group nodes
812    [Cp1nn, Cp2nn, Cp3nn] = rpc:call(Cp1, global_group, own_nodes, []),
813    [Cp1nn, Cp2nn, Cp3nn] = rpc:call(Cp2, global_group, own_nodes, []),
814    [Cp1nn, Cp2nn, Cp3nn] = rpc:call(Cp3, global_group, own_nodes, []),
815    [Cpxnn, Cpynn, Cpznn] = rpc:call(Cpx, global_group, own_nodes, []),
816    [Cpxnn, Cpynn, Cpznn] = rpc:call(Cpy, global_group, own_nodes, []),
817    [Cpxnn, Cpynn, Cpznn] = rpc:call(Cpz, global_group, own_nodes, []),
818
819
820    %% start a proc and register it
821    {Pid1, yes} = rpc:call(Cp1, ?MODULE, start_proc, [test]),
822
823    Pid1 = rpc:call(Cp1, global_group, send, [test, {io, from_cp1}]),
824    Pid1 = rpc:call(Cpx, global_group, send, [test, {io, from_cpx}]),
825    Pid1 = rpc:call(Cp1, global_group, send, [{group,nc1}, test,
826					      {io, from_cp1}]),
827    [test] =
828        rpc:call(Cpx, global_group, registered_names, [{node, Cp1nn}]),
829    [test] =
830        rpc:call(Cpx, global_group, registered_names, [{group, nc1}]),
831    [] = rpc:call(Cpx, global_group, registered_names, [{node, Cpxnn}]),
832    [] = rpc:call(Cpx, global_group, registered_names, [{group, nc2}]),
833    Pid1 = rpc:call(Cpx, global_group, send, [{group,nc1}, test,
834					      {io, from_cp1}]),
835    {badarg,{test,{io,from_cpx}}} =
836	rpc:call(Cp1, global_group, send, [{group,nc2}, test, {io, from_cpx}]),
837    {badarg,{test,{io,from_cpx}}} =
838	rpc:call(Cpx, global_group, send, [{group,nc2}, test, {io, from_cpx}]),
839
840
841
842    %% test that it is registered at all nodes
843    Pid1 = rpc:call(Cp1, global, whereis_name, [test]),
844    Pid1 = rpc:call(Cp2, global, whereis_name, [test]),
845    Pid1 = rpc:call(Cp3, global, whereis_name, [test]),
846    undefined = rpc:call(Cpx, global, whereis_name, [test]),
847    undefined = rpc:call(Cpy, global, whereis_name, [test]),
848    undefined = rpc:call(Cpz, global, whereis_name, [test]),
849
850    %% start a proc and register it
851    {PidX, yes} = rpc:call(Cpx, ?MODULE, start_proc, [test]),
852
853    %% test that it is registered at all nodes
854    Pid1 = rpc:call(Cp1, global, whereis_name, [test]),
855    Pid1 = rpc:call(Cp2, global, whereis_name, [test]),
856    Pid1 = rpc:call(Cp3, global, whereis_name, [test]),
857    PidX = rpc:call(Cpx, global, whereis_name, [test]),
858    PidX = rpc:call(Cpy, global, whereis_name, [test]),
859    PidX = rpc:call(Cpz, global, whereis_name, [test]),
860
861    Pid1 ! die,
862    %% If we don't wait for global on other nodes to have updated its
863    %% tables, 'test' may still be defined at the point when it is
864    %% tested a few lines below.
865    ?UNTIL(begin
866               Pid = rpc:call(Cp2, global, whereis_name, [test]),
867               undefined =:= Pid
868           end),
869
870    %% start a proc and register it
871    {Pid2, yes} = rpc:call(Cp2, ?MODULE, start_proc, [test2]),
872
873    %% test that it is registered at all nodes
874    Pid2 = rpc:call(Cp1, global, whereis_name, [test2]),
875    Pid2 = rpc:call(Cp2, global, whereis_name, [test2]),
876    Pid2 = rpc:call(Cp3, global, whereis_name, [test2]),
877    PidX = rpc:call(Cpx, global, whereis_name, [test]),
878    PidX = rpc:call(Cpy, global, whereis_name, [test]),
879    PidX = rpc:call(Cpz, global, whereis_name, [test]),
880
881    undefined = rpc:call(Cp1, global, whereis_name, [test]),
882    undefined = rpc:call(Cp2, global, whereis_name, [test]),
883    undefined = rpc:call(Cp3, global, whereis_name, [test]),
884    undefined = rpc:call(Cpx, global, whereis_name, [test2]),
885    undefined = rpc:call(Cpy, global, whereis_name, [test2]),
886    undefined = rpc:call(Cpz, global, whereis_name, [test2]),
887
888
889    Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
890    receive
891	{pong, Cp2} -> ok
892    after
893	2000 -> ct:fail(timeout2)
894    end,
895    Pid2 = rpc:call(Cp2, global_group, send, [test2, {ping, self()}]),
896    receive
897	{pong, Cp2} -> ok
898    after
899	2000 -> ct:fail(timeout2)
900    end,
901    Pid2 = rpc:call(Cp3, global_group, send, [test2, {ping, self()}]),
902    receive
903	{pong, Cp2} -> ok
904    after
905	2000 -> ct:fail(timeout2)
906    end,
907
908    PidX = rpc:call(Cpx, global_group, send, [test, {ping, self()}]),
909    receive
910	{pong, Cpx} -> ok
911    after
912	2000 -> ct:fail(timeout2)
913    end,
914    PidX = rpc:call(Cpy, global_group, send, [test, {ping, self()}]),
915    receive
916	{pong, Cpx} -> ok
917    after
918	2000 -> ct:fail(timeout2)
919    end,
920    PidX = rpc:call(Cpz, global_group, send, [test, {ping, self()}]),
921    receive
922	{pong, Cpx} -> ok
923    after
924	2000 -> ct:fail(timeout2)
925    end,
926
927    Pid2 = rpc:call(Cpx, global_group, send, [{node, Cp1nn}, test2,
928					      {ping, self()}]),
929    receive
930	{pong, Cp2} -> ok
931    after
932	2000 -> ct:fail(timeout2)
933    end,
934    Pid2 = rpc:call(Cpy, global_group, send, [{node, Cp2nn}, test2,
935					      {ping, self()}]),
936    receive
937	{pong, Cp2} -> ok
938    after
939	2000 -> ct:fail(timeout2)
940    end,
941    Pid2 = rpc:call(Cpz, global_group, send, [{node, Cp3nn}, test2,
942					      {ping, self()}]),
943    receive
944	{pong, Cp2} -> ok
945    after
946	2000 -> ct:fail(timeout2)
947    end,
948
949    PidX = rpc:call(Cpx, global_group, send, [{node, Cpznn}, test,
950					      {ping, self()}]),
951    receive
952	{pong, Cpx} -> ok
953    after
954	2000 -> ct:fail(timeout2)
955    end,
956    PidX = rpc:call(Cpy, global_group, send, [{node, Cpxnn}, test,
957					      {ping, self()}]),
958    receive
959	{pong, Cpx} -> ok
960    after
961	2000 -> ct:fail(timeout2)
962    end,
963    PidX = rpc:call(Cpz, global_group, send, [{node, Cpynn}, test,
964					      {ping, self()}]),
965    receive
966	{pong, Cpx} -> ok
967    after
968	2000 -> ct:fail(timeout2)
969    end,
970
971    Pid2 = rpc:call(Cpx, global_group, send, [{group, nc1}, test2,
972					      {ping, self()}]),
973    receive
974	{pong, Cp2} -> ok
975    after
976	2000 -> ct:fail(timeout2)
977    end,
978    PidX = rpc:call(Cpy, global_group, send, [{group, nc2}, test,
979					      {ping, self()}]),
980    receive
981	{pong, Cpx} -> ok
982    after
983	2000 -> ct:fail(timeout2)
984    end,
985
986    %%------------------------------------
987    %% Test monitor nodes
988    %%------------------------------------
989    Pid2 =
990        rpc:call(Cp1, global_group, send, [{node, Cp2nn}, test2, monitor]),
991    PidX =
992        rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, monitor]),
993
994
995    %% Kill node Cp1
996    Pid2 = rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2,
997					      {wait_nodedown, Cp1}]),
998    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test,
999					      {wait_nodedown, Cp1}]),
1000    ct:sleep(100),
1001    stop_node(Cp1),
1002    ct:sleep(1000),
1003
1004    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
1005    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop_nodedown),
1006    PidX =
1007	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, to_loop]),
1008
1009    %% Kill node Cpz
1010    Pid2 = rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2,
1011					      {wait_nodedown, Cpz}]),
1012    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test,
1013					      {wait_nodedown, Cpz}]),
1014    ct:sleep(100),
1015    stop_node(Cpz),
1016    ct:sleep(1000),
1017
1018    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop_nodedown),
1019    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
1020    Pid2 =
1021	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, to_loop]),
1022
1023    %% Restart node Cp1
1024    [Cp1nn, Cp2nn, Cp3nn] = rpc:call(Cp2, global_group, own_nodes, []),
1025    Pid2 = rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2,
1026					      {wait_nodeup, Cp1}]),
1027    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test,
1028					      {wait_nodeup, Cp1}]),
1029    ct:sleep(100),
1030    {ok, Cp1} = start_node(Ncp1, Config),
1031    ct:sleep(5000),
1032
1033    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop),
1034    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop_nodeup),
1035    PidX =
1036	rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test, to_loop]),
1037
1038
1039    %% Restart node Cpz
1040    Pid2 = rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2,
1041					      {wait_nodeup, Cpz}]),
1042    PidX = rpc:call(Cpx, global_group, send, [{node, Cpxnn}, test,
1043					      {wait_nodeup, Cpz}]),
1044    ct:sleep(100),
1045    {ok, Cpz} = start_node(Ncpz, Config),
1046    ct:sleep(5000),
1047
1048    ok = assert_loop(Cp2, Cp2nn, test2, Pid2, loop_nodeup),
1049    ok = assert_loop(Cpx, Cpxnn, test, PidX, loop),
1050    Pid2 =
1051	rpc:call(Cp2, global_group, send, [{node, Cp2nn}, test2, to_loop]),
1052
1053
1054    Pid2 ! die,
1055    PidX ! die,
1056
1057    stop_node(Cp1),
1058    stop_node(Cp2),
1059    stop_node(Cp3),
1060    stop_node(Cpx),
1061    stop_node(Cpy),
1062    stop_node(Cpz),
1063
1064    ok.
1065
1066
1067
1068%% Test hidden global groups.
1069hidden_groups(Config) when is_list(Config) ->
1070    Dir = proplists:get_value(priv_dir, Config),
1071    File = filename:join(Dir, "global_group.config"),
1072    {ok, Fd} = file:open(File, [write]),
1073
1074    [Ncp1,Ncp2,Ncp3,Ncpx,Ncpy,Ncpz,Ncpq] =
1075        node_names([cp1,cp2,cp3,cpx,cpy,cpz,cpq], Config),
1076    config_hidden(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz, Ncpq),
1077
1078    {ok, Cp1} = start_node(Ncp1, Config),
1079    {ok, Cp2} = start_node(Ncp2, Config),
1080    {ok, Cp3} = start_node(Ncp3, Config),
1081    {ok, Cpx} = start_node(Ncpx, Config),
1082    {ok, Cpy} = start_node(Ncpy, Config),
1083    {ok, Cpz} = start_node(Ncpz, Config),
1084    {ok, Cpq} = start_node(Ncpq, Config),
1085
1086    %% sleep a while to make the global_groups to sync...
1087    ct:sleep(1000),
1088
1089    %% check the global group names
1090    {nc1, [nc2, nc3]} = rpc:call(Cp1, global_group, global_groups, []),
1091    {nc1, [nc2, nc3]} = rpc:call(Cp2, global_group, global_groups, []),
1092    {nc1, [nc2, nc3]} = rpc:call(Cp3, global_group, global_groups, []),
1093    {nc2, [nc1, nc3]} = rpc:call(Cpx, global_group, global_groups, []),
1094    {nc2, [nc1, nc3]} = rpc:call(Cpy, global_group, global_groups, []),
1095    {nc2, [nc1, nc3]} = rpc:call(Cpz, global_group, global_groups, []),
1096
1097    %% check the global group nodes
1098    [Cp1, Cp2, Cp3] = rpc:call(Cp1, global_group, own_nodes, []),
1099    [Cp1, Cp2, Cp3] = rpc:call(Cp2, global_group, own_nodes, []),
1100    [Cp1, Cp2, Cp3] = rpc:call(Cp3, global_group, own_nodes, []),
1101    [Cpx, Cpy, Cpz] = rpc:call(Cpx, global_group, own_nodes, []),
1102    [Cpx, Cpy, Cpz] = rpc:call(Cpy, global_group, own_nodes, []),
1103    [Cpx, Cpy, Cpz] = rpc:call(Cpz, global_group, own_nodes, []),
1104    [Cpq]           = rpc:call(Cpq, global_group, own_nodes, []),
1105
1106    %% Make some inter group connections
1107    pong = rpc:call(Cp1, net_adm, ping, [Cpx]),
1108    pong = rpc:call(Cpy, net_adm, ping, [Cp2]),
1109    pong = rpc:call(Cp3, net_adm, ping, [Cpx]),
1110    pong = rpc:call(Cpz, net_adm, ping, [Cp3]),
1111    pong = rpc:call(Cpq, net_adm, ping, [Cp1]),
1112    pong = rpc:call(Cpz, net_adm, ping, [Cpq]),
1113
1114    %% Check that no inter group connections are visible
1115    NC1Nodes = lists:sort([Cp1, Cp2, Cp3]),
1116    NC2Nodes = lists:sort([Cpx, Cpy, Cpz]),
1117    NC1Nodes = lists:sort([Cp1|rpc:call(Cp1, erlang, nodes, [])]),
1118    NC1Nodes = lists:sort([Cp2|rpc:call(Cp2, erlang, nodes, [])]),
1119    NC1Nodes = lists:sort([Cp3|rpc:call(Cp3, erlang, nodes, [])]),
1120    NC2Nodes = lists:sort([Cpx|rpc:call(Cpx, erlang, nodes, [])]),
1121    NC2Nodes = lists:sort([Cpy|rpc:call(Cpy, erlang, nodes, [])]),
1122    NC2Nodes = lists:sort([Cpz|rpc:call(Cpz, erlang, nodes, [])]),
1123    NC12Nodes = lists:append(NC1Nodes, NC2Nodes),
1124    false = lists:any(fun(N) -> lists:member(N, NC12Nodes) end,
1125		      rpc:call(Cpq, erlang, nodes, [])),
1126
1127
1128    stop_node(Cp1),
1129    stop_node(Cp2),
1130    stop_node(Cp3),
1131    stop_node(Cpx),
1132    stop_node(Cpy),
1133    stop_node(Cpz),
1134    stop_node(Cpq),
1135
1136    ok.
1137
1138
1139%% Checks when the search process exits. .
1140test_exit(Config) when is_list(Config) ->
1141    NN = node_name(atom_to_list(node())),
1142    Cp1nn = list_to_atom("cp1@" ++ NN),
1143
1144    {ok, Cp1} = start_node(cp1, Config),
1145    {ok, Cp2} = start_node(cp2, Config),
1146    {ok, Cp3} = start_node(cp3, Config),
1147
1148    ct:sleep(1000),
1149
1150    {error, illegal_function_call} =
1151        rpc:call(Cp1, global_group, registered_names_test, [{node, Cp1nn}]),
1152    {badarg,_} =
1153        rpc:call(Cp1, global_group, send, [king, "The message"]),
1154    undefined = rpc:call(Cp1, global_group, whereis_name, [king]),
1155
1156    % make sure the search process really exits after every global_group operations
1157    ProcessCount0 = rpc:call(Cp1, erlang, system_info, [process_count]),
1158    _ = rpc:call(Cp1, global_group, whereis_name, [{node, Cp1nn}, whatever_pid_name]),
1159    ProcessCount1 = rpc:call(Cp1, erlang, system_info, [process_count]),
1160    _ = rpc:call(Cp1, global_group, registered_names, [{node, Cp1nn}]),
1161    ProcessCount2 = rpc:call(Cp1, erlang, system_info, [process_count]),
1162    _ = rpc:call(Cp1, global_group, send, [{node, Cp1nn}, whatever_pid_name, msg]),
1163    ProcessCount3 = rpc:call(Cp1, erlang, system_info, [process_count]),
1164    ProcessCount0 = ProcessCount1 = ProcessCount2 = ProcessCount3,
1165
1166    %% stop the nodes, and make sure names are released.
1167    stop_node(Cp1),
1168    stop_node(Cp2),
1169    stop_node(Cp3),
1170
1171    %% sleep to let the nodes die
1172    ct:sleep(1000),
1173
1174    ok.
1175
1176
1177start_node(Name, Config) ->
1178    Pa=filename:dirname(code:which(?MODULE)),
1179    Dir=proplists:get_value(priv_dir, Config),
1180    ConfFile = "  -config " ++ filename:join(Dir, "global_group"),
1181    test_server:start_node(Name, slave, [{args, "-pa " ++ Pa ++ ConfFile}]).
1182
1183start_node_no(Name, Config) ->
1184    Pa=filename:dirname(code:which(?MODULE)),
1185    Dir=proplists:get_value(priv_dir, Config),
1186    ConfFile = "  -config " ++ filename:join(Dir, "no_global_group"),
1187    test_server:start_node(Name, slave, [{args, "-pa " ++ Pa ++ ConfFile}]).
1188
1189start_node_no2(Name, Config) ->
1190    Pa=filename:dirname(code:which(?MODULE)),
1191    Dir=proplists:get_value(priv_dir, Config),
1192    ConfFile = "  -config " ++ filename:join(Dir, "no_global_group_sync"),
1193    test_server:start_node(Name, slave, [{args, "-pa " ++ Pa ++ ConfFile}]).
1194
1195start_node_comp(Name, Config) ->
1196    Pa=filename:dirname(code:which(?MODULE)),
1197    Dir=proplists:get_value(priv_dir, Config),
1198    ConfFile = "  -config " ++ filename:join(Dir, "global_group_comp"),
1199    test_server:start_node(Name, slave, [{args, "-pa " ++ Pa ++ ConfFile}]).
1200
1201node_names(Names, Config) ->
1202    [node_name(Name, Config) || Name <- Names].
1203
1204node_name(Name, Config) ->
1205    U = "_",
1206    Pid = os:getpid(),
1207    {{Y,M,D}, {H,Min,S}} = calendar:now_to_local_time(now()),
1208    Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w",
1209                         [Y,M,D, H,Min,S]),
1210    L = lists:flatten(Date),
1211    lists:concat([Name,U,?testcase,U,Pid,U,U,L]).
1212
1213stop_node(Node) ->
1214    test_server:stop_node(Node).
1215
1216
1217wait_for_ready_net() ->
1218    Nodes = lists:sort(?NODES),
1219    ?UNTIL(begin
1220               lists:all(fun(N) -> Nodes =:= get_known(N) end, Nodes) and
1221		   lists:all(fun(N) ->
1222				     LNs = rpc:call(N, erlang, nodes, []),
1223				     Nodes =:= lists:sort([N | LNs])
1224			     end, Nodes)
1225           end).
1226
1227get_known(Node) ->
1228    Known = gen_server:call({global_name_server,Node}, get_known),
1229    lists:sort([Node | Known]).
1230
1231config_hidden(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz, Ncpq) ->
1232    M = from($@, atom_to_list(node())),
1233    io:format(Fd, "[{kernel, [{sync_nodes_optional, ['~s@~s','~s@~s','~s@~s', "
1234	      " '~s@~s','~s@~s','~s@~s']},"
1235	      "{sync_nodes_timeout, 1000},"
1236	      "{global_groups, [{nc1, hidden, ['~s@~s','~s@~s','~s@~s']}, "
1237	      "{nc2, hidden, ['~s@~s','~s@~s','~s@~s']}, "
1238	      "{nc3, normal, ['~s@~s']}]} ] }]. ~n",
1239	      [Ncp1, M, Ncp2, M, Ncp3, M,
1240               Ncpx, M, Ncpy, M, Ncpz, M,
1241               Ncp1, M, Ncp2, M, Ncp3, M,
1242               Ncpx, M, Ncpy, M, Ncpz, M,
1243               Ncpq, M]).
1244
1245config(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz, Ncpq) ->
1246    M = from($@, atom_to_list(node())),
1247    io:format(Fd, "[{kernel, [{sync_nodes_optional, ['~s@~s','~s@~s','~s@~s', "
1248	      " '~s@~s','~s@~s','~s@~s']},"
1249	      "{sync_nodes_timeout, 1000},"
1250	      "{global_groups, [{nc1, ['~s@~s','~s@~s','~s@~s']}, "
1251	      " {nc2, ['~s@~s','~s@~s','~s@~s']}, "
1252	      "{nc3, ['~s@~s']}]} ] }]. ~n",
1253	      [Ncp1, M, Ncp2, M, Ncp3, M,
1254               Ncpx, M, Ncpy, M, Ncpz, M,
1255               Ncp1, M, Ncp2, M, Ncp3, M,
1256               Ncpx, M, Ncpy, M, Ncpz, M,
1257               Ncpq, M]).
1258
1259config_no(Fd) ->
1260    io:format(Fd, "[{kernel, [{global_groups, []}]}]. ~n",[]).
1261
1262config_sync(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz) ->
1263    M = from($@, atom_to_list(node())),
1264    io:format(Fd, "[{kernel, [{sync_nodes_optional, ['~s@~s','~s@~s','~s@~s', "
1265	      " '~s@~s','~s@~s','~s@~s']},"
1266	      "{sync_nodes_timeout, 1000},"
1267	      "{global_groups, []} ] }] .~n",
1268	      [Ncp1, M, Ncp2, M, Ncp3, M,
1269               Ncpx, M, Ncpy, M, Ncpz, M]).
1270
1271
1272config_comp(Fd, Ncp1, Ncp2, Ncp3, Ncpx, Ncpy, Ncpz) ->
1273    M = from($@, atom_to_list(node())),
1274    io:format(Fd, "[{kernel, [{sync_nodes_optional, ['~s@~s','~s@~s','~s@~s', "
1275	      " '~s@~s','~s@~s','~s@~s']},"
1276	      "{sync_nodes_timeout, 1000} ] }] .~n",
1277	      [Ncp1, M, Ncp2, M, Ncp3, M,
1278               Ncpx, M, Ncpy, M, Ncpz, M]).
1279
1280node_at(N) ->
1281    NN = node_name(atom_to_list(node())),
1282    list_to_atom(lists:concat([N, "@", NN])).
1283
1284node_name(L) ->
1285    from($@, L).
1286
1287from(H, [H | T]) -> T;
1288from(H, [_ | T]) -> from(H, T);
1289from(_, []) -> [].
1290
1291
1292start_proc(Name) ->
1293    Pid = spawn(?MODULE, init, [self(), Name]),
1294    receive
1295	{Pid, Res} -> {Pid, Res}
1296    end.
1297
1298start_proc_rereg(Name) ->
1299    Pid = spawn(?MODULE, init2, [self(), Name]),
1300    receive
1301	Pid -> Pid
1302    end.
1303
1304
1305
1306
1307
1308
1309
1310init(Parent) ->
1311    Parent ! self(),
1312    loop().
1313
1314init(Parent, Name) ->
1315    X = global:register_name(Name, self()),
1316    Parent ! {self(),X},
1317    loop().
1318
1319init2(Parent, Name) ->
1320    global:re_register_name(Name, self()),
1321    Parent ! self(),
1322    loop().
1323
1324loop() ->
1325    receive
1326	monitor ->
1327	    global_group:monitor_nodes(true),
1328	    loop();
1329	stop_monitor ->
1330	    global_group:monitor_nodes(false),
1331	    loop();
1332	{wait_nodeup, Node} ->
1333	    loop_nodeup(Node);
1334	{wait_nodedown, Node} ->
1335	    loop_nodedown(Node);
1336	{io, _Msg} ->
1337	    loop();
1338	{ping, From} ->
1339	    From ! {pong, node()},
1340	    loop();
1341	{del_lock, Id} ->
1342	    global:del_lock({Id, self()}),
1343	    loop();
1344	{del_lock, Id, Nodes} ->
1345	    global:del_lock({Id, self()}, Nodes),
1346	    loop();
1347	{set_lock, Id, From} ->
1348	    Res = global:set_lock({Id, self()}, ?NODES, 1),
1349	    From ! Res,
1350	    loop();
1351	{set_lock, Id, From, Nodes} ->
1352	    Res = global:set_lock({Id, self()}, Nodes, 1),
1353	    From ! Res,
1354	    loop();
1355	{set_lock_loop, Id, From} ->
1356	    global:set_lock({Id, self()}, ?NODES),
1357	    From ! {got_lock, self()},
1358	    loop();
1359	{{got_notify, From}, Ref} ->
1360	    receive
1361		X when element(1, X) == global_name_conflict ->
1362		    From ! {Ref, yes}
1363	    after
1364		0 -> From ! {Ref, no}
1365	    end,
1366	    loop();
1367	{which_loop, From} ->
1368	    From ! loop,
1369	    loop();
1370	die ->
1371	    exit(normal)
1372    end.
1373
1374
1375loop_nodeup(Node) ->
1376    receive
1377	{nodeup, Node} ->
1378	    loop();
1379	to_loop ->
1380	    loop();
1381	{which_loop, From} ->
1382	    From ! loop_nodeup,
1383	    loop_nodeup(Node);
1384	die ->
1385	    exit(normal)
1386    end.
1387
1388
1389loop_nodedown(Node) ->
1390    receive
1391	{nodedown, Node} ->
1392	    loop();
1393	to_loop ->
1394	    loop();
1395	{which_loop, From} ->
1396	    From ! loop_nodedown,
1397	    loop_nodedown(Node);
1398	die ->
1399	    exit(normal)
1400    end.
1401
1402assert_loop(Cp, CpName, Name, NamePid, Loop) ->
1403    M = {which_loop, self()},
1404    NamePid = rpc:call(Cp, global_group, send, [{node, CpName}, Name, M]),
1405    receive
1406        Loop ->
1407            ok;
1408        Other1 ->
1409            ct:fail(Other1)
1410    after 5000 ->
1411            ct:fail(timeout)
1412    end.
1413
1414loop_until_true(Fun) ->
1415    case Fun() of
1416	true ->
1417	    ok;
1418	_ ->
1419	    loop_until_true(Fun)
1420    end.
1421
1422