/hazelcast/src/test/java/com/hazelcast/cluster/MemberListTest.java

https://bitbucket.org/gabral6_gmailcom/hazelcast · Java · 348 lines · 243 code · 64 blank · 41 comment · 3 complexity · b047893f3b370a66c8b54db6839f7371 MD5 · raw file

  1. /*
  2. * Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.hazelcast.cluster;
  17. import com.hazelcast.config.Config;
  18. import com.hazelcast.config.NetworkConfig;
  19. import com.hazelcast.core.Hazelcast;
  20. import com.hazelcast.core.HazelcastInstance;
  21. import com.hazelcast.core.Member;
  22. import com.hazelcast.core.MultiTask;
  23. import com.hazelcast.impl.*;
  24. import org.junit.After;
  25. import org.junit.BeforeClass;
  26. import org.junit.Test;
  27. import org.junit.runner.RunWith;
  28. import java.io.Serializable;
  29. import java.util.*;
  30. import java.util.concurrent.Callable;
  31. import java.util.concurrent.atomic.AtomicBoolean;
  32. import static junit.framework.Assert.assertEquals;
  33. @RunWith(com.hazelcast.util.RandomBlockJUnit4ClassRunner.class)
  34. public class MemberListTest {
  35. @BeforeClass
  36. public static void init() throws Exception {
  37. Hazelcast.shutdownAll();
  38. }
  39. @After
  40. public void cleanup() throws Exception {
  41. Hazelcast.shutdownAll();
  42. }
  43. /*
  44. * Sets up a situation where node3 removes the master and sets node2 as the
  45. * master but none of the other nodes do. This means that node3 thinks node2
  46. * is master but node2 thinks node1 is master.
  47. */
  48. @Test
  49. public void testOutOfSyncMemberListIssue274() throws Exception {
  50. Config c1 = buildConfig(false);
  51. Config c2 = buildConfig(false);
  52. Config c3 = buildConfig(false);
  53. c1.getNetworkConfig().setPort(35701);
  54. c2.getNetworkConfig().setPort(35702);
  55. c3.getNetworkConfig().setPort(35703);
  56. List<String> allMembers = Arrays.asList("127.0.0.1:35701, 127.0.0.1:35702, 127.0.0.1:35703");
  57. c1.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  58. c2.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  59. c3.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  60. final HazelcastInstance h1 = Hazelcast.newHazelcastInstance(c1);
  61. final HazelcastInstance h2 = Hazelcast.newHazelcastInstance(c2);
  62. final HazelcastInstance h3 = Hazelcast.newHazelcastInstance(c3);
  63. // All three nodes join into one cluster
  64. assertEquals(3, h1.getCluster().getMembers().size());
  65. assertEquals(3, h2.getCluster().getMembers().size());
  66. assertEquals(3, h3.getCluster().getMembers().size());
  67. // This simulates each node reading from the other nodes in the list at regular intervals
  68. // This prevents the heart beat code from timing out
  69. final HazelcastInstance[] instances = new HazelcastInstance[] {h1, h2, h3};
  70. final AtomicBoolean doingWork = new AtomicBoolean(true);
  71. Thread[] workThreads = new Thread[instances.length];
  72. for (int i = 0; i < instances.length; i++) {
  73. final int threadNum = i;
  74. workThreads[threadNum] = new Thread(new Runnable() {
  75. public void run() {
  76. while (doingWork.get()) {
  77. final HazelcastInstance hz = instances[threadNum];
  78. Set<Member> members = new HashSet<Member>(hz.getCluster().getMembers());
  79. members.remove(hz.getCluster().getLocalMember());
  80. MultiTask<String> task = new MultiTask<String>(new PingCallable(), members);
  81. hz.getExecutorService().execute(task);
  82. try {
  83. task.get();
  84. } catch (Exception e) {
  85. e.printStackTrace();
  86. }
  87. try {
  88. Thread.sleep(2000);
  89. } catch (InterruptedException e) {
  90. e.printStackTrace();
  91. }
  92. }
  93. }
  94. });
  95. workThreads[threadNum].start();
  96. }
  97. final Node n3 = TestUtil.getNode(h3);
  98. n3.clusterManager.enqueueAndWait(new Processable() {
  99. public void process() {
  100. // Simulates node3's heartbeat code choosing to remove node1
  101. n3.clusterManager.doRemoveAddress(((MemberImpl) h1.getCluster().getLocalMember()).getAddress());
  102. assertEquals(2, n3.clusterManager.getMembers().size());
  103. }
  104. }, 5);
  105. // Give the cluster some time to figure things out. The merge and heartbeat code should have kicked in by this point
  106. Thread.sleep(30 * 1000);
  107. doingWork.set(false);
  108. for (Thread t : workThreads) {
  109. t.join();
  110. }
  111. assertEquals(3, h1.getCluster().getMembers().size());
  112. assertEquals(3, h2.getCluster().getMembers().size());
  113. assertEquals(3, h3.getCluster().getMembers().size());
  114. }
  115. private static class PingCallable implements Callable<String>, Serializable {
  116. public String call() throws Exception {
  117. return "ping response";
  118. }
  119. }
  120. /*
  121. * Sets up a situation where the member list is out of order on node2. Both
  122. * node2 and node1 think they are masters and both think each other are in
  123. * their clusters.
  124. */
  125. @Test
  126. public void testOutOfSyncMemberListTwoMastersIssue274() throws Exception {
  127. Config c1 = buildConfig(false);
  128. Config c2 = buildConfig(false);
  129. Config c3 = buildConfig(false);
  130. c1.getNetworkConfig().setPort(45701);
  131. c2.getNetworkConfig().setPort(45702);
  132. c3.getNetworkConfig().setPort(45703);
  133. List<String> allMembers = Arrays.asList("127.0.0.1:45701, 127.0.0.1:45702, 127.0.0.1:45703");
  134. c1.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  135. c2.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  136. c3.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  137. final HazelcastInstance h1 = Hazelcast.newHazelcastInstance(c1);
  138. final HazelcastInstance h2 = Hazelcast.newHazelcastInstance(c2);
  139. final HazelcastInstance h3 = Hazelcast.newHazelcastInstance(c3);
  140. final MemberImpl m1 = (MemberImpl) h1.getCluster().getLocalMember();
  141. final MemberImpl m2 = (MemberImpl) h2.getCluster().getLocalMember();
  142. final MemberImpl m3 = (MemberImpl) h3.getCluster().getLocalMember();
  143. // All three nodes join into one cluster
  144. assertEquals(3, h1.getCluster().getMembers().size());
  145. assertEquals(3, h2.getCluster().getMembers().size());
  146. assertEquals(3, h3.getCluster().getMembers().size());
  147. final Node n2 = TestUtil.getNode(h2);
  148. n2.clusterManager.enqueueAndWait(new Processable() {
  149. public void process() {
  150. // Simulates node2 getting an out of order member list. That causes node2 to think it's the master.
  151. List<MemberInfo> members = new ArrayList<MemberInfo>();
  152. members.add(new MemberInfo(m2.getAddress(), m2.getNodeType(), m2.getUuid()));
  153. members.add(new MemberInfo(m3.getAddress(), m3.getNodeType(), m3.getUuid()));
  154. members.add(new MemberInfo(m1.getAddress(), m1.getNodeType(), m1.getUuid()));
  155. n2.clusterManager.updateMembers(members);
  156. n2.setMasterAddress(m2.getAddress());
  157. }
  158. }, 5);
  159. // Give the cluster some time to figure things out. The merge and heartbeat code should have kicked in by this point
  160. Thread.sleep(30 * 1000);
  161. assertEquals(m1, h1.getCluster().getMembers().iterator().next());
  162. assertEquals(m1, h2.getCluster().getMembers().iterator().next());
  163. assertEquals(m1, h3.getCluster().getMembers().iterator().next());
  164. assertEquals(3, h1.getCluster().getMembers().size());
  165. assertEquals(3, h2.getCluster().getMembers().size());
  166. assertEquals(3, h3.getCluster().getMembers().size());
  167. }
  168. /*
  169. * Sets up situation where all nodes have the same master, but node 2's list
  170. * doesn't contain node 3.
  171. */
  172. @Test
  173. public void testSameMasterDifferentMemberListIssue274() throws Exception {
  174. Config c1 = buildConfig(false);
  175. Config c2 = buildConfig(false);
  176. Config c3 = buildConfig(false);
  177. c1.getNetworkConfig().setPort(55701);
  178. c2.getNetworkConfig().setPort(55702);
  179. c3.getNetworkConfig().setPort(55703);
  180. List<String> allMembers = Arrays.asList("127.0.0.1:55701, 127.0.0.1:55702, 127.0.0.1:55703");
  181. c1.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  182. c2.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  183. c3.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  184. final HazelcastInstance h1 = Hazelcast.newHazelcastInstance(c1);
  185. final HazelcastInstance h2 = Hazelcast.newHazelcastInstance(c2);
  186. final HazelcastInstance h3 = Hazelcast.newHazelcastInstance(c3);
  187. final MemberImpl m1 = (MemberImpl) h1.getCluster().getLocalMember();
  188. final MemberImpl m2 = (MemberImpl) h2.getCluster().getLocalMember();
  189. // All three nodes join into one cluster
  190. assertEquals(3, h1.getCluster().getMembers().size());
  191. assertEquals(3, h2.getCluster().getMembers().size());
  192. assertEquals(3, h3.getCluster().getMembers().size());
  193. final Node n2 = TestUtil.getNode(h2);
  194. n2.clusterManager.enqueueAndWait(new Processable() {
  195. public void process() {
  196. // Simulates node2 getting an out of order member list. That causes node2 to think it's the master.
  197. List<MemberInfo> members = new ArrayList<MemberInfo>();
  198. members.add(new MemberInfo(m1.getAddress(), m1.getNodeType(), m1.getUuid()));
  199. members.add(new MemberInfo(m2.getAddress(), m2.getNodeType(), m2.getUuid()));
  200. n2.clusterManager.updateMembers(members);
  201. }
  202. }, 5);
  203. // Give the cluster some time to figure things out. The merge and heartbeat code should have kicked in by this point
  204. Thread.sleep(30 * 1000);
  205. assertEquals(m1, h1.getCluster().getMembers().iterator().next());
  206. assertEquals(m1, h2.getCluster().getMembers().iterator().next());
  207. assertEquals(m1, h3.getCluster().getMembers().iterator().next());
  208. assertEquals(3, h1.getCluster().getMembers().size());
  209. assertEquals(3, h2.getCluster().getMembers().size());
  210. assertEquals(3, h3.getCluster().getMembers().size());
  211. }
  212. @Test
  213. public void testSwitchingMastersIssue274() throws Exception {
  214. Config c1 = buildConfig(false);
  215. Config c2 = buildConfig(false);
  216. Config c3 = buildConfig(false);
  217. Config c4 = buildConfig(false);
  218. Config c5 = buildConfig(false);
  219. c1.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "15");
  220. c2.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "15");
  221. c3.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "15");
  222. c4.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "15");
  223. c5.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "15");
  224. c1.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "45");
  225. c2.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "45");
  226. c3.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "45");
  227. c4.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "45");
  228. c5.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "45");
  229. c1.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "120");
  230. c2.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "120");
  231. c3.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "120");
  232. c4.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "120");
  233. c5.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "120");
  234. c1.getNetworkConfig().setPort(55701);
  235. c2.getNetworkConfig().setPort(55702);
  236. c3.getNetworkConfig().setPort(55703);
  237. c4.getNetworkConfig().setPort(55704);
  238. c5.getNetworkConfig().setPort(55705);
  239. List<String> allMembers = Arrays.asList("127.0.0.1:55701", "127.0.0.1:55702", "127.0.0.1:55703", "127.0.0.1:55704", "127.0.0.1:55705");
  240. c1.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  241. c2.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  242. c3.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  243. c4.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  244. c5.getNetworkConfig().getJoin().getTcpIpConfig().setMembers(allMembers);
  245. final HazelcastInstance h1 = Hazelcast.newHazelcastInstance(c1);
  246. final HazelcastInstance h2 = Hazelcast.newHazelcastInstance(c2);
  247. final HazelcastInstance h3 = Hazelcast.newHazelcastInstance(c3);
  248. final HazelcastInstance h4 = Hazelcast.newHazelcastInstance(c4);
  249. final HazelcastInstance h5 = Hazelcast.newHazelcastInstance(c5);
  250. assertEquals(5, h1.getCluster().getMembers().size());
  251. assertEquals(5, h2.getCluster().getMembers().size());
  252. assertEquals(5, h3.getCluster().getMembers().size());
  253. assertEquals(5, h4.getCluster().getMembers().size());
  254. assertEquals(5, h5.getCluster().getMembers().size());
  255. // Need to wait for at least as long as PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS
  256. Thread.sleep(60 * 1000);
  257. h1.getLifecycleService().shutdown();
  258. Thread.sleep(10 * 1000);
  259. assertEquals(4, h2.getCluster().getMembers().size());
  260. assertEquals(4, h3.getCluster().getMembers().size());
  261. assertEquals(4, h4.getCluster().getMembers().size());
  262. assertEquals(4, h5.getCluster().getMembers().size());
  263. Thread.sleep(20 * 1000);
  264. assertEquals(4, h2.getCluster().getMembers().size());
  265. assertEquals(4, h3.getCluster().getMembers().size());
  266. assertEquals(4, h4.getCluster().getMembers().size());
  267. assertEquals(4, h5.getCluster().getMembers().size());
  268. }
  269. private static Config buildConfig(boolean multicastEnabled) {
  270. Config c = new Config();
  271. c.getGroupConfig().setName("group").setPassword("pass");
  272. c.setProperty(GroupProperties.PROP_MERGE_FIRST_RUN_DELAY_SECONDS, "10");
  273. c.setProperty(GroupProperties.PROP_MERGE_NEXT_RUN_DELAY_SECONDS, "5");
  274. c.setProperty(GroupProperties.PROP_MAX_NO_HEARTBEAT_SECONDS, "10");
  275. c.setProperty(GroupProperties.PROP_MASTER_CONFIRMATION_INTERVAL_SECONDS, "2");
  276. c.setProperty(GroupProperties.PROP_MAX_NO_MASTER_CONFIRMATION_SECONDS, "10");
  277. c.setProperty(GroupProperties.PROP_MEMBER_LIST_PUBLISH_INTERVAL_SECONDS, "10");
  278. final NetworkConfig networkConfig = c.getNetworkConfig();
  279. networkConfig.getJoin().getMulticastConfig().setEnabled(multicastEnabled);
  280. networkConfig.getJoin().getTcpIpConfig().setEnabled(!multicastEnabled);
  281. networkConfig.setPortAutoIncrement(false);
  282. return c;
  283. }
  284. }