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.util.HashSet;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Properties;
26  
27  import org.apache.commons.jcs.auxiliary.MockCacheEventLogger;
28  import org.apache.commons.jcs.auxiliary.remote.MockRemoteCacheListener;
29  import org.apache.commons.jcs.auxiliary.remote.RemoteUtils;
30  import org.apache.commons.jcs.auxiliary.remote.server.behavior.IRemoteCacheServerAttributes;
31  import org.apache.commons.jcs.auxiliary.remote.server.behavior.RemoteType;
32  import org.apache.commons.jcs.engine.CacheElement;
33  import org.apache.commons.jcs.engine.behavior.ICacheElement;
34  import org.apache.commons.jcs.utils.timing.SleepUtil;
35  
36  import junit.framework.TestCase;
37  
38  /**
39   * Since the server does not know that it is a server, it is easy to unit test. The factory does all
40   * the rmi work.
41   * <p>
42   * @author Aaron Smuts
43   */
44  public class RemoteCacheServerUnitTest
45      extends TestCase
46  {
47      private static final String expectedIp1 = "adfasdf";
48      private static final String expectedIp2 = "adsfadsafaf";
49  
50      private RemoteCacheServer<String, String> server;
51  
52      @Override
53      protected void setUp() throws Exception
54      {
55          super.setUp();
56  
57          IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
58          rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
59          Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
60          this.server = new RemoteCacheServer<String, String>( rcsa, config );
61      }
62  
63      @Override
64      protected void tearDown() throws Exception
65      {
66          this.server.shutdown();
67  
68          super.tearDown();
69      }
70  
71      /**
72       * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
73       * and verify that the second gets an id of 2.
74       * <p>
75       * @throws Exception
76       */
77      public void testAddListenerToCache_LOCALtype()
78          throws Exception
79      {
80          MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<String, String>();
81          mockListener1.remoteType = RemoteType.LOCAL;
82          mockListener1.localAddress = expectedIp1;
83          MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<String, String>();
84          mockListener1.remoteType = RemoteType.LOCAL;
85          mockListener2.localAddress = expectedIp2;
86  
87          String cacheName = "testAddListener";
88  
89          // DO WORK
90          server.addCacheListener( cacheName, mockListener1 );
91          server.addCacheListener( cacheName, mockListener2 );
92  
93          // VERIFY
94          assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
95          assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
96          assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
97          assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
98      }
99  
100     /**
101      * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
102      * and verify that the second gets an id of 2.
103      * <p>
104      * @throws Exception
105      */
106     public void testAddListenerToCache_CLUSTERtype()
107         throws Exception
108     {
109         MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<String, String>();
110         mockListener1.remoteType = RemoteType.CLUSTER;
111         mockListener1.localAddress = expectedIp1;
112         MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<String, String>();
113         mockListener1.remoteType = RemoteType.CLUSTER;
114         mockListener2.localAddress = expectedIp2;
115 
116         String cacheName = "testAddListener";
117 
118         // DO WORK
119         server.addCacheListener( cacheName, mockListener1 );
120         server.addCacheListener( cacheName, mockListener2 );
121 
122         // VERIFY
123         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
124         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
125         assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
126         assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
127     }
128 
129     // TODO: This test only works if preconfigured remote caches exist. Need to fix.
130 //    /**
131 //     * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
132 //     * and verify that the second gets an id of 2.
133 //     * <p>
134 //     * @throws Exception
135 //     */
136 //    public void testAddListener_ToAll()
137 //        throws Exception
138 //    {
139 //        MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<String, String>();
140 //        mockListener1.localAddress = expectedIp1;
141 //        MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<String, String>();
142 //        mockListener2.localAddress = expectedIp2;
143 //
144 //        // DO WORK
145 //        // don't specify the cache name
146 //        server.addCacheListener( mockListener1 );
147 //        server.addCacheListener( mockListener2 );
148 //
149 //        // VERIFY
150 //        assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
151 //        assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
152 //        assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
153 //        assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
154 //    }
155 
156     /**
157      * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
158      * and verify that the second gets an id of 2. Call remove Listener and verify that it is
159      * removed.
160      * <p>
161      * @throws Exception
162      */
163     public void testAddListener_ToAllThenRemove()
164         throws Exception
165     {
166         MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<String, String>();
167         MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<String, String>();
168 
169         String cacheName = "testAddListenerToAllThenRemove";
170 
171         // DO WORK
172         server.addCacheListener( cacheName, mockListener1 );
173         server.addCacheListener( cacheName, mockListener2 );
174 
175         // VERIFY
176         assertEquals( "Wrong number of listeners.", 2, server.getCacheListeners( cacheName ).eventQMap.size() );
177         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
178         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
179 
180         // DO WORK
181         server.removeCacheListener( cacheName, mockListener1.getListenerId() );
182         assertEquals( "Wrong number of listeners.", 1, server.getCacheListeners( cacheName ).eventQMap.size() );
183     }
184 
185     /**
186      * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
187      * and verify that the second gets an id of 2. Call remove Listener and verify that it is
188      * removed.
189      * <p>
190      * @throws Exception
191      */
192     public void testAddListener_ToAllThenRemove_clusterType()
193         throws Exception
194     {
195         MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<String, String>();
196         mockListener1.remoteType = RemoteType.CLUSTER;
197         MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<String, String>();
198         mockListener2.remoteType = RemoteType.CLUSTER;
199 
200         String cacheName = "testAddListenerToAllThenRemove";
201 
202         // DO WORK
203         server.addCacheListener( cacheName, mockListener1 );
204         server.addCacheListener( cacheName, mockListener2 );
205 
206         // VERIFY
207         assertEquals( "Wrong number of listeners.", 0, server.getCacheListeners( cacheName ).eventQMap.size() );
208         assertEquals( "Wrong number of listeners.", 2, server.getClusterListeners( cacheName ).eventQMap.size() );
209         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
210         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
211 
212         // DO WORK
213         server.removeCacheListener( cacheName, mockListener1.getListenerId() );
214         assertEquals( "Wrong number of listeners.", 1, server.getClusterListeners( cacheName ).eventQMap.size() );
215         assertNull( "Should be no entry in the ip map.", server.getExtraInfoForRequesterId( 1 ) );
216     }
217 
218     /**
219      * Register a listener and then verify that it is called when we put using a different listener
220      * id.
221      * @throws Exception
222      */
223     public void testSimpleRegisterListenerAndPut()
224         throws Exception
225     {
226         IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
227         rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
228 
229         Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
230         MockRemoteCacheListener<String, Long> mockListener = new MockRemoteCacheListener<String, Long>();
231         RemoteCacheServer<String, Long> server = new RemoteCacheServer<String, Long>( rcsa, config );
232 
233         String cacheName = "testSimpleRegisterListenerAndPut";
234         server.addCacheListener( cacheName, mockListener );
235 
236         // DO WORK
237         List<ICacheElement<String, Long>> inputItems = new LinkedList<ICacheElement<String, Long>>();
238         int numToPut = 10;
239 
240         for ( int i = 0; i < numToPut; i++ )
241         {
242             ICacheElement<String, Long> element = new CacheElement<String, Long>( cacheName, String.valueOf( i ), Long.valueOf( i ) );
243             inputItems.add( element );
244             server.update( element, 9999 );
245         }
246 
247         Thread.sleep( 100 );
248         Thread.yield();
249         Thread.sleep( 100 );
250 
251         // VERIFY
252         assertEquals( "Wrong number of items put to listener.", numToPut, mockListener.putItems.size() );
253         for ( int i = 0; i < numToPut; i++ )
254         {
255             assertEquals( "Wrong item.", inputItems.get( i ), mockListener.putItems.get( i ) );
256         }
257 
258         server.shutdown();
259     }
260 
261     /**
262      * Register a listener and then verify that it is called when we put using a different listener
263      * id. The updates should come from a cluster listener and local cluster consistency should be
264      * true.
265      * <p>
266      * @throws Exception
267      */
268     public void testSimpleRegisterListenerAndPut_FromClusterWithLCC()
269         throws Exception
270     {
271         // SETUP
272         IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
273         rcsa.setLocalClusterConsistency( true );
274         rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
275         Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
276         RemoteCacheServer<String, Long> server = new RemoteCacheServer<String, Long>( rcsa, config );
277 
278         // this is to get the listener id for inserts.
279         MockRemoteCacheListener<String, Long> clusterListener = new MockRemoteCacheListener<String, Long>();
280         clusterListener.remoteType = RemoteType.CLUSTER;
281 
282         // this should get the updates
283         MockRemoteCacheListener<String, Long> localListener = new MockRemoteCacheListener<String, Long>();
284         localListener.remoteType = RemoteType.LOCAL;
285 
286         String cacheName = "testSimpleRegisterListenerAndPut_FromClusterWithLCC";
287         server.addCacheListener( cacheName, clusterListener );
288         server.addCacheListener( cacheName, localListener );
289 
290         // DO WORK
291         List<ICacheElement<String, Long>> inputItems = new LinkedList<ICacheElement<String,Long>>();
292         int numToPut = 10;
293 
294         for ( int i = 0; i < numToPut; i++ )
295         {
296             ICacheElement<String, Long> element = new CacheElement<String, Long>( cacheName, String.valueOf( i ), Long.valueOf( i ) );
297             inputItems.add( element );
298             // update using the cluster listener id
299             server.update( element, clusterListener.getListenerId() );
300         }
301 
302         SleepUtil.sleepAtLeast( 200 );
303         Thread.yield();
304         SleepUtil.sleepAtLeast( 200 );
305 
306         // VERIFY
307         assertEquals( "Wrong number of items put to listener.", numToPut, localListener.putItems.size() );
308         for ( int i = 0; i < numToPut; i++ )
309         {
310             assertEquals( "Wrong item.", inputItems.get( i ), localListener.putItems.get( i ) );
311         }
312 
313         server.shutdown();
314     }
315 
316     /**
317      * Register a listener and then verify that it is called when we put using a different listener
318      * id.
319      * @throws Exception
320      */
321     public void testSimpleRegisterListenerAndRemove()
322         throws Exception
323     {
324         MockRemoteCacheListener<String, String> mockListener = new MockRemoteCacheListener<String, String>();
325 
326         String cacheName = "testSimpleRegisterListenerAndPut";
327         server.addCacheListener( cacheName, mockListener );
328 
329         // DO WORK
330         int numToPut = 10;
331 
332         for ( int i = 0; i < numToPut; i++ )
333         {
334             // use a junk listener id
335             server.remove( cacheName, String.valueOf( i ), 9999 );
336         }
337 
338         Thread.sleep( 100 );
339         Thread.yield();
340         Thread.sleep( 100 );
341 
342         // VERIFY
343         assertEquals( "Wrong number of items removed from listener.", numToPut, mockListener.removedKeys.size() );
344         for ( int i = 0; i < numToPut; i++ )
345         {
346             assertEquals( "Wrong key.", String.valueOf( i ), mockListener.removedKeys.get( i ) );
347         }
348     }
349 
350     /**
351      * Verify event log calls.
352      * <p>
353      * @throws Exception
354      */
355     public void testUpdate_simple()
356         throws Exception
357     {
358         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
359         server.setCacheEventLogger( cacheEventLogger );
360 
361         ICacheElement<String, String> item = new CacheElement<String, String>( "region", "key", "value" );
362 
363         // DO WORK
364         server.update( item );
365 
366         // VERIFY
367         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
368         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
369     }
370 
371     /**
372      * Verify event log calls.
373      * <p>
374      * @throws Exception
375      */
376     public void testGet_simple()
377         throws Exception
378     {
379         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
380         server.setCacheEventLogger( cacheEventLogger );
381 
382         // DO WORK
383         server.get( "region", "key" );
384 
385         // VERIFY
386         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
387         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
388     }
389 
390     /**
391      * Verify event log calls.
392      * <p>
393      * @throws Exception
394      */
395     public void testGetMatching_simple()
396         throws Exception
397     {
398         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
399         server.setCacheEventLogger( cacheEventLogger );
400 
401         // DO WORK
402         server.getMatching( "region", "pattern", 0 );
403 
404         // VERIFY
405         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
406         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
407     }
408 
409     /**
410      * Verify event log calls.
411      * <p>
412      * @throws Exception
413      */
414     public void testGetMultiple_simple()
415         throws Exception
416     {
417         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
418         server.setCacheEventLogger( cacheEventLogger );
419 
420         // DO WORK
421         server.getMultiple( "region", new HashSet<String>() );
422 
423         // VERIFY
424         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
425         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
426     }
427 
428     /**
429      * Verify event log calls.
430      * <p>
431      * @throws Exception
432      */
433     public void testRemove_simple()
434         throws Exception
435     {
436         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
437         server.setCacheEventLogger( cacheEventLogger );
438 
439         // DO WORK
440         server.remove( "region", "key" );
441 
442         // VERIFY
443         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
444         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
445     }
446 
447     /**
448      * Verify event log calls.
449      * <p>
450      * @throws Exception
451      */
452     public void testRemoveAll_simple()
453         throws Exception
454     {
455         MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
456         server.setCacheEventLogger( cacheEventLogger );
457 
458         // DO WORK
459         server.removeAll( "region" );
460 
461         // VERIFY
462         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
463         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
464     }
465 }