1 /**
2 * Copyright 2003-2006 Greg Luck
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 junit.framework.TestCase;
20 import net.sf.ehcache.Cache;
21 import net.sf.ehcache.CacheManager;
22 import net.sf.ehcache.Element;
23 import net.sf.ehcache.AbstractCacheTest;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.net.SocketTimeoutException;
28 import java.rmi.RemoteException;
29 import java.rmi.UnmarshalException;
30 import java.util.Date;
31 import java.util.List;
32 import java.util.ArrayList;
33
34 /**
35 * Unit tests for RMICachePeer
36 *
37 * Note these tests need a live network interface running in multicast mode to work
38 *
39 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
40 * @version $Id: RMICacheManagerPeerTest.java 52 2006-04-24 14:50:03Z gregluck $
41 */
42 public class RMICacheManagerPeerTest extends TestCase {
43
44 private static final Log LOG = LogFactory.getLog(RMICacheManagerPeerTest.class.getName());
45
46
47 /**
48 * manager
49 */
50 protected CacheManager manager;
51 private String hostName = "localhost";
52 private Integer port = new Integer(40000);
53 private RMICacheManagerPeerListener peerListener;
54 private Cache cache;
55
56
57 /**
58 * {@inheritDoc}
59 *
60 * @throws Exception
61 */
62 protected void setUp() throws Exception {
63 manager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
64 cache = new Cache("test", 10, false, false, 10, 10);
65 peerListener = new RMICacheManagerPeerListener(hostName, port, manager, new Integer(2000));
66 }
67
68 /**
69 * Shutdown the cache
70 */
71 protected void tearDown() throws InterruptedException {
72 Thread.sleep(10);
73 if (peerListener != null) {
74 peerListener.dispose();
75 }
76 manager.shutdown();
77 }
78
79
80 /**
81 * Can we create the peer?
82 */
83 public void testCreatePeer() throws RemoteException {
84 for (int i = 0; i < 10; i++) {
85 new RMICachePeer(cache, hostName, port, new Integer(2000));
86 }
87 }
88
89
90 /**
91 * See if socket.setSoTimeout(socketTimeoutMillis) works. Should throw a SocketTimeoutException
92 *
93 * @throws RemoteException
94 */
95 public void testFailsIfTimeoutExceeded() throws Exception {
96
97 RMICachePeer rmiCachePeer = new SlowRMICachePeer(cache, hostName, port, new Integer(1000));
98 peerListener.getCachePeers().add(rmiCachePeer);
99 peerListener.init();
100
101 try {
102 CachePeer cachePeer = RMICacheManagerPeerProvider.lookupRemoteCachePeer(rmiCachePeer.getUrl());
103 cachePeer.put(new Element("1", new Date()));
104 fail();
105 } catch (UnmarshalException e) {
106 assertEquals(SocketTimeoutException.class, e.getCause().getClass());
107 }
108 }
109
110 /**
111 * See if socket.setSoTimeout(socketTimeoutMillis) works.
112 * Should not fail because the put takes less than the timeout.
113 *
114 * @throws RemoteException
115 */
116 public void testWorksIfTimeoutNotExceeded() throws Exception {
117
118 cache = new Cache("test", 10, false, false, 10, 10);
119 RMICachePeer rmiCachePeer = new SlowRMICachePeer(cache, hostName, port, new Integer(2100));
120
121 peerListener.getCachePeers().add(rmiCachePeer);
122 peerListener.init();
123
124 CachePeer cachePeer = RMICacheManagerPeerProvider.lookupRemoteCachePeer(rmiCachePeer.getUrl());
125 cachePeer.put(new Element("1", new Date()));
126 }
127
128 /**
129 * Test send.
130 * <p/>
131 * This is a unit test because it was throwing AbstractMethodError if a method has changed signature,
132 * or NoSuchMethodError is a new one is added. The problem is that rmic needs
133 * to recompile the stub after any changes are made to the CachePeer source, something done by ant
134 * compile but not by the IDE.
135 */
136 public void testSend() throws Exception {
137
138 cache = new Cache("test", 10, false, false, 10, 10);
139 RMICachePeer rmiCachePeer = new RMICachePeer(cache, hostName, port, new Integer(2100));
140 manager.addCache(cache);
141
142 peerListener.getCachePeers().add(rmiCachePeer);
143 peerListener.init();
144
145 CachePeer cachePeer = RMICacheManagerPeerProvider.lookupRemoteCachePeer(rmiCachePeer.getUrl());
146 Element element = new Element("1", new Date());
147 EventMessage eventMessage = new EventMessage(EventMessage.PUT, null, element);
148 List eventMessages = new ArrayList();
149 eventMessages.add(eventMessage);
150 cachePeer.send(eventMessages);
151 }
152
153
154 /**
155 * RMICachePeer that breaks in lots of interesting ways.
156 */
157 class SlowRMICachePeer extends RMICachePeer {
158
159 /**
160 * Constructor
161 * @param cache
162 * @param hostName
163 * @param port
164 * @param socketTimeoutMillis
165 * @throws RemoteException
166 */
167 public SlowRMICachePeer(Cache cache, String hostName, Integer port, Integer socketTimeoutMillis) throws RemoteException {
168 super(cache, hostName, port, socketTimeoutMillis);
169 }
170
171 /**
172 * Puts an Element into the underlying cache without notifying listeners or updating statistics.
173 *
174 * @param element
175 * @throws java.rmi.RemoteException
176 * @throws IllegalArgumentException
177 * @throws IllegalStateException
178 */
179 public void put(Element element) throws RemoteException, IllegalArgumentException, IllegalStateException {
180 try {
181 Thread.sleep(2000);
182 } catch (InterruptedException exception) {
183 LOG.debug(exception.getMessage(), exception);
184 }
185 }
186 }
187 }