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