View Javadoc
1   package org.apache.commons.jcs.auxiliary.remote.server;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.net.InetAddress;
24  import java.net.NetworkInterface;
25  import java.util.Enumeration;
26  
27  import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
28  import org.apache.commons.jcs.auxiliary.MockCacheEventLogger;
29  import org.apache.commons.jcs.auxiliary.remote.MockRemoteCacheListener;
30  import org.apache.commons.jcs.auxiliary.remote.RemoteCacheAttributes;
31  import org.apache.commons.jcs.auxiliary.remote.RemoteCacheFactory;
32  import org.apache.commons.jcs.auxiliary.remote.RemoteCacheManager;
33  import org.apache.commons.jcs.engine.CacheElement;
34  import org.apache.commons.jcs.engine.CacheStatus;
35  import org.apache.commons.jcs.engine.behavior.ICacheElement;
36  import org.apache.commons.jcs.engine.control.MockCompositeCacheManager;
37  import org.apache.commons.jcs.engine.control.MockElementSerializer;
38  import org.apache.commons.jcs.utils.net.HostNameUtil;
39  import org.apache.commons.jcs.utils.timing.SleepUtil;
40  import org.junit.AfterClass;
41  import org.junit.Assert;
42  import org.junit.BeforeClass;
43  import org.junit.FixMethodOrder;
44  import org.junit.Test;
45  import org.junit.runners.MethodSorters;
46  
47  /**
48   * These tests startup the remote server and make requests to it.
49   * <p>
50   *
51   * @author Aaron Smuts
52   */
53  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
54  public class BasicRemoteCacheClientServerUnitTest extends Assert
55  {
56      private static final int LOCAL_PORT = 12020;
57  
58     /**
59       * Server instance to use in the tests.
60       */
61      private static RemoteCacheServer<String, String> server = null;
62  
63      /**
64       * Factory instance to use in the tests.
65       */
66      private static RemoteCacheFactory factory = null;
67  
68      /**
69       * the remote server port
70       */
71      private static int remotePort;
72  
73      /**
74       * Starts the server. This is not in a setup, since the server is slow to kill right now.
75       */
76      @BeforeClass
77      public static void setup()
78      {
79          // Add some debug to try and find out why test fails on Jenkins/Continuum
80          try {
81              InetAddress lh = InetAddress.getByName("localhost");
82              System.out.println("localhost="+lh);
83              InetAddress ina=InetAddress.getLocalHost();
84              System.out.println("InetAddress.getLocalHost()="+ina);
85              // Iterate all NICs (network interface cards)...
86              for ( Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); )
87              {
88                  NetworkInterface iface = ifaces.nextElement();
89                  // Iterate all IP addresses assigned to each card...
90                  for ( Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); )
91                  {
92                      InetAddress inetAddr = inetAddrs.nextElement();
93                      boolean loopbackAddress = inetAddr.isLoopbackAddress();
94                      boolean siteLocalAddress = inetAddr.isSiteLocalAddress();
95                      System.out.println("Found: "+ inetAddr +
96                              " isLoopback: " + loopbackAddress +
97                              " isSiteLocal: " + siteLocalAddress +
98                              ((!loopbackAddress && siteLocalAddress) ? " *" : ""));
99                  }
100             }
101         } catch (Exception e) {
102             e.printStackTrace();
103         }
104         // end of debug
105         String configFile = "TestRemoteCacheClientServer.ccf";
106         server = RemoteCacheServerStartupUtil.startServerUsingProperties(configFile);
107         factory = new RemoteCacheFactory();
108         factory.initialize();
109         remotePort = server.remoteCacheServerAttributes.getRemoteLocation().getPort();
110     }
111 
112     @AfterClass
113     public static void stop() throws IOException
114     {
115         if (server != null) { // in case setup failed, no point throwing NPE as well
116             server.shutdown("localhost", remotePort);
117         }
118         // Debug: unfortunately Surefire restarts JVM so log files get overwritten
119         // There's probably a better way to fix this ...
120         java.io.File jcsLog = new java.io.File("target/jcs.log");
121         java.io.File logSave = new java.io.File("target/BasicRemoteCacheClientServerUnitTest_jcs.log");
122         System.out.println("Renamed log file? "+jcsLog.renameTo(logSave));
123     }
124 
125     /**
126      * Verify that we can start the remote cache server. Send an item to the remote. Verify that the
127      * remote put count goes up. If we go through JCS, the manager will be shared and we will get
128      * into an endless loop. We will use a mock cache manager instead.
129      * <p>
130      * The remote server uses the real JCS. We can verify that items are added to JCS behind the
131      * server by calling get. We cannot access it directly via JCS since it is serialized.
132      * <p>
133      * This test uses a mock injected client to test a normal server.
134      * <p>
135      *
136      * @throws Exception
137      */
138     @Test
139     public void test1SinglePut()
140             throws Exception
141             {
142         // SETUP
143         MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
144 
145         RemoteCacheAttributes attributes = new RemoteCacheAttributes();
146         attributes.setRemoteLocation("localhost", remotePort);
147         attributes.setLocalPort(LOCAL_PORT);
148         attributes.setCacheName("testSinglePut");
149 
150         RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
151         AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
152 
153         // DO WORK
154         int numPutsPrior = server.getPutCount();
155         ICacheElement<String, String> element = new CacheElement<String, String>(cache.getCacheName(), "key", "value");
156         cache.update(element);
157         SleepUtil.sleepAtLeast(200);
158 
159         // VERIFY
160         try
161         {
162             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
163             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
164         }
165         catch (junit.framework.AssertionFailedError e)
166         {
167             System.out.println(cache.getStats());
168             System.out.println(server.getStats());
169             throw e;
170         }
171 
172         // DO WORK
173         ICacheElement<String, String> result = cache.get("key");
174 
175         // VERIFY
176         assertEquals("Wrong element.", element.getVal(), result.getVal());
177             }
178 
179     /**
180      * Verify that we can remove an item via the remote server.
181      * <p>
182      *
183      * @throws Exception
184      */
185     @Test
186     public void test2PutRemove()
187             throws Exception
188             {
189         // SETUP
190         MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
191 
192         RemoteCacheAttributes attributes = new RemoteCacheAttributes();
193         attributes.setRemoteLocation("localhost", remotePort);
194         attributes.setLocalPort(LOCAL_PORT);
195         attributes.setCacheName("testPutRemove");
196 
197         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
198 
199         RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, cacheEventLogger, null);
200         AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
201 
202         // DO WORK
203         int numPutsPrior = server.getPutCount();
204         ICacheElement<String, String> element = new CacheElement<String, String>(cache.getCacheName(), "key", "value");
205         cache.update(element);
206         SleepUtil.sleepAtLeast(50);
207 
208         // VERIFY
209         try
210         {
211             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
212             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
213         }
214         catch (junit.framework.AssertionFailedError e)
215         {
216             System.out.println(cache.getStats());
217             System.out.println(server.getStats());
218             throw e;
219         }
220 
221         // DO WORK
222         ICacheElement<String, String> result = cache.get("key");
223 
224         // VERIFY
225         assertEquals("Wrong element.", element.getVal(), result.getVal());
226 
227         // DO WORK
228         cache.remove("key");
229         SleepUtil.sleepAtLeast(200);
230         ICacheElement<String, String> resultAfterRemote = cache.get("key");
231 
232         // VERIFY
233         assertNull("Element resultAfterRemote should be null.", resultAfterRemote);
234             }
235 
236     /**
237      * Register a listener with the server. Send an update. Verify that the listener received it.
238      *
239      * @throws Exception
240      */
241     @Test
242     public void test3PutAndListen()
243             throws Exception
244             {
245         // SETUP
246         MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
247 
248         RemoteCacheAttributes attributes = new RemoteCacheAttributes();
249         attributes.setRemoteLocation("localhost", remotePort);
250         attributes.setLocalPort(LOCAL_PORT);
251         attributes.setCacheName("testPutAndListen");
252 
253         RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
254         AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
255 
256         MockRemoteCacheListener<String, String> listener = new MockRemoteCacheListener<String, String>();
257         server.addCacheListener(cache.getCacheName(), listener);
258 
259         // DO WORK
260         int numPutsPrior = server.getPutCount();
261         ICacheElement<String, String> element = new CacheElement<String, String>(cache.getCacheName(), "key", "value");
262         cache.update(element);
263         SleepUtil.sleepAtLeast(50);
264 
265         // VERIFY
266         try
267         {
268             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
269             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
270             assertEquals("Wrong number of puts to listener.", 1, listener.putCount);
271         }
272         catch (junit.framework.AssertionFailedError e)
273         {
274             System.out.println(cache.getStats());
275             System.out.println(server.getStats());
276             throw e;
277         }
278         finally
279         {
280             // remove from all regions.
281             server.removeCacheListener(listener);
282         }
283     }
284 
285     /**
286      * Register a listener with the server. Send an update. Verify that the listener received it.
287      *
288      * @throws Exception
289      */
290     @Test
291     public void test4PutaMultipleAndListen()
292             throws Exception
293     {
294         // SETUP
295         MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
296 
297         RemoteCacheAttributes attributes = new RemoteCacheAttributes();
298         attributes.setRemoteLocation("localhost", remotePort);
299         attributes.setLocalPort(LOCAL_PORT);
300         attributes.setCacheName("testPutaMultipleAndListen");
301 
302         RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
303         AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
304 
305         MockRemoteCacheListener<String, String> listener = new MockRemoteCacheListener<String, String>();
306         server.addCacheListener(cache.getCacheName(), listener);
307 
308         // DO WORK
309         int numPutsPrior = server.getPutCount();
310         int numToPut = 100;
311         for (int i = 0; i < numToPut; i++)
312         {
313             ICacheElement<String, String> element = new CacheElement<String, String>(cache.getCacheName(), "key" + 1, "value" + i);
314             cache.update(element);
315         }
316         SleepUtil.sleepAtLeast(500);
317 
318         // VERIFY
319         try
320         {
321             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
322             assertEquals("Wrong number of puts", numToPut, server.getPutCount() - numPutsPrior);
323             assertEquals("Wrong number of puts to listener.", numToPut, listener.putCount);
324         }
325         catch (junit.framework.AssertionFailedError e)
326         {
327             System.out.println(cache.getStats());
328             System.out.println(server.getStats());
329             throw e;
330         }
331     }
332 
333     @Test
334     public void testLocalHost() throws Exception
335     {
336         final InetAddress byName = InetAddress.getByName("localhost");
337         assertTrue("Expected localhost (" + byName.getHostAddress() + ") to be a loopback address", byName.isLoopbackAddress());
338         final InetAddress localHost = HostNameUtil.getLocalHostLANAddress();
339         assertTrue("Expected getLocalHostLANAddress() (" + localHost + ") to return a site local address", localHost.isSiteLocalAddress());
340     }
341 }