Clover coverage report -
Coverage timestamp: Wed Jan 31 2007 15:38:53 EST
file stats: LOC: 498   Methods: 14
NCLOC: 251   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
RemoteCacheListenerTest.java 40% 97% 92.9% 93.6%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source.
 3    * Copyright 2006, Red Hat Middleware LLC, and individual contributors
 4    * as indicated by the @author tags. See the copyright.txt file in the
 5    * distribution for a full listing of individual contributors.
 6    *
 7    * This is free software; you can redistribute it and/or modify it
 8    * under the terms of the GNU Lesser General Public License as
 9    * published by the Free Software Foundation; either version 2.1 of
 10    * the License, or (at your option) any later version.
 11    *
 12    * This software is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15    * Lesser General Public License for more details.
 16    *
 17    * You should have received a copy of the GNU Lesser General Public
 18    * License along with this software; if not, write to the Free
 19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21    */
 22   
 23    package org.jboss.cache.notifications;
 24   
 25    import junit.framework.TestCase;
 26    import org.jboss.cache.AbstractCacheListener;
 27    import org.jboss.cache.Cache;
 28    import org.jboss.cache.DefaultCacheFactory;
 29    import org.jboss.cache.Fqn;
 30    import org.jboss.cache.Node;
 31    import org.jboss.cache.config.Configuration;
 32    import org.jboss.cache.lock.IsolationLevel;
 33   
 34    import javax.transaction.TransactionManager;
 35    import java.util.ArrayList;
 36    import java.util.Collections;
 37    import java.util.HashMap;
 38    import java.util.List;
 39    import java.util.Map;
 40   
 41    /**
 42    * Remote conterpart of CacheListenerTest. Main difference is event is originating as local.
 43    *
 44    * @author Ben Wang
 45    * @since 2.0.0
 46    */
 47    public class RemoteCacheListenerTest extends TestCase
 48    {
 49   
 50    protected boolean optLocking = false;
 51   
 52    private Cache cache1, cache2;
 53    private EventLog eventLog1 = new EventLog(), eventLog2 = new EventLog();
 54    private Fqn fqn = Fqn.fromString("/test");
 55   
 56  12 protected void setUp() throws Exception
 57    {
 58  12 super.setUp();
 59  12 Configuration c = new Configuration();
 60  12 c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
 61  12 c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
 62  6 if (optLocking) c.setNodeLockingScheme(Configuration.NodeLockingScheme.OPTIMISTIC);
 63  12 c.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
 64  12 c.setFetchInMemoryState(false);
 65   
 66    // we need this because notifications emitted by the notification interceptor are done during the commit call.
 67    // If we want to check notifications on remote nodes we need to make sure the commit completes before we test anything.
 68  12 c.setSyncCommitPhase(true);
 69   
 70    // more time to help with debugging
 71  12 c.setSyncReplTimeout(60000);
 72   
 73  12 cache1 = DefaultCacheFactory.getInstance().createCache(c);
 74  12 cache2 = DefaultCacheFactory.getInstance().createCache(c.clone());
 75   
 76  12 eventLog1.events.clear();
 77  12 eventLog2.events.clear();
 78   
 79  12 cache1.addCacheListener(eventLog1);
 80  12 cache2.addCacheListener(eventLog2);
 81    }
 82   
 83  12 protected void tearDown() throws Exception
 84    {
 85  12 super.tearDown();
 86  12 TransactionManager tm;
 87  ? if ((tm = cache1.getConfiguration().getRuntimeConfig().getTransactionManager()) != null)
 88    {
 89  12 if (tm.getTransaction() != null)
 90    {
 91  0 try
 92    {
 93  0 tm.rollback();
 94    }
 95    catch (Exception e)
 96    {
 97    // do nothing
 98    }
 99    }
 100    }
 101  ? if ((tm = cache2.getConfiguration().getRuntimeConfig().getTransactionManager()) != null)
 102    {
 103  12 if (tm.getTransaction() != null)
 104    {
 105  0 try
 106    {
 107  0 tm.rollback();
 108    }
 109    catch (Exception e)
 110    {
 111    // do nothing
 112    }
 113    }
 114    }
 115   
 116  12 cache1.stop();
 117  12 cache1.destroy();
 118  12 cache2.stop();
 119  12 cache2.destroy();
 120    }
 121   
 122    // simple tests first
 123   
 124  2 public void testCreation() throws Exception
 125    {
 126  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 127  2 cache1.put(fqn, "key", "value");
 128  2 Map data = new HashMap();
 129  2 data.put("key", "value");
 130   
 131    //expectedRemote
 132  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 133  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, true, true, null));
 134  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, false, true, null));
 135  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, true, Collections.emptyMap()));
 136  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, true, data));
 137   
 138    //expectedRemote
 139  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 140  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, true, false, null));
 141  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, false, false, null));
 142  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, false, Collections.emptyMap()));
 143  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, false, data));
 144   
 145  2 assertEquals(expectedLocal, eventLog1.events);
 146  2 assertEquals(expectedRemote, eventLog2.events);
 147  2 assertEquals("value", cache1.get(fqn, "key"));
 148    }
 149   
 150  2 public void testOnlyModification() throws Exception
 151    {
 152  2 assertNull(cache1.get(fqn, "key"));
 153  2 assertNull(cache2.get(fqn, "key"));
 154   
 155  2 cache1.put(fqn, "key", "value");
 156  2 Map oldData = new HashMap();
 157  2 oldData.put("key", "value");
 158   
 159  2 assertEquals("value", cache1.get(fqn, "key"));
 160  2 assertEquals("value", cache2.get(fqn, "key"));
 161   
 162    // clear event log
 163  2 eventLog1.events.clear();
 164  2 eventLog2.events.clear();
 165  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog1.events);
 166  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 167   
 168    // modify existing node
 169  2 cache1.put(fqn, "key", "value2");
 170  2 Map newData = new HashMap();
 171  2 newData.put("key", "value2");
 172   
 173    //expectedLocal
 174  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 175  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, true, oldData));
 176  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, true, newData));
 177   
 178    //expectedRemote
 179  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 180  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, false, oldData));
 181  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, false, newData));
 182   
 183  2 assertEquals(expectedLocal, eventLog1.events);
 184  2 assertEquals(expectedRemote, eventLog2.events);
 185    }
 186   
 187   
 188  2 public void testOnlyRemoval() throws Exception
 189    {
 190  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 191  2 cache1.put(fqn, "key", "value");
 192  2 Map oldData = new HashMap();
 193  2 oldData.put("key", "value");
 194   
 195  2 assertEquals("value", cache1.get(fqn, "key"));
 196  2 assertEquals("value", cache2.get(fqn, "key"));
 197   
 198    // clear event log
 199  2 eventLog1.events.clear();
 200  2 eventLog2.events.clear();
 201  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog1.events);
 202  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 203   
 204    // modify existing node
 205  2 cache1.removeNode(fqn);
 206   
 207    //expectedLocal
 208  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 209  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_REMOVED, fqn, true, true, oldData));
 210  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_REMOVED, fqn, false, true, null));
 211   
 212    //expectedRemote
 213  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 214  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_REMOVED, fqn, true, false, oldData));
 215  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_REMOVED, fqn, false, false, null));
 216   
 217  2 assertEquals(expectedLocal, eventLog1.events);
 218  2 assertEquals(expectedRemote, eventLog2.events);
 219   
 220    // test that the node has in fact been removed.
 221  2 assertNull("Should be null", cache1.getRoot().getChild(fqn));
 222    }
 223   
 224   
 225  2 public void testRemoveData() throws Exception
 226    {
 227  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 228  2 cache1.put(fqn, "key", "value");
 229  2 cache1.put(fqn, "key2", "value2");
 230  2 Map oldData = new HashMap();
 231  2 oldData.put("key", "value");
 232  2 oldData.put("key2", "value2");
 233   
 234    // clear event log
 235  2 eventLog1.events.clear();
 236  2 eventLog2.events.clear();
 237  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog1.events);
 238  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 239   
 240    // modify existing node
 241  2 cache1.remove(fqn, "key2");
 242  2 Map removed = new HashMap();
 243  2 removed.put("key2", "value2");
 244   
 245    //expectedLocal
 246  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 247  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, true, oldData));
 248  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, true, removed));
 249   
 250    //expectedRemote
 251  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 252  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, false, oldData));
 253  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, false, removed));
 254   
 255  2 assertEquals(expectedLocal, eventLog1.events);
 256  2 assertEquals(expectedRemote, eventLog2.events);
 257    }
 258   
 259  2 public void testPutMap() throws Exception
 260    {
 261  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 262  2 Map oldData = new HashMap();
 263  2 oldData.put("key", "value");
 264  2 oldData.put("key2", "value2");
 265   
 266  2 assertNull(cache1.getRoot().getChild(fqn));
 267  2 assertNull(cache2.getRoot().getChild(fqn));
 268   
 269    // clear event log
 270  2 eventLog1.events.clear();
 271  2 eventLog2.events.clear();
 272  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog1.events);
 273  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 274   
 275  2 cache1.put(fqn, oldData);
 276   
 277    //expectedLocal
 278  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 279  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, true, true, null));
 280  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, false, true, null));
 281  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, true, Collections.emptyMap()));
 282  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, true, oldData));
 283   
 284    //expectedRemote
 285  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 286  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, true, false, null));
 287  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, false, false, null));
 288  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, true, false, Collections.emptyMap()));
 289  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, false, false, oldData));
 290   
 291  2 assertEquals(expectedLocal, eventLog1.events);
 292  2 assertEquals(expectedRemote, eventLog2.events);
 293    }
 294   
 295  2 public void testMove()
 296    {
 297  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 298  2 Fqn newParent = Fqn.fromString("/a");
 299  2 cache1.put(fqn, "key", "value");
 300  2 cache1.put(newParent, "key", "value");
 301   
 302  2 Node n1 = cache1.getRoot().getChild(fqn);
 303  2 Node n2 = cache1.getRoot().getChild(newParent);
 304   
 305  2 eventLog1.events.clear();
 306  2 eventLog2.events.clear();// clear events
 307  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog1.events);
 308  2 assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 309   
 310  2 cache1.move(n1.getFqn(), n2.getFqn());
 311  2 Fqn newFqn = new Fqn(newParent, fqn.getLastElement());
 312   
 313    //expectedLocal
 314  2 List<CacheListenerEvent> expectedLocal = new ArrayList<CacheListenerEvent>();
 315  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MOVED, fqn, newFqn, true, true));
 316  2 expectedLocal.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MOVED, fqn, newFqn, false, true));
 317   
 318    //expectedRemote
 319  2 List<CacheListenerEvent> expectedRemote = new ArrayList<CacheListenerEvent>();
 320  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MOVED, fqn, newFqn, true, false));
 321  2 expectedRemote.add(new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MOVED, fqn, newFqn, false, false));
 322   
 323  2 assertEquals(expectedLocal, eventLog1.events);
 324  2 assertEquals(expectedRemote, eventLog2.events);
 325    }
 326   
 327    // -- now the transactional ones
 328   
 329    /*
 330    // TODO: Reinstate these once we have a proper plan for dealing with transactions and notifications.
 331   
 332    public void testTxCreationCommit() throws Exception
 333    {
 334    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 335    tm.begin();
 336    cache1.put(fqn, "key", "value");
 337    // assertEquals("Events log should be empty until commit time", 0, eventLog2.events.size());
 338    tm.commit();
 339   
 340    Map data = new HashMap();
 341    data.put("key", "value");
 342   
 343    //expected
 344    List<CacheListenerEvent> expected = new ArrayList<CacheListenerEvent>();
 345    expected.add(new CacheListenerEvent(RemoteCacheListenerTest.ListenerMethod.NODE_CREATED, fqn, true, false, null));
 346    expected.add(new CacheListenerEvent(RemoteCacheListenerTest.ListenerMethod.NODE_CREATED, fqn, false, false, null));
 347    expected.add(new CacheListenerEvent(RemoteCacheListenerTest.ListenerMethod.NODE_MODIFIED, fqn, true, false, Collections.emptyMap()));
 348    expected.add(new CacheListenerEvent(RemoteCacheListenerTest.ListenerMethod.NODE_MODIFIED, fqn, false, false, data));
 349   
 350    assertEquals(expected, eventLog2.events);
 351    assertEquals("value", cache1.get(fqn, "key"));
 352    }
 353   
 354    public void testTxCreationRollback() throws Exception
 355    {
 356    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 357    tm.begin();
 358    cache1.put(fqn, "key", "value");
 359    assertEquals("Events log should be empty until commit time", 0, eventLog2.events.size());
 360    tm.rollback();
 361    assertEquals("Events log should be empty until commit time", 0, eventLog2.events.size());
 362    }
 363   
 364   
 365    public void testTxOnlyModification() throws Exception
 366    {
 367    fail("implement me");
 368    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 369    cache1.put(fqn, "key", "value");
 370    Map oldData = new HashMap();
 371    oldData.put("key", "value");
 372   
 373    // clear event log
 374    eventLog2.events.clear();
 375    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 376   
 377    // modify existing node
 378    cache1.put(fqn, "key", "value2");
 379    Map newData = new HashMap();
 380    newData.put("key", "value2");
 381   
 382    //expected
 383    List<Event> expected = new ArrayList<Event>();
 384    expected.add(new Event(ListenerMethod.NODE_MODIFIED, fqn, true, true, oldData));
 385    expected.add(new Event(ListenerMethod.NODE_MODIFIED, fqn, false, true, newData));
 386   
 387    assertEquals(expected, eventLog2.events);
 388    }
 389   
 390   
 391    public void testTxOnlyRemoval() throws Exception
 392    {
 393    fail("implement me");
 394    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 395    cache1.put(fqn, "key", "value");
 396    Map oldData = new HashMap();
 397    oldData.put("key", "value");
 398   
 399    assertEquals("value", cache1.get(fqn, "key"));
 400   
 401    // clear event log
 402    eventLog2.events.clear();
 403    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 404   
 405    // modify existing node
 406    cache1.removeNode(fqn);
 407   
 408    //expected
 409    List<Event> expected = new ArrayList<Event>();
 410    expected.add(new Event(ListenerMethod.NODE_REMOVED, fqn, true, true, oldData));
 411    expected.add(new Event(ListenerMethod.NODE_REMOVED, fqn, false, true, null));
 412   
 413    assertEquals(expected, eventLog2.events);
 414   
 415    // test that the node has in fact been removed.
 416    assertNull("Should be null", cache1.getChild(fqn));
 417    }
 418   
 419   
 420    public void testTxRemoveData() throws Exception
 421    {
 422    fail("implement me");
 423    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 424    cache1.put(fqn, "key", "value");
 425    cache1.put(fqn, "key2", "value2");
 426    Map oldData = new HashMap();
 427    oldData.put("key", "value");
 428    oldData.put("key2", "value2");
 429   
 430    // clear event log
 431    eventLog2.events.clear();
 432    assertEquals("Event log should be empty", Collections.emptyList(), eventLog2.events);
 433   
 434    // modify existing node
 435    cache1.remove(fqn, "key2");
 436    Map newData = new HashMap();
 437    newData.put("key", "value");
 438   
 439    //expected
 440    List<Event> expected = new ArrayList<Event>();
 441    expected.add(new Event(ListenerMethod.NODE_MODIFIED, fqn, true, true, oldData));
 442    expected.add(new Event(ListenerMethod.NODE_MODIFIED, fqn, false, true, newData));
 443   
 444    assertEquals(expected, eventLog2.events);
 445    }
 446   
 447    public void testTxMove()
 448    {
 449    fail("implement me");
 450    }
 451    */
 452   
 453    // ============= supporting classes and enums =======================
 454   
 455   
 456    public static class EventLog extends AbstractCacheListener
 457    {
 458    public final List<CacheListenerEvent> events = new ArrayList<CacheListenerEvent>();
 459   
 460  56 public void nodeCreated(Fqn fqn, boolean pre, boolean isLocal)
 461    {
 462  56 CacheListenerEvent e = new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_CREATED, fqn, pre, isLocal, null);
 463  56 events.add(e);
 464    }
 465   
 466  8 public void nodeRemoved(Fqn fqn, boolean pre, boolean isLocal, Map data)
 467    {
 468  8 CacheListenerEvent e = new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_REMOVED, fqn, pre, isLocal, data);
 469  8 events.add(e);
 470    }
 471   
 472  80 public void nodeModified(Fqn fqn, boolean pre, boolean isLocal, ModificationType modType, Map data)
 473    {
 474  80 CacheListenerEvent e = new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MODIFIED, fqn, pre, isLocal, data);
 475  80 events.add(e);
 476    }
 477   
 478  26 public void nodeVisited(Fqn fqn, boolean pre)
 479    {
 480  26 CacheListenerEvent e = new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_VISITED, fqn, pre, false, null);
 481  26 events.add(e);
 482    }
 483   
 484  8 public void nodeMoved(Fqn from, Fqn to, boolean pre, boolean isLocal)
 485    {
 486  8 CacheListenerEvent e = new CacheListenerEvent(CacheListenerEvent.ListenerMethod.NODE_MOVED, from, to, pre, isLocal);
 487  8 events.add(e);
 488    }
 489   
 490   
 491  0 public String toString()
 492    {
 493  0 return "EventLog{" +
 494    "events=" + events +
 495    '}';
 496    }
 497    }
 498    }