syn_registry_SUITE.erl 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. %% ==========================================================================================================
  2. %% Syn - A global Process Registry and Process Group manager.
  3. %%
  4. %% The MIT License (MIT)
  5. %%
  6. %% Copyright (c) 2015-2021 Roberto Ostinelli <roberto@ostinelli.net> and Neato Robotics, Inc.
  7. %%
  8. %% Permission is hereby granted, free of charge, to any person obtaining a copy
  9. %% of this software and associated documentation files (the "Software"), to deal
  10. %% in the Software without restriction, including without limitation the rights
  11. %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. %% copies of the Software, and to permit persons to whom the Software is
  13. %% furnished to do so, subject to the following conditions:
  14. %%
  15. %% The above copyright notice and this permission notice shall be included in
  16. %% all copies or substantial portions of the Software.
  17. %%
  18. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. %% THE SOFTWARE.
  25. %% ==========================================================================================================
  26. -module(syn_registry_SUITE).
  27. %% callbacks
  28. -export([all/0]).
  29. -export([init_per_suite/1, end_per_suite/1]).
  30. -export([groups/0, init_per_group/2, end_per_group/2]).
  31. -export([init_per_testcase/2, end_per_testcase/2]).
  32. %% tests
  33. -export([
  34. three_nodes_discover_default_scope/1,
  35. three_nodes_discover_custom_scope/1,
  36. three_nodes_register_unregister_and_monitor_default_scope/1,
  37. three_nodes_register_unregister_and_monitor_custom_scope/1,
  38. three_nodes_cluster_changes/1,
  39. three_nodes_cluster_conflicts/1,
  40. three_nodes_custom_event_handler_reg_unreg/1
  41. ]).
  42. %% include
  43. -include_lib("common_test/include/ct.hrl").
  44. -include_lib("syn/src/syn.hrl").
  45. %% ===================================================================
  46. %% Callbacks
  47. %% ===================================================================
  48. %% -------------------------------------------------------------------
  49. %% Function: all() -> GroupsAndTestCases | {skip,Reason}
  50. %% GroupsAndTestCases = [{group,GroupName} | TestCase]
  51. %% GroupName = atom()
  52. %% TestCase = atom()
  53. %% Reason = any()
  54. %% -------------------------------------------------------------------
  55. all() ->
  56. [
  57. {group, three_nodes_process_registration}
  58. ].
  59. %% -------------------------------------------------------------------
  60. %% Function: groups() -> [Group]
  61. %% Group = {GroupName,Properties,GroupsAndTestCases}
  62. %% GroupName = atom()
  63. %% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
  64. %% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
  65. %% TestCase = atom()
  66. %% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
  67. %% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
  68. %% repeat_until_any_ok | repeat_until_any_fail
  69. %% N = integer() | forever
  70. %% -------------------------------------------------------------------
  71. groups() ->
  72. [
  73. {three_nodes_process_registration, [shuffle], [
  74. three_nodes_discover_default_scope,
  75. three_nodes_discover_custom_scope,
  76. three_nodes_register_unregister_and_monitor_default_scope,
  77. three_nodes_register_unregister_and_monitor_custom_scope,
  78. three_nodes_cluster_changes,
  79. three_nodes_cluster_conflicts,
  80. three_nodes_custom_event_handler_reg_unreg
  81. ]}
  82. ].
  83. %% -------------------------------------------------------------------
  84. %% Function: init_per_suite(Config0) ->
  85. %% Config1 | {skip,Reason} |
  86. %% {skip_and_save,Reason,Config1}
  87. %% Config0 = Config1 = [tuple()]
  88. %% Reason = any()
  89. %% -------------------------------------------------------------------
  90. init_per_suite(Config) ->
  91. Config.
  92. %% -------------------------------------------------------------------
  93. %% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
  94. %% Config0 = Config1 = [tuple()]
  95. %% -------------------------------------------------------------------
  96. end_per_suite(_Config) ->
  97. ok.
  98. %% -------------------------------------------------------------------
  99. %% Function: init_per_group(GroupName, Config0) ->
  100. %% Config1 | {skip,Reason} |
  101. %% {skip_and_save,Reason,Config1}
  102. %% GroupName = atom()
  103. %% Config0 = Config1 = [tuple()]
  104. %% Reason = any()
  105. %% -------------------------------------------------------------------
  106. init_per_group(three_nodes_process_registration, Config) ->
  107. %% start slave
  108. {ok, SlaveNode1} = syn_test_suite_helper:start_slave(syn_slave_1),
  109. {ok, SlaveNode2} = syn_test_suite_helper:start_slave(syn_slave_2),
  110. syn_test_suite_helper:connect_node(SlaveNode1),
  111. syn_test_suite_helper:connect_node(SlaveNode2),
  112. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  113. %% wait full cluster
  114. case syn_test_suite_helper:wait_cluster_mesh_connected([node(), SlaveNode1, SlaveNode2]) of
  115. ok ->
  116. %% config
  117. [{slave_node_1, SlaveNode1}, {slave_node_2, SlaveNode2} | Config];
  118. Other ->
  119. ct:pal("*********** Could not get full cluster, skipping"),
  120. end_per_group(three_nodes_process_registration, Config),
  121. {skip, Other}
  122. end;
  123. init_per_group(_GroupName, Config) ->
  124. Config.
  125. %% -------------------------------------------------------------------
  126. %% Function: end_per_group(GroupName, Config0) ->
  127. %% void() | {save_config,Config1}
  128. %% GroupName = atom()
  129. %% Config0 = Config1 = [tuple()]
  130. %% -------------------------------------------------------------------
  131. end_per_group(three_nodes_process_registration, Config) ->
  132. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  133. syn_test_suite_helper:connect_node(SlaveNode1),
  134. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  135. syn_test_suite_helper:connect_node(SlaveNode2),
  136. syn_test_suite_helper:clean_after_test(),
  137. syn_test_suite_helper:stop_slave(syn_slave_1),
  138. syn_test_suite_helper:stop_slave(syn_slave_2),
  139. timer:sleep(1000);
  140. end_per_group(_GroupName, _Config) ->
  141. syn_test_suite_helper:clean_after_test().
  142. %% -------------------------------------------------------------------
  143. %% Function: init_per_testcase(TestCase, Config0) ->
  144. %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
  145. %% TestCase = atom()
  146. %% Config0 = Config1 = [tuple()]
  147. %% Reason = any()
  148. %% -------------------------------------------------------------------
  149. init_per_testcase(TestCase, Config) ->
  150. ct:pal("Starting test: ~p", [TestCase]),
  151. Config.
  152. %% -------------------------------------------------------------------
  153. %% Function: end_per_testcase(TestCase, Config0) ->
  154. %% void() | {save_config,Config1} | {fail,Reason}
  155. %% TestCase = atom()
  156. %% Config0 = Config1 = [tuple()]
  157. %% Reason = any()
  158. %% -------------------------------------------------------------------
  159. end_per_testcase(_, _Config) ->
  160. syn_test_suite_helper:clean_after_test().
  161. %% ===================================================================
  162. %% Tests
  163. %% ===================================================================
  164. three_nodes_discover_default_scope(Config) ->
  165. %% get slaves
  166. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  167. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  168. %% start syn on nodes
  169. ok = syn:start(),
  170. ok = rpc:call(SlaveNode1, syn, start, []),
  171. ok = rpc:call(SlaveNode2, syn, start, []),
  172. %% check
  173. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  174. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  175. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]),
  176. %% simulate full netsplit
  177. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  178. syn_test_suite_helper:disconnect_node(SlaveNode1),
  179. syn_test_suite_helper:disconnect_node(SlaveNode2),
  180. syn_test_suite_helper:assert_cluster(node(), []),
  181. %% check
  182. syn_test_suite_helper:assert_scope_subcluster(node(), default, []),
  183. %% reconnect slave 1
  184. syn_test_suite_helper:connect_node(SlaveNode1),
  185. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1]),
  186. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  187. %% check
  188. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1]),
  189. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node()]),
  190. %% reconnect all
  191. syn_test_suite_helper:connect_node(SlaveNode2),
  192. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  193. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  194. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  195. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  196. %% check
  197. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  198. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  199. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]),
  200. %% simulate full netsplit, again
  201. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  202. syn_test_suite_helper:disconnect_node(SlaveNode1),
  203. syn_test_suite_helper:disconnect_node(SlaveNode2),
  204. syn_test_suite_helper:assert_cluster(node(), []),
  205. %% check
  206. syn_test_suite_helper:assert_scope_subcluster(node(), default, []),
  207. %% reconnect all, again
  208. syn_test_suite_helper:connect_node(SlaveNode2),
  209. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  210. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  211. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  212. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  213. %% check
  214. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  215. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  216. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]),
  217. %% crash the scope process on local
  218. syn_test_suite_helper:kill_process(syn_registry_default),
  219. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  220. %% check, it should have rebuilt after supervisor restarts it
  221. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  222. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  223. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]),
  224. %% crash scopes supervisor on local
  225. syn_test_suite_helper:kill_process(syn_scopes_sup),
  226. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  227. %% check
  228. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  229. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  230. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]).
  231. three_nodes_discover_custom_scope(Config) ->
  232. %% get slaves
  233. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  234. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  235. %% start syn on nodes
  236. ok = syn:start(),
  237. ok = rpc:call(SlaveNode1, syn, start, []),
  238. ok = rpc:call(SlaveNode2, syn, start, []),
  239. %% add custom scopes
  240. ok = syn:add_node_to_scope(custom_scope_ab),
  241. ok = syn:add_node_to_scope(custom_scope_all),
  242. ok = rpc:call(SlaveNode1, syn, add_node_to_scopes, [[custom_scope_ab, custom_scope_bc, custom_scope_all]]),
  243. ok = rpc:call(SlaveNode2, syn, add_node_to_scopes, [[custom_scope_bc, custom_scope_c, custom_scope_all]]),
  244. %% check
  245. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_ab, [SlaveNode1]),
  246. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_all, [SlaveNode1, SlaveNode2]),
  247. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_ab, [node()]),
  248. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_bc, [SlaveNode2]),
  249. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_all, [node(), SlaveNode2]),
  250. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_bc, [SlaveNode1]),
  251. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_c, []),
  252. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_all, [node(), SlaveNode1]),
  253. %% check default
  254. syn_test_suite_helper:assert_scope_subcluster(node(), default, [SlaveNode1, SlaveNode2]),
  255. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, default, [node(), SlaveNode2]),
  256. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, default, [node(), SlaveNode1]),
  257. %% disconnect node 2 (node 1 can still see node 2)
  258. syn_test_suite_helper:disconnect_node(SlaveNode2),
  259. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1]),
  260. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  261. %% check
  262. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_ab, [SlaveNode1]),
  263. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_all, [SlaveNode1]),
  264. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_ab, [node()]),
  265. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_bc, [SlaveNode2]),
  266. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_all, [node(), SlaveNode2]),
  267. %% reconnect node 2
  268. syn_test_suite_helper:connect_node(SlaveNode2),
  269. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  270. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  271. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  272. %% check
  273. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_ab, [SlaveNode1]),
  274. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_all, [SlaveNode1, SlaveNode2]),
  275. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_ab, [node()]),
  276. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_bc, [SlaveNode2]),
  277. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_all, [node(), SlaveNode2]),
  278. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_bc, [SlaveNode1]),
  279. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_c, []),
  280. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_all, [node(), SlaveNode1]),
  281. %% crash a scope process on 2
  282. rpc:call(SlaveNode2, syn_test_suite_helper, kill_process, [syn_registry_custom_scope_bc]),
  283. rpc:call(SlaveNode2, syn_test_suite_helper, wait_process_name_ready, [syn_registry_default]),
  284. %% check
  285. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_ab, [SlaveNode1]),
  286. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_all, [SlaveNode1, SlaveNode2]),
  287. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_ab, [node()]),
  288. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_bc, [SlaveNode2]),
  289. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_all, [node(), SlaveNode2]),
  290. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_bc, [SlaveNode1]),
  291. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_c, []),
  292. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_all, [node(), SlaveNode1]),
  293. %% crash scopes supervisor on local
  294. syn_test_suite_helper:kill_process(syn_scopes_sup),
  295. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  296. %% check
  297. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_ab, [SlaveNode1]),
  298. syn_test_suite_helper:assert_scope_subcluster(node(), custom_scope_all, [SlaveNode1, SlaveNode2]),
  299. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_ab, [node()]),
  300. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_bc, [SlaveNode2]),
  301. syn_test_suite_helper:assert_scope_subcluster(SlaveNode1, custom_scope_all, [node(), SlaveNode2]),
  302. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_bc, [SlaveNode1]),
  303. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_c, []),
  304. syn_test_suite_helper:assert_scope_subcluster(SlaveNode2, custom_scope_all, [node(), SlaveNode1]).
  305. three_nodes_register_unregister_and_monitor_default_scope(Config) ->
  306. %% get slaves
  307. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  308. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  309. %% start syn on nodes
  310. ok = syn:start(),
  311. ok = rpc:call(SlaveNode1, syn, start, []),
  312. ok = rpc:call(SlaveNode2, syn, start, []),
  313. %% start processes
  314. Pid = syn_test_suite_helper:start_process(),
  315. PidWithMeta = syn_test_suite_helper:start_process(),
  316. PidRemoteOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  317. %% retrieve
  318. undefined = syn:lookup(<<"my proc">>),
  319. undefined = rpc:call(SlaveNode1, syn, lookup, [<<"my proc">>]),
  320. undefined = rpc:call(SlaveNode2, syn, lookup, [<<"my proc">>]),
  321. undefined = syn:lookup({"my proc alias"}),
  322. undefined = rpc:call(SlaveNode1, syn, lookup, [{"my proc alias"}]),
  323. undefined = rpc:call(SlaveNode2, syn, lookup, [{"my proc alias"}]),
  324. undefined = syn:lookup(<<"my proc with meta">>),
  325. undefined = rpc:call(SlaveNode1, syn, lookup, [<<"my proc with meta">>]),
  326. undefined = rpc:call(SlaveNode2, syn, lookup, [<<"my proc with meta">>]),
  327. undefined = syn:lookup({remote_pid_on, slave_1}),
  328. undefined = rpc:call(SlaveNode1, syn, lookup, [{remote_pid_on, slave_1}]),
  329. undefined = rpc:call(SlaveNode2, syn, lookup, [{remote_pid_on, slave_1}]),
  330. 0 = syn:registry_count(default),
  331. 0 = syn:registry_count(default, node()),
  332. 0 = syn:registry_count(default, SlaveNode1),
  333. 0 = syn:registry_count(default, SlaveNode2),
  334. %% register
  335. ok = syn:register(<<"my proc">>, Pid),
  336. ok = syn:register({"my proc alias"}, Pid), %% same pid, different name
  337. ok = syn:register(<<"my proc with meta">>, PidWithMeta, {meta, <<"meta">>}), %% pid with meta
  338. ok = syn:register({remote_pid_on, slave_1}, PidRemoteOn1), %% remote on slave 1
  339. %% errors
  340. {error, taken} = syn:register(<<"my proc">>, PidRemoteOn1),
  341. {error, not_alive} = syn:register({"pid not alive"}, list_to_pid("<0.9999.0>")),
  342. %% retrieve
  343. syn_test_suite_helper:assert_wait(
  344. {Pid, undefined},
  345. fun() -> syn:lookup(<<"my proc">>) end
  346. ),
  347. syn_test_suite_helper:assert_wait(
  348. {Pid, undefined},
  349. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc">>]) end
  350. ),
  351. syn_test_suite_helper:assert_wait(
  352. {Pid, undefined},
  353. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc">>]) end
  354. ),
  355. syn_test_suite_helper:assert_wait(
  356. {Pid, undefined},
  357. fun() -> syn:lookup({"my proc alias"}) end
  358. ),
  359. syn_test_suite_helper:assert_wait(
  360. {Pid, undefined},
  361. fun() -> rpc:call(SlaveNode1, syn, lookup, [{"my proc alias"}]) end
  362. ),
  363. syn_test_suite_helper:assert_wait(
  364. {Pid, undefined},
  365. fun() -> rpc:call(SlaveNode2, syn, lookup, [{"my proc alias"}]) end
  366. ),
  367. syn_test_suite_helper:assert_wait(
  368. {PidWithMeta, {meta, <<"meta">>}},
  369. fun() -> syn:lookup(<<"my proc with meta">>) end
  370. ),
  371. syn_test_suite_helper:assert_wait(
  372. {PidWithMeta, {meta, <<"meta">>}},
  373. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc with meta">>]) end
  374. ),
  375. syn_test_suite_helper:assert_wait(
  376. {PidWithMeta, {meta, <<"meta">>}},
  377. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc with meta">>]) end
  378. ),
  379. syn_test_suite_helper:assert_wait(
  380. {PidRemoteOn1, undefined},
  381. fun() -> syn:lookup({remote_pid_on, slave_1}) end
  382. ),
  383. syn_test_suite_helper:assert_wait(
  384. {PidRemoteOn1, undefined},
  385. fun() -> rpc:call(SlaveNode1, syn, lookup, [{remote_pid_on, slave_1}]) end
  386. ),
  387. syn_test_suite_helper:assert_wait(
  388. {PidRemoteOn1, undefined},
  389. fun() -> rpc:call(SlaveNode2, syn, lookup, [{remote_pid_on, slave_1}]) end
  390. ),
  391. 4 = syn:registry_count(default),
  392. 3 = syn:registry_count(default, node()),
  393. 1 = syn:registry_count(default, SlaveNode1),
  394. 0 = syn:registry_count(default, SlaveNode2),
  395. %% re-register to edit meta
  396. ok = syn:register(<<"my proc with meta">>, PidWithMeta, {meta2, <<"meta2">>}),
  397. ok = rpc:call(SlaveNode2, syn, register, [{remote_pid_on, slave_1}, PidRemoteOn1, added_meta]), %% updated on slave 2
  398. %% retrieve
  399. syn_test_suite_helper:assert_wait(
  400. {PidWithMeta, {meta2, <<"meta2">>}},
  401. fun() -> syn:lookup(<<"my proc with meta">>) end
  402. ),
  403. syn_test_suite_helper:assert_wait(
  404. {PidWithMeta, {meta2, <<"meta2">>}},
  405. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc with meta">>]) end
  406. ),
  407. syn_test_suite_helper:assert_wait(
  408. {PidWithMeta, {meta2, <<"meta2">>}},
  409. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc with meta">>]) end
  410. ),
  411. syn_test_suite_helper:assert_wait(
  412. {PidRemoteOn1, added_meta},
  413. fun() -> syn:lookup({remote_pid_on, slave_1}) end
  414. ),
  415. syn_test_suite_helper:assert_wait(
  416. {PidRemoteOn1, added_meta},
  417. fun() -> rpc:call(SlaveNode1, syn, lookup, [{remote_pid_on, slave_1}]) end
  418. ),
  419. syn_test_suite_helper:assert_wait(
  420. {PidRemoteOn1, added_meta},
  421. fun() -> rpc:call(SlaveNode2, syn, lookup, [{remote_pid_on, slave_1}]) end
  422. ),
  423. 4 = syn:registry_count(default),
  424. 3 = syn:registry_count(default, node()),
  425. 1 = syn:registry_count(default, SlaveNode1),
  426. 0 = syn:registry_count(default, SlaveNode2),
  427. %% crash scope process to ensure that monitors get recreated
  428. exit(whereis(syn_registry_default), kill),
  429. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  430. %% kill process
  431. syn_test_suite_helper:kill_process(Pid),
  432. syn_test_suite_helper:kill_process(PidRemoteOn1),
  433. %% unregister process
  434. ok = syn:unregister(<<"my proc with meta">>),
  435. %% retrieve
  436. syn_test_suite_helper:assert_wait(
  437. undefined,
  438. fun() -> syn:lookup(<<"my proc">>) end
  439. ),
  440. syn_test_suite_helper:assert_wait(
  441. undefined,
  442. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc">>]) end
  443. ),
  444. syn_test_suite_helper:assert_wait(
  445. undefined,
  446. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc">>]) end
  447. ),
  448. syn_test_suite_helper:assert_wait(
  449. undefined,
  450. fun() -> syn:lookup({"my proc alias"}) end
  451. ),
  452. syn_test_suite_helper:assert_wait(
  453. undefined,
  454. fun() -> rpc:call(SlaveNode1, syn, lookup, [{"my proc alias"}]) end
  455. ),
  456. syn_test_suite_helper:assert_wait(
  457. undefined,
  458. fun() -> rpc:call(SlaveNode2, syn, lookup, [{"my proc alias"}]) end
  459. ),
  460. syn_test_suite_helper:assert_wait(
  461. undefined,
  462. fun() -> syn:lookup(<<"my proc with meta">>) end
  463. ),
  464. syn_test_suite_helper:assert_wait(
  465. undefined,
  466. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc with meta">>]) end
  467. ),
  468. syn_test_suite_helper:assert_wait(
  469. undefined,
  470. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc with meta">>]) end
  471. ),
  472. syn_test_suite_helper:assert_wait(
  473. undefined,
  474. fun() -> syn:lookup({remote_pid_on, slave_1}) end
  475. ),
  476. syn_test_suite_helper:assert_wait(
  477. undefined,
  478. fun() -> rpc:call(SlaveNode1, syn, lookup, [{remote_pid_on, slave_1}]) end
  479. ),
  480. syn_test_suite_helper:assert_wait(
  481. undefined,
  482. fun() -> rpc:call(SlaveNode2, syn, lookup, [{remote_pid_on, slave_1}]) end
  483. ),
  484. 0 = syn:registry_count(default),
  485. 0 = syn:registry_count(default, node()),
  486. 0 = syn:registry_count(default, SlaveNode1),
  487. 0 = syn:registry_count(default, SlaveNode2),
  488. %% errors
  489. {error, undefined} = syn:unregister({invalid_name}),
  490. %% (simulate race condition)
  491. Pid1 = syn_test_suite_helper:start_process(),
  492. Pid2 = syn_test_suite_helper:start_process(),
  493. ok = syn:register(<<"my proc">>, Pid1),
  494. syn_test_suite_helper:assert_wait(
  495. {Pid1, undefined},
  496. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc">>]) end
  497. ),
  498. syn_registry:remove_from_local_table(default, <<"my proc">>, Pid1),
  499. syn_registry:add_to_local_table(default, <<"my proc">>, Pid2, undefined, 0, undefined),
  500. {error, race_condition} = rpc:call(SlaveNode1, syn, unregister, [<<"my proc">>]).
  501. three_nodes_register_unregister_and_monitor_custom_scope(Config) ->
  502. %% get slaves
  503. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  504. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  505. %% start syn on nodes
  506. ok = syn:start(),
  507. ok = rpc:call(SlaveNode1, syn, start, []),
  508. ok = rpc:call(SlaveNode2, syn, start, []),
  509. %% add custom scopes
  510. ok = syn:add_node_to_scope(custom_scope_ab),
  511. ok = rpc:call(SlaveNode1, syn, add_node_to_scopes, [[custom_scope_ab, custom_scope_bc]]),
  512. ok = rpc:call(SlaveNode2, syn, add_node_to_scopes, [[custom_scope_bc]]),
  513. %% start processes
  514. Pid = syn_test_suite_helper:start_process(),
  515. PidWithMeta = syn_test_suite_helper:start_process(),
  516. PidRemoteWithMetaOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  517. %% retrieve
  518. undefined = syn:lookup("scope_a"),
  519. undefined = rpc:call(SlaveNode1, syn, lookup, ["scope_a"]),
  520. undefined = rpc:call(SlaveNode2, syn, lookup, ["scope_a"]),
  521. undefined = syn:lookup(custom_scope_ab, "scope_a"),
  522. undefined = rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a"]),
  523. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a"]),
  524. undefined = syn:lookup(custom_scope_ab, "scope_a_alias"),
  525. undefined = rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a_alias"]),
  526. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a_alias"]),
  527. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, {remote_scoped_bc}),
  528. undefined = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]),
  529. undefined = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]),
  530. 0 = syn:registry_count(custom_scope_ab),
  531. 0 = syn:registry_count(custom_scope_ab, node()),
  532. 0 = syn:registry_count(custom_scope_ab, SlaveNode1),
  533. 0 = syn:registry_count(custom_scope_ab, SlaveNode2),
  534. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  535. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, node()),
  536. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode1),
  537. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode2),
  538. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab]),
  539. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, node()]),
  540. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  541. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  542. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  543. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  544. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  545. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  546. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab]),
  547. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, node()]),
  548. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  549. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  550. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  551. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  552. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  553. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  554. %% register
  555. ok = syn:register(custom_scope_ab, "scope_a", Pid),
  556. ok = syn:register(custom_scope_ab, "scope_a_alias", PidWithMeta, <<"with_meta">>),
  557. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:register(custom_scope_bc, "scope_a", Pid),
  558. {'EXIT', {{invalid_scope, non_existent_scope}, _}} = catch syn:register(non_existent_scope, "scope_a", Pid),
  559. ok = rpc:call(SlaveNode2, syn, register, [custom_scope_bc, {remote_scoped_bc}, PidRemoteWithMetaOn1, <<"with_meta 1">>]),
  560. %% errors
  561. {error, taken} = syn:register(custom_scope_ab, "scope_a", PidWithMeta),
  562. {error, not_alive} = syn:register(custom_scope_ab, {"pid not alive"}, list_to_pid("<0.9999.0>")),
  563. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:register(custom_scope_bc, "scope_a_noscope", Pid),
  564. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:unregister(custom_scope_bc, "scope_a_noscope"),
  565. %% retrieve
  566. syn_test_suite_helper:assert_wait(
  567. undefined,
  568. fun() -> syn:lookup("scope_a") end
  569. ),
  570. syn_test_suite_helper:assert_wait(
  571. undefined,
  572. fun() -> rpc:call(SlaveNode1, syn, lookup, ["scope_a"]) end
  573. ),
  574. syn_test_suite_helper:assert_wait(
  575. undefined,
  576. fun() -> rpc:call(SlaveNode2, syn, lookup, ["scope_a"]) end
  577. ),
  578. syn_test_suite_helper:assert_wait(
  579. {Pid, undefined},
  580. fun() -> syn:lookup(custom_scope_ab, "scope_a") end
  581. ),
  582. syn_test_suite_helper:assert_wait(
  583. {Pid, undefined},
  584. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a"]) end
  585. ),
  586. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a"]),
  587. syn_test_suite_helper:assert_wait(
  588. {PidWithMeta, <<"with_meta">>},
  589. fun() -> syn:lookup(custom_scope_ab, "scope_a_alias") end
  590. ),
  591. syn_test_suite_helper:assert_wait(
  592. {PidWithMeta, <<"with_meta">>},
  593. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a_alias"]) end
  594. ),
  595. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a_alias"]),
  596. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, {remote_scoped_bc}),
  597. syn_test_suite_helper:assert_wait(
  598. {PidRemoteWithMetaOn1, <<"with_meta 1">>},
  599. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]) end
  600. ),
  601. syn_test_suite_helper:assert_wait(
  602. {PidRemoteWithMetaOn1, <<"with_meta 1">>},
  603. fun() -> rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]) end
  604. ),
  605. 2 = syn:registry_count(custom_scope_ab),
  606. 2 = syn:registry_count(custom_scope_ab, node()),
  607. 0 = syn:registry_count(custom_scope_ab, SlaveNode1),
  608. 0 = syn:registry_count(custom_scope_ab, SlaveNode2),
  609. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  610. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, node()),
  611. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode1),
  612. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode2),
  613. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab]),
  614. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, node()]),
  615. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  616. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  617. 1 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  618. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  619. 1 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  620. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  621. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab]),
  622. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, node()]),
  623. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  624. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  625. 1 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  626. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  627. 1 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  628. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  629. %% re-register to edit meta
  630. ok = syn:register(custom_scope_ab, "scope_a_alias", PidWithMeta, <<"with_meta_updated">>),
  631. syn_test_suite_helper:assert_wait(
  632. {PidWithMeta, <<"with_meta_updated">>},
  633. fun() -> syn:lookup(custom_scope_ab, "scope_a_alias") end
  634. ),
  635. syn_test_suite_helper:assert_wait(
  636. {PidWithMeta, <<"with_meta_updated">>},
  637. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a_alias"]) end
  638. ),
  639. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a_alias"]),
  640. %% crash scope process to ensure that monitors get recreated
  641. syn_test_suite_helper:kill_process(syn_registry_custom_scope_ab),
  642. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  643. %% kill process
  644. syn_test_suite_helper:kill_process(Pid),
  645. syn_test_suite_helper:kill_process(PidWithMeta),
  646. %% unregister processes
  647. {error, undefined} = catch syn:unregister(<<"my proc with meta">>),
  648. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:unregister(custom_scope_bc, <<"my proc with meta">>),
  649. ok = rpc:call(SlaveNode1, syn, unregister, [custom_scope_bc, {remote_scoped_bc}]),
  650. %% retrieve
  651. syn_test_suite_helper:assert_wait(
  652. undefined,
  653. fun() -> syn:lookup("scope_a") end
  654. ),
  655. syn_test_suite_helper:assert_wait(
  656. undefined,
  657. fun() -> rpc:call(SlaveNode1, syn, lookup, ["scope_a"]) end
  658. ),
  659. syn_test_suite_helper:assert_wait(
  660. undefined,
  661. fun() -> rpc:call(SlaveNode2, syn, lookup, ["scope_a"]) end
  662. ),
  663. syn_test_suite_helper:assert_wait(
  664. undefined,
  665. fun() -> syn:lookup(custom_scope_ab, "scope_a") end
  666. ),
  667. syn_test_suite_helper:assert_wait(
  668. undefined,
  669. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a"]) end
  670. ),
  671. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a"]),
  672. syn_test_suite_helper:assert_wait(
  673. undefined,
  674. fun() -> syn:lookup(custom_scope_ab, "scope_a_alias") end
  675. ),
  676. syn_test_suite_helper:assert_wait(
  677. undefined,
  678. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, "scope_a_alias"]) end
  679. ),
  680. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, lookup, [custom_scope_ab, "scope_a_alias"]),
  681. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, {remote_scoped_bc}),
  682. syn_test_suite_helper:assert_wait(
  683. undefined,
  684. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]) end
  685. ),
  686. syn_test_suite_helper:assert_wait(
  687. undefined,
  688. fun() -> rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, {remote_scoped_bc}]) end
  689. ),
  690. 0 = syn:registry_count(custom_scope_ab),
  691. 0 = syn:registry_count(custom_scope_ab, node()),
  692. 0 = syn:registry_count(custom_scope_ab, SlaveNode1),
  693. 0 = syn:registry_count(custom_scope_ab, SlaveNode2),
  694. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  695. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, node()),
  696. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode1),
  697. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc, SlaveNode2),
  698. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab]),
  699. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, node()]),
  700. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  701. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  702. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  703. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  704. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  705. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  706. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab]),
  707. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, node()]),
  708. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode1]),
  709. {badrpc, {'EXIT', {{invalid_scope, custom_scope_ab}, _}}} = catch rpc:call(SlaveNode2, syn, registry_count, [custom_scope_ab, SlaveNode2]),
  710. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  711. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  712. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  713. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  714. %% errors
  715. {error, undefined} = syn:unregister(custom_scope_ab, {invalid_name}),
  716. %% (simulate race condition)
  717. Pid1 = syn_test_suite_helper:start_process(),
  718. Pid2 = syn_test_suite_helper:start_process(),
  719. ok = syn:register(custom_scope_ab, <<"my proc">>, Pid1),
  720. syn_test_suite_helper:assert_wait(
  721. {Pid1, undefined},
  722. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_ab, <<"my proc">>]) end
  723. ),
  724. syn_registry:remove_from_local_table(custom_scope_ab, <<"my proc">>, Pid1),
  725. syn_registry:add_to_local_table(custom_scope_ab, <<"my proc">>, Pid2, undefined, 0, undefined),
  726. {error, race_condition} = rpc:call(SlaveNode1, syn, unregister, [custom_scope_ab, <<"my proc">>]).
  727. three_nodes_cluster_changes(Config) ->
  728. %% get slaves
  729. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  730. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  731. %% disconnect 1 from 2
  732. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  733. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  734. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  735. syn_test_suite_helper:assert_cluster(SlaveNode2, [node()]),
  736. %% start syn on 1 and 2, nodes don't know of each other
  737. ok = rpc:call(SlaveNode1, syn, start, []),
  738. ok = rpc:call(SlaveNode2, syn, start, []),
  739. %% add custom scopes
  740. ok = rpc:call(SlaveNode1, syn, add_node_to_scopes, [[custom_scope_bc]]),
  741. ok = rpc:call(SlaveNode2, syn, add_node_to_scopes, [[custom_scope_bc]]),
  742. %% start processes
  743. PidRemoteOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  744. PidRemoteOn2 = syn_test_suite_helper:start_process(SlaveNode2),
  745. %% register
  746. ok = rpc:call(SlaveNode1, syn, register, ["proc-1", PidRemoteOn1, "meta-1"]),
  747. ok = rpc:call(SlaveNode1, syn, register, ["proc-2", PidRemoteOn2, "meta-2"]),
  748. ok = rpc:call(SlaveNode1, syn, register, [custom_scope_bc, "BC-proc-1", PidRemoteOn1, "meta-1"]),
  749. ok = rpc:call(SlaveNode1, syn, register, [custom_scope_bc, "BC-proc-1 alias", PidRemoteOn1, "meta-1 alias"]),
  750. %% form full cluster
  751. ok = syn:start(),
  752. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  753. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  754. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  755. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  756. syn_test_suite_helper:wait_process_name_ready(syn_registry_default),
  757. {PidRemoteOn1, "meta-1"} = syn:lookup("proc-1"),
  758. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, ["proc-1"]),
  759. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode2, syn, lookup, ["proc-1"]),
  760. {PidRemoteOn2, "meta-2"} = syn:lookup("proc-2"),
  761. {PidRemoteOn2, "meta-2"} = rpc:call(SlaveNode1, syn, lookup, ["proc-2"]),
  762. {PidRemoteOn2, "meta-2"} = rpc:call(SlaveNode2, syn, lookup, ["proc-2"]),
  763. 2 = syn:registry_count(default),
  764. 0 = syn:registry_count(default, node()),
  765. 1 = syn:registry_count(default, SlaveNode1),
  766. 1 = syn:registry_count(default, SlaveNode2),
  767. 2 = rpc:call(SlaveNode1, syn, registry_count, [default]),
  768. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, node()]),
  769. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode1]),
  770. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode2]),
  771. 2 = rpc:call(SlaveNode2, syn, registry_count, [default]),
  772. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, node()]),
  773. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode1]),
  774. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode2]),
  775. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1"),
  776. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  777. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  778. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1 alias"),
  779. {PidRemoteOn1, "meta-1 alias"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  780. {PidRemoteOn1, "meta-1 alias"} = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  781. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  782. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  783. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  784. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  785. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  786. 2 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  787. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  788. 2 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  789. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  790. %% partial netsplit (1 cannot see 2)
  791. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  792. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  793. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  794. syn_test_suite_helper:assert_cluster(SlaveNode2, [node()]),
  795. %% retrieve
  796. {PidRemoteOn1, "meta-1"} = syn:lookup("proc-1"),
  797. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, ["proc-1"]),
  798. undefined = rpc:call(SlaveNode2, syn, lookup, ["proc-1"]),
  799. {PidRemoteOn2, "meta-2"} = syn:lookup("proc-2"),
  800. undefined = rpc:call(SlaveNode1, syn, lookup, ["proc-2"]),
  801. {PidRemoteOn2, "meta-2"} = rpc:call(SlaveNode2, syn, lookup, ["proc-2"]),
  802. 2 = syn:registry_count(default),
  803. 0 = syn:registry_count(default, node()),
  804. 1 = syn:registry_count(default, SlaveNode1),
  805. 1 = syn:registry_count(default, SlaveNode2),
  806. 1 = rpc:call(SlaveNode1, syn, registry_count, [default]),
  807. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, node()]),
  808. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode1]),
  809. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode2]),
  810. 1 = rpc:call(SlaveNode2, syn, registry_count, [default]),
  811. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, node()]),
  812. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode1]),
  813. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode2]),
  814. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1"),
  815. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  816. undefined = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  817. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1 alias"),
  818. {PidRemoteOn1, "meta-1 alias"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  819. undefined = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  820. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  821. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  822. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  823. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  824. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  825. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  826. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  827. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  828. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  829. %% re-join
  830. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  831. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  832. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  833. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  834. %% retrieve
  835. {PidRemoteOn1, "meta-1"} = syn:lookup("proc-1"),
  836. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, ["proc-1"]),
  837. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode2, syn, lookup, ["proc-1"]),
  838. {PidRemoteOn2, "meta-2"} = syn:lookup("proc-2"),
  839. {PidRemoteOn2, "meta-2"} = rpc:call(SlaveNode1, syn, lookup, ["proc-2"]),
  840. {PidRemoteOn2, "meta-2"} = rpc:call(SlaveNode2, syn, lookup, ["proc-2"]),
  841. 2 = syn:registry_count(default),
  842. 0 = syn:registry_count(default, node()),
  843. 1 = syn:registry_count(default, SlaveNode1),
  844. 1 = syn:registry_count(default, SlaveNode2),
  845. 2 = rpc:call(SlaveNode1, syn, registry_count, [default]),
  846. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, node()]),
  847. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode1]),
  848. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode2]),
  849. 2 = rpc:call(SlaveNode2, syn, registry_count, [default]),
  850. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, node()]),
  851. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode1]),
  852. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode2]),
  853. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1"),
  854. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  855. {PidRemoteOn1, "meta-1"} = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1"]),
  856. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:lookup(custom_scope_bc, "BC-proc-1 alias"),
  857. {PidRemoteOn1, "meta-1 alias"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  858. {PidRemoteOn1, "meta-1 alias"} = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "BC-proc-1 alias"]),
  859. {'EXIT', {{invalid_scope, custom_scope_bc}, _}} = catch syn:registry_count(custom_scope_bc),
  860. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  861. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  862. 2 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  863. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  864. 2 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  865. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  866. 2 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  867. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]).
  868. three_nodes_cluster_conflicts(Config) ->
  869. %% get slaves
  870. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  871. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  872. %% start syn on nodes
  873. ok = syn:start(),
  874. ok = rpc:call(SlaveNode1, syn, start, []),
  875. ok = rpc:call(SlaveNode2, syn, start, []),
  876. %% add custom scopes
  877. ok = rpc:call(SlaveNode1, syn, add_node_to_scopes, [[custom_scope_bc]]),
  878. ok = rpc:call(SlaveNode2, syn, add_node_to_scopes, [[custom_scope_bc]]),
  879. %% partial netsplit (1 cannot see 2)
  880. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  881. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  882. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  883. syn_test_suite_helper:assert_cluster(SlaveNode2, [node()]),
  884. %% start conflict processes
  885. Pid2RemoteOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  886. Pid2RemoteOn2 = syn_test_suite_helper:start_process(SlaveNode2),
  887. %% --> conflict by netsplit
  888. ok = rpc:call(SlaveNode1, syn, register, ["proc-confict", Pid2RemoteOn1, "meta-1"]),
  889. ok = rpc:call(SlaveNode2, syn, register, ["proc-confict", Pid2RemoteOn2, "meta-2"]),
  890. ok = rpc:call(SlaveNode1, syn, register, [custom_scope_bc, "proc-confict", Pid2RemoteOn1, "meta-1"]),
  891. ok = rpc:call(SlaveNode2, syn, register, [custom_scope_bc, "proc-confict", Pid2RemoteOn2, "meta-2"]),
  892. %% re-join
  893. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  894. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  895. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  896. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  897. %% retrieve
  898. {Pid2RemoteOn2, "meta-2"} = syn:lookup("proc-confict"),
  899. syn_test_suite_helper:assert_wait(
  900. {Pid2RemoteOn2, "meta-2"},
  901. fun() -> rpc:call(SlaveNode1, syn, lookup, ["proc-confict"]) end
  902. ),
  903. syn_test_suite_helper:assert_wait(
  904. {Pid2RemoteOn2, "meta-2"},
  905. fun() -> rpc:call(SlaveNode2, syn, lookup, ["proc-confict"]) end
  906. ),
  907. 1 = syn:registry_count(default),
  908. 0 = syn:registry_count(default, node()),
  909. 0 = syn:registry_count(default, SlaveNode1),
  910. 1 = syn:registry_count(default, SlaveNode2),
  911. 1 = rpc:call(SlaveNode1, syn, registry_count, [default]),
  912. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, node()]),
  913. 0 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode1]),
  914. 1 = rpc:call(SlaveNode1, syn, registry_count, [default, SlaveNode2]),
  915. 1 = rpc:call(SlaveNode2, syn, registry_count, [default]),
  916. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, node()]),
  917. 0 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode1]),
  918. 1 = rpc:call(SlaveNode2, syn, registry_count, [default, SlaveNode2]),
  919. {Pid2RemoteOn2, "meta-2"} = rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, "proc-confict"]),
  920. {Pid2RemoteOn2, "meta-2"} = rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, "proc-confict"]),
  921. 1 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc]),
  922. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, node()]),
  923. 0 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  924. 1 = rpc:call(SlaveNode1, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  925. 1 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc]),
  926. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, node()]),
  927. 0 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode1]),
  928. 1 = rpc:call(SlaveNode2, syn, registry_count, [custom_scope_bc, SlaveNode2]),
  929. %% --> conflict by race condition
  930. Pid1 = syn_test_suite_helper:start_process(),
  931. Pid2 = syn_test_suite_helper:start_process(SlaveNode1),
  932. rpc:call(SlaveNode1, syn_registry, add_to_local_table, [default, <<"my proc">>, Pid2, "meta-2", erlang:system_time(), undefined]),
  933. ok = syn:register(<<"my proc">>, Pid1, "meta-1"),
  934. {Pid1, "meta-1"} = syn:lookup(<<"my proc">>),
  935. syn_test_suite_helper:assert_wait(
  936. {Pid1, "meta-1"},
  937. fun() -> rpc:call(SlaveNode1, syn, lookup, [<<"my proc">>]) end
  938. ),
  939. syn_test_suite_helper:assert_wait(
  940. {Pid1, "meta-1"},
  941. fun() -> rpc:call(SlaveNode2, syn, lookup, [<<"my proc">>]) end
  942. ),
  943. true = is_process_alive(Pid1),
  944. false = rpc:call(SlaveNode1, erlang, is_process_alive, [Pid2]),
  945. PidCustom1 = syn_test_suite_helper:start_process(SlaveNode1),
  946. PidCustom2 = syn_test_suite_helper:start_process(SlaveNode2),
  947. rpc:call(SlaveNode2, syn_registry, add_to_local_table, [custom_scope_bc, <<"my proc">>, PidCustom2, "meta-2", erlang:system_time(), undefined]),
  948. ok = rpc:call(SlaveNode1, syn, register, [custom_scope_bc, <<"my proc">>, PidCustom1, "meta-1"]),
  949. syn_test_suite_helper:assert_wait(
  950. {PidCustom1, "meta-1"},
  951. fun() -> rpc:call(SlaveNode1, syn, lookup, [custom_scope_bc, <<"my proc">>]) end
  952. ),
  953. syn_test_suite_helper:assert_wait(
  954. {PidCustom1, "meta-1"},
  955. fun() -> rpc:call(SlaveNode2, syn, lookup, [custom_scope_bc, <<"my proc">>]) end
  956. ),
  957. true = rpc:call(SlaveNode1, erlang, is_process_alive, [PidCustom1]),
  958. false = rpc:call(SlaveNode2, erlang, is_process_alive, [PidCustom2]).
  959. three_nodes_custom_event_handler_reg_unreg(Config) ->
  960. %% get slaves
  961. SlaveNode1 = proplists:get_value(slave_node_1, Config),
  962. SlaveNode2 = proplists:get_value(slave_node_2, Config),
  963. %% add custom handler
  964. syn_test_suite_helper:use_custom_handler(),
  965. rpc:call(SlaveNode1, syn_test_suite_helper, use_custom_handler, []),
  966. rpc:call(SlaveNode2, syn_test_suite_helper, use_custom_handler, []),
  967. %% start syn on nodes
  968. ok = syn:start(),
  969. ok = rpc:call(SlaveNode1, syn, start, []),
  970. ok = rpc:call(SlaveNode2, syn, start, []),
  971. %% init
  972. CurrentNode = node(),
  973. %% start process
  974. Pid = syn_test_suite_helper:start_process(),
  975. %% ---> on registration
  976. ok = syn:register("proc-handler", Pid, {recipient, self(), <<"meta">>}),
  977. %% check callbacks called
  978. syn_test_suite_helper:assert_received_messages([
  979. {on_process_registered, CurrentNode, default, "proc-handler", Pid, <<"meta">>},
  980. {on_process_registered, SlaveNode1, default, "proc-handler", Pid, <<"meta">>},
  981. {on_process_registered, SlaveNode2, default, "proc-handler", Pid, <<"meta">>}
  982. ]),
  983. syn_test_suite_helper:assert_empty_queue(self()),
  984. %% ---> on meta update
  985. ok = syn:register("proc-handler", Pid, {recipient, self(), <<"new-meta">>}),
  986. %% check callbacks called
  987. syn_test_suite_helper:assert_received_messages([
  988. {on_process_registered, CurrentNode, default, "proc-handler", Pid, <<"new-meta">>},
  989. {on_process_registered, SlaveNode1, default, "proc-handler", Pid, <<"new-meta">>},
  990. {on_process_registered, SlaveNode2, default, "proc-handler", Pid, <<"new-meta">>}
  991. ]),
  992. syn_test_suite_helper:assert_empty_queue(self()),
  993. %% ---> on unregister
  994. ok = syn:unregister("proc-handler"),
  995. %% check callbacks called
  996. syn_test_suite_helper:assert_received_messages([
  997. {on_process_unregistered, CurrentNode, default, "proc-handler", Pid, <<"new-meta">>},
  998. {on_process_unregistered, SlaveNode1, default, "proc-handler", Pid, <<"new-meta">>},
  999. {on_process_unregistered, SlaveNode2, default, "proc-handler", Pid, <<"new-meta">>}
  1000. ]),
  1001. syn_test_suite_helper:assert_empty_queue(self()),
  1002. %% clean & check
  1003. syn_test_suite_helper:kill_process(Pid),
  1004. syn_test_suite_helper:assert_empty_queue(self()),
  1005. %% ---> after a netsplit
  1006. PidRemoteOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  1007. syn:register(remote_on_1, PidRemoteOn1, {recipient, self(), <<"netsplit">>}),
  1008. %% check callbacks called
  1009. syn_test_suite_helper:assert_received_messages([
  1010. {on_process_registered, CurrentNode, default, remote_on_1, PidRemoteOn1, <<"netsplit">>},
  1011. {on_process_registered, SlaveNode1, default, remote_on_1, PidRemoteOn1, <<"netsplit">>},
  1012. {on_process_registered, SlaveNode2, default, remote_on_1, PidRemoteOn1, <<"netsplit">>}
  1013. ]),
  1014. syn_test_suite_helper:assert_empty_queue(self()),
  1015. %% partial netsplit (1 cannot see 2)
  1016. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  1017. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  1018. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  1019. syn_test_suite_helper:assert_cluster(SlaveNode2, [node()]),
  1020. %% check callbacks called
  1021. syn_test_suite_helper:assert_received_messages([
  1022. {on_process_unregistered, SlaveNode2, default, remote_on_1, PidRemoteOn1, <<"netsplit">>}
  1023. ]),
  1024. syn_test_suite_helper:assert_empty_queue(self()),
  1025. %% ---> after a re-join
  1026. %% re-join
  1027. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  1028. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  1029. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  1030. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  1031. %% check callbacks called
  1032. syn_test_suite_helper:assert_received_messages([
  1033. {on_process_registered, SlaveNode2, default, remote_on_1, PidRemoteOn1, <<"netsplit">>}
  1034. ]),
  1035. syn_test_suite_helper:assert_empty_queue(self()),
  1036. %% clean
  1037. syn_test_suite_helper:kill_process(PidRemoteOn1),
  1038. %% check callbacks called
  1039. syn_test_suite_helper:assert_received_messages([
  1040. {on_process_unregistered, CurrentNode, default, remote_on_1, PidRemoteOn1, <<"netsplit">>},
  1041. {on_process_unregistered, SlaveNode1, default, remote_on_1, PidRemoteOn1, <<"netsplit">>},
  1042. {on_process_unregistered, SlaveNode2, default, remote_on_1, PidRemoteOn1, <<"netsplit">>}
  1043. ]),
  1044. syn_test_suite_helper:assert_empty_queue(self()),
  1045. %% ---> after a conflict resolution
  1046. %% partial netsplit (1 cannot see 2)
  1047. rpc:call(SlaveNode1, syn_test_suite_helper, disconnect_node, [SlaveNode2]),
  1048. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  1049. syn_test_suite_helper:assert_cluster(SlaveNode1, [node()]),
  1050. syn_test_suite_helper:assert_cluster(SlaveNode2, [node()]),
  1051. %% start conflict processes
  1052. Pid2RemoteOn1 = syn_test_suite_helper:start_process(SlaveNode1),
  1053. Pid2RemoteOn2 = syn_test_suite_helper:start_process(SlaveNode2),
  1054. ok = rpc:call(SlaveNode1, syn, register, ["proc-confict", Pid2RemoteOn1, {recipient, self(), <<"meta-1">>}]),
  1055. ok = rpc:call(SlaveNode2, syn, register, ["proc-confict", Pid2RemoteOn2, {recipient, self(), <<"meta-2">>}]),
  1056. %% check callbacks called
  1057. syn_test_suite_helper:assert_received_messages([
  1058. {on_process_registered, CurrentNode, default, "proc-confict", Pid2RemoteOn1, <<"meta-1">>},
  1059. {on_process_unregistered, CurrentNode, default, "proc-confict", Pid2RemoteOn1, <<"meta-1">>},
  1060. {on_process_registered, CurrentNode, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>},
  1061. {on_process_registered, SlaveNode1, default, "proc-confict", Pid2RemoteOn1, <<"meta-1">>},
  1062. {on_process_registered, SlaveNode2, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>}
  1063. ]),
  1064. syn_test_suite_helper:assert_empty_queue(self()),
  1065. %% re-join
  1066. rpc:call(SlaveNode1, syn_test_suite_helper, connect_node, [SlaveNode2]),
  1067. syn_test_suite_helper:assert_cluster(node(), [SlaveNode1, SlaveNode2]),
  1068. syn_test_suite_helper:assert_cluster(SlaveNode1, [node(), SlaveNode2]),
  1069. syn_test_suite_helper:assert_cluster(SlaveNode2, [node(), SlaveNode1]),
  1070. %% check callbacks called
  1071. syn_test_suite_helper:assert_received_messages([
  1072. {on_process_unregistered, SlaveNode1, default, "proc-confict", Pid2RemoteOn1, <<"meta-1">>},
  1073. {on_process_registered, SlaveNode1, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>}
  1074. ]),
  1075. syn_test_suite_helper:assert_empty_queue(self()),
  1076. %% clean
  1077. syn_test_suite_helper:kill_process(Pid2RemoteOn1),
  1078. syn_test_suite_helper:kill_process(Pid2RemoteOn2),
  1079. %% check callbacks called
  1080. syn_test_suite_helper:assert_received_messages([
  1081. {on_process_unregistered, CurrentNode, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>},
  1082. {on_process_unregistered, SlaveNode1, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>},
  1083. {on_process_unregistered, SlaveNode2, default, "proc-confict", Pid2RemoteOn2, <<"meta-2">>}
  1084. ]),
  1085. syn_test_suite_helper:assert_empty_queue(self()),
  1086. %% ---> don't call on monitor rebuild
  1087. %% crash the scope process on local
  1088. syn_test_suite_helper:kill_process(syn_registry_default),
  1089. %% no messages
  1090. syn_test_suite_helper:assert_wait(
  1091. ok,
  1092. fun() -> syn_test_suite_helper:assert_empty_queue(self()) end
  1093. ).