1 /***
2 * Copyright 2003-2007 Terracotta, Inc.
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
17 package net.sf.ehcache.distribution;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.MulticastSocket;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.concurrent.Callable;
29 import java.util.concurrent.TimeUnit;
30
31 import net.sf.ehcache.AbstractCacheTest;
32 import net.sf.ehcache.Cache;
33 import net.sf.ehcache.CacheManager;
34 import net.sf.ehcache.Ehcache;
35 import net.sf.ehcache.util.RetryAssert;
36
37 import org.hamcrest.collection.IsEmptyCollection;
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Test;
41
42 /***
43 * Multicast tests. These require special machine configuration.
44 * <p/>
45 * Running on a single machine, as these tests do, you need to add a route command so that two multiCast sockets
46 * can be added at the same time.
47 * <ol>
48 * <li>Mac OSX: <code>route add -net 224.0.0.0 -interface lo0</code>
49 * <li>Linux (from JGroups doco, untested): <code>route add -net 224.0.0.0 netmask 224.0.0.0 dev lo</code>
50 * </ol>
51 *
52 * @author Greg Luck
53 * @version $Id: MulticastRMIPeerProviderTest.html 13146 2011-08-01 17:12:39Z oletizi $
54 */
55 public class MulticastRMIPeerProviderTest extends AbstractRMITest {
56
57 /***
58 * Cache Manager 1
59 */
60 protected CacheManager manager1;
61 /***
62 * Cache Manager 2
63 */
64 protected CacheManager manager2;
65 /***
66 * Cache Manager 3
67 */
68 protected CacheManager manager3;
69
70 /***
71 * {@inheritDoc}
72 */
73 @Before
74 public void setUp() throws Exception {
75 MulticastKeepaliveHeartbeatSender.setHeartBeatInterval(1000);
76 manager1 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed1.xml");
77 manager2 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed2.xml");
78 manager3 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed3.xml");
79
80
81 waitForClusterMembership(10, TimeUnit.SECONDS, Collections.singleton("sampleCache1"), manager1, manager2, manager3);
82 }
83
84 /***
85 * {@inheritDoc}
86 */
87 @After
88 public void tearDown() throws Exception {
89 if (manager1 != null) {
90 manager1.shutdown();
91 }
92 if (manager2 != null) {
93 manager2.shutdown();
94 }
95 if (manager3 != null) {
96 manager3.shutdown();
97 }
98
99 RetryAssert.assertBy(30, TimeUnit.SECONDS, new Callable<Set<Thread>>() {
100 public Set<Thread> call() throws Exception {
101 return getActiveReplicationThreads();
102 }
103 }, IsEmptyCollection.<Thread>empty());
104 }
105
106 /***
107 * Make sure no exceptions get logged. Manual inspection.
108 */
109 @Test
110 public void testSolePeer() throws Exception {
111 tearDown();
112
113 manager1 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR
114 + "distribution/ehcache-distributed-no-caches-replicating.xml");
115 }
116
117 /***
118 * test remote cache peers
119 */
120 @Test
121 public void testProviderFromCacheManager() throws InterruptedException {
122
123 Ehcache m1sampleCache1 = manager1.getCache("sampleCache1");
124 Thread.sleep(2000);
125
126 List peerUrls = manager1.getCacheManagerPeerProvider("RMI").listRemoteCachePeers(m1sampleCache1);
127 assertEquals(expectedPeers(), peerUrls.size());
128
129 Ehcache m2sampleCache1 = manager2.getCache("sampleCache1");
130 assertFalse(m1sampleCache1.getGuid().equals(m2sampleCache1.getGuid()));
131
132 List peerUrls2 = manager2.getCacheManagerPeerProvider("RMI").listRemoteCachePeers(m2sampleCache1);
133 assertEquals(expectedPeers(), peerUrls2.size());
134
135 Ehcache m3sampleCache1 = manager3.getCache("sampleCache1");
136 assertFalse(m1sampleCache1.getGuid().equals(m3sampleCache1.getGuid()));
137
138 List peerUrls3 = manager3.getCacheManagerPeerProvider("RMI").listRemoteCachePeers(m3sampleCache1);
139 assertEquals(expectedPeers(), peerUrls3.size());
140
141
142 manager1.shutdown();
143 Thread.sleep(5000);
144 peerUrls3 = manager3.getCacheManagerPeerProvider("RMI").listRemoteCachePeers(m3sampleCache1);
145 assertEquals(expectedPeers() - 1, peerUrls3.size());
146
147 }
148
149 /***
150 * The default caches for ehcache-dsitributed1-6.xml are set to replicate.
151 * We create a new cache from the default and expect it to be replicated.
152 */
153 @Test
154 public void testProviderCreatedFromDefaultCache() throws InterruptedException {
155
156
157
158 if (this.getClass() != MulticastRMIPeerProviderTest.class) {
159 return;
160 }
161
162 manager1.addCache("fromDefaultCache");
163 RMICacheManagerPeerListener peerListener1 = (RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI");
164
165 manager2.addCache("fromDefaultCache");
166 RMICacheManagerPeerListener peerListener2 = (RMICacheManagerPeerListener) manager2.getCachePeerListener("RMI");
167
168 manager3.addCache("fromDefaultCache");
169 RMICacheManagerPeerListener peerListener3 = (RMICacheManagerPeerListener) manager3.getCachePeerListener("RMI");
170
171 Thread.sleep(2000);
172
173 CacheManagerPeerProvider cachePeerProvider = manager1.getCacheManagerPeerProvider("RMI");
174
175 Cache cache = manager1.getCache("fromDefaultCache");
176 List peerUrls = cachePeerProvider.listRemoteCachePeers(cache);
177 assertEquals(expectedPeers(), peerUrls.size());
178
179 }
180
181
182 /***
183 * The default caches for ehcache-dsitributed1-6.xml are set to replicate.
184 * We create a new cache from the default and expect it to be replicated.
185 */
186 @Test
187 public void testDeleteReplicatedCache() throws InterruptedException {
188
189
190
191 if (this.getClass() != MulticastRMIPeerProviderTest.class) {
192 return;
193 }
194
195 manager1.addCache("fromDefaultCache");
196 manager2.addCache("fromDefaultCache");
197 manager3.addCache("fromDefaultCache");
198 Thread.sleep(2200);
199
200 CacheManagerPeerProvider cachePeerProvider = manager1.getCacheManagerPeerProvider("RMI");
201 Cache cache = manager1.getCache("fromDefaultCache");
202
203
204 List peerUrls = cachePeerProvider.listRemoteCachePeers(cache);
205 assertEquals(expectedPeers(), peerUrls.size());
206
207
208 manager1.removeCache("fromDefaultCache");
209 Thread.sleep(2200);
210
211 peerUrls = cachePeerProvider.listRemoteCachePeers(cache);
212 assertEquals(expectedPeers(), peerUrls.size());
213
214 }
215
216 /***
217 * There are 3 in the cluster, so there will be two others
218 */
219 protected int expectedPeers() {
220 return 2;
221 }
222
223
224 /***
225 * Determines that the multicast TTL default is 1, which means that packets are restricted to the same subnet.
226 * peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, multicastPacketTimeToLive=255
227 */
228 @Test
229 public void testMulticastTTL() throws IOException {
230 InetAddress groupAddress = InetAddress.getByName("230.0.0.1");
231 MulticastSocket socket = new MulticastSocket();
232 socket.joinGroup(groupAddress);
233 int ttl = socket.getTimeToLive();
234 assertEquals(1, ttl);
235 }
236
237 }