Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 479   Methods: 18
NCLOC: 386   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
NotificationTest.java 85.2% 97.7% 100% 95.2%
coverage coverage
 1    package org.jboss.cache.jmx;
 2   
 3    import junit.framework.AssertionFailedError;
 4    import junit.framework.TestCase;
 5    import org.jboss.cache.CacheImpl;
 6    import org.jboss.cache.DefaultCacheFactory;
 7    import org.jboss.cache.Fqn;
 8    import org.jboss.cache.config.CacheLoaderConfig;
 9    import org.jboss.cache.config.Configuration;
 10    import org.jboss.cache.config.Configuration.CacheMode;
 11    import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
 12    import org.jboss.cache.factories.XmlConfigurationParser;
 13    import org.jboss.cache.loader.CacheLoader;
 14    import org.jboss.cache.xml.XmlHelper;
 15    import org.w3c.dom.Element;
 16   
 17    import javax.management.MBeanServer;
 18    import javax.management.MBeanServerFactory;
 19    import javax.management.Notification;
 20    import javax.management.NotificationListener;
 21    import javax.management.ObjectName;
 22    import java.util.EnumSet;
 23    import java.util.HashMap;
 24   
 25    /**
 26    * Functional tests for CacheJmxWrapper broadcast of cache event notifications
 27    *
 28    * @author Jerry Gauthier
 29    * @version $Id: NotificationTest.java,v 1.6 2007/06/28 16:53:38 msurtani Exp $
 30    */
 31    public class NotificationTest extends TestCase
 32    {
 33    protected static final String CLUSTER_NAME = "NotificationTestCluster";
 34   
 35    protected static final String CAPITAL = "capital";
 36    protected static final String CURRENCY = "currency";
 37    protected static final String POPULATION = "population";
 38    protected static final String EUROPE_NODE = "Europe";
 39   
 40    public enum Type
 41    {
 42    STARTED, STOPPED, PRECREATE, POSTCREATE, PREEVICT, POSTEVICT,
 43    PRELOAD, POSTLOAD, PREREMOVE, POSTREMOVE, PREVISIT, POSTVISIT,
 44    PREMODIFY, POSTMODIFY, PREACTIVATE, POSTACTIVATE, PREPASSIVATE,
 45    POSTPASSIVATE, VIEWCHANGE
 46    }
 47   
 48    protected MBeanServer m_server;
 49    protected EnumSet<Type> events = EnumSet.noneOf(Type.class);
 50   
 51    protected CacheImpl cache = null;
 52    protected boolean optimistic = false;
 53   
 54  16 protected void setUp() throws Exception
 55    {
 56  16 super.setUp();
 57  16 m_server = MBeanServerFactory.createMBeanServer();
 58   
 59  16 Object cacheMBean = createCacheAndJmxWrapper();
 60   
 61    // bind manually for now.
 62  16 ObjectName mgmt = getWrapperObjectName();
 63   
 64  16 m_server.registerMBean(cacheMBean, mgmt);
 65    }
 66   
 67  8 protected Object createCacheAndJmxWrapper() throws Exception
 68    {
 69  8 cache = createCache(CLUSTER_NAME);
 70  8 return new CacheJmxWrapper(cache);
 71    }
 72   
 73  16 protected void tearDown() throws Exception
 74    {
 75  16 try
 76    {
 77  16 super.tearDown();
 78   
 79  16 cleanup();
 80    }
 81    finally
 82    {
 83    // make sure we stop the mbean server
 84  16 if (m_server != null)
 85  16 MBeanServerFactory.releaseMBeanServer(m_server);
 86    }
 87    }
 88   
 89  20 protected void cleanup() throws Exception
 90    {
 91  20 events.clear();
 92   
 93  20 destroyCache();
 94   
 95  20 if (m_server != null)
 96    {
 97  20 ObjectName mgmt = getWrapperObjectName();
 98  20 if (m_server.isRegistered(mgmt))
 99  20 m_server.unregisterMBean(mgmt);
 100    }
 101    }
 102   
 103  10 protected void destroyCache()
 104    {
 105  10 if (cache != null)
 106    {
 107    // stop the cache before the listener is unregistered
 108    //cache1.stop();
 109  10 cache.destroy();
 110  10 cache = null;
 111    }
 112    }
 113   
 114  26 protected ObjectName getWrapperObjectName() throws Exception
 115    {
 116  26 return new ObjectName(JmxUtil.PREFIX + CLUSTER_NAME);
 117    }
 118   
 119  4 public void testNotifications() throws Exception
 120    {
 121  4 assertNotNull("MBeanServer is null.", m_server);
 122  4 assertNotNull("Cache is null.", cache);
 123   
 124  4 ObjectName mgmt = getWrapperObjectName();
 125  4 MyListener listener = new MyListener(mgmt);
 126   
 127   
 128  4 m_server.addNotificationListener(mgmt, listener, null, null);
 129   
 130    // start the cache after registering listener - this will trigger CacheStarted
 131    // since cache is defined with cluster, thiswill also trigger ViewChange
 132  4 cache.start();
 133   
 134    // add a node - this will trigger NodeCreated, NodeModify(pre/post) and NodeModified
 135  4 HashMap albania = new HashMap(4);
 136  4 albania.put(CAPITAL, "Tirana");
 137  4 albania.put(CURRENCY, "Lek");
 138  4 cache.put("Europe/Albania", albania);
 139   
 140    // modify a node - this will trigger NodeModified and NodeModify(pre/post)
 141  4 cache.put("Europe/Albania", POPULATION, 3563112);
 142   
 143    // retrieve an attribute - this will trigger NodeVisited
 144  4 Fqn key = Fqn.fromString("Europe/Albania");
 145  4 assertNotNull("Retrieval error: expected to retrieve " + CURRENCY + " for " + key, cache.get(key, CURRENCY));
 146   
 147    // evict the node - this will trigger NodePassivate, NodeEvicted and NodeEvict(pre/post)
 148  4 cache.evict(key);
 149   
 150    // retrieve the attribute again - this will trigger NodeVisited and NodeActivate
 151  4 assertNotNull("Retrieval error: expected to retrieve " + CURRENCY + " for " + key, cache.get(key, CURRENCY));
 152   
 153    // remove the node - this will trigger NodeRemoved and NodeRemove(pre/post)
 154  4 cache.remove(key);
 155   
 156    // clean up before stopping the cache
 157  4 CacheLoader cl = cache.getCacheLoader();
 158  4 cl.remove(Fqn.fromString(EUROPE_NODE));
 159   
 160    // stop the cache
 161  4 cache.stop();
 162  4 m_server.removeNotificationListener(mgmt, listener);
 163   
 164    // run the tests
 165  4 assertTrue("Expected CacheStarted notification", events.contains(Type.STARTED));
 166  4 assertTrue("Expected CacheStopped notification", events.contains(Type.STOPPED));
 167  4 assertTrue("Expected NodeCreated notification", events.contains(Type.PRECREATE));
 168  4 assertTrue("Expected NodeCreated notification", events.contains(Type.POSTCREATE));
 169  4 assertTrue("Expected NodeEvicted notification", events.contains(Type.PREEVICT));
 170  4 assertTrue("Expected NodeEvicted notification", events.contains(Type.POSTEVICT));
 171  4 assertTrue("Expected NodeLoaded notification", events.contains(Type.PRELOAD));
 172  4 assertTrue("Expected NodeLoaded notification", events.contains(Type.POSTLOAD));
 173  4 assertTrue("Expected NodeVisited notification", events.contains(Type.PREVISIT));
 174  4 assertTrue("Expected NodeVisited notification", events.contains(Type.POSTVISIT));
 175  4 assertTrue("Expected NodeActivated notification", events.contains(Type.PREACTIVATE));
 176  4 assertTrue("Expected NodeActivated notification", events.contains(Type.POSTACTIVATE));
 177  4 assertTrue("Expected NodeModified notification", events.contains(Type.PREMODIFY));
 178  4 assertTrue("Expected NodeModified notification", events.contains(Type.POSTMODIFY));
 179  4 assertTrue("Expected NodePassivated notification", events.contains(Type.PREPASSIVATE));
 180  4 assertTrue("Expected NodePassivated notification", events.contains(Type.POSTPASSIVATE));
 181  4 assertTrue("Expected NodeRemoved notification", events.contains(Type.PREREMOVE));
 182  4 assertTrue("Expected NodeRemoved notification", events.contains(Type.POSTREMOVE));
 183  4 assertTrue("Expected ViewChange notification", events.contains(Type.VIEWCHANGE));
 184  4 validateHealthyListener(listener);
 185    }
 186   
 187  4 public void testEarlyRegistration() throws Exception
 188    {
 189    // undo setup
 190  4 cleanup();
 191   
 192  4 CacheJmxWrapper wrapper = new CacheJmxWrapper();
 193  4 ObjectName mgmt = getWrapperObjectName();
 194  4 m_server.registerMBean(wrapper, mgmt);
 195  4 MyListener listener = new MyListener(mgmt);
 196  4 m_server.addNotificationListener(mgmt, listener, null, null);
 197   
 198  4 cache = createCache(CLUSTER_NAME);
 199  4 wrapper.setCache(cache);
 200  4 cache.start();
 201  4 try
 202    {
 203  4 assertTrue("Expected CacheStarted notification", events.contains(Type.STARTED));
 204  4 validateHealthyListener(listener);
 205    }
 206    finally
 207    {
 208  4 cache.stop();
 209    }
 210    }
 211   
 212  4 public void testLateRegistration() throws Exception
 213    {
 214  4 assertNotNull("MBeanServer is null.", m_server);
 215  4 assertNotNull("Cache is null.", cache);
 216   
 217    // start the cache before registering listener
 218  4 cache.start();
 219   
 220  4 try
 221    {
 222  4 ObjectName mgmt = getWrapperObjectName();
 223  4 MyListener listener = new MyListener(mgmt);
 224   
 225   
 226  4 m_server.addNotificationListener(mgmt, listener, null, null);
 227   
 228    // add a node - this will trigger NodeCreated, NodeModify(pre/post) and NodeModified
 229  4 HashMap albania = new HashMap(4);
 230  4 albania.put(CAPITAL, "Tirana");
 231  4 albania.put(CURRENCY, "Lek");
 232  4 cache.put("Europe/Albania", albania);
 233   
 234    // run the tests
 235  4 assertTrue("Expected NodeModified notification", events.contains(Type.PREMODIFY));
 236  4 assertTrue("Expected NodeModified notification", events.contains(Type.POSTMODIFY));
 237  4 validateHealthyListener(listener);
 238    }
 239    finally
 240    {
 241  4 cache.stop();
 242    }
 243    }
 244   
 245  4 public void testListenerRemoval() throws Exception
 246    {
 247  4 assertNotNull("MBeanServer is null.", m_server);
 248  4 assertNotNull("Cache is null.", cache);
 249   
 250  4 ObjectName mgmt = getWrapperObjectName();
 251  4 MyListener listener = new MyListener(mgmt);
 252   
 253  4 m_server.addNotificationListener(mgmt, listener, null, null);
 254   
 255    // start the cache after registering listener - this will trigger CacheStarted
 256    // since cache is defined with cluster, thiswill also trigger ViewChange
 257  4 cache.start();
 258  4 boolean ok = false;
 259  4 try
 260    {
 261  4 assertTrue("Expected CacheStarted notification", events.contains(Type.STARTED));
 262   
 263  4 m_server.removeNotificationListener(mgmt, listener);
 264  4 ok = true;
 265    }
 266    finally
 267    {
 268  4 cache.stop();
 269  4 if (ok)
 270    {
 271  4 assertFalse("Expected no CacheStopped notification", events.contains(Type.STOPPED));
 272  4 validateHealthyListener(listener);
 273    }
 274    }
 275    }
 276   
 277  12 private CacheImpl createCache(String clusterName) throws Exception
 278    {
 279  12 Configuration config = createConfiguration(clusterName);
 280  12 CacheImpl cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(config, false);
 281   
 282  12 cache.create();
 283    // start the cache after the listener has been registered
 284    //cache.start();
 285  12 return cache;
 286    }
 287   
 288  20 protected Configuration createConfiguration(String clusterName) throws Exception
 289    {
 290  20 Configuration config = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
 291  20 config.setCacheMode(Configuration.CacheMode.REPL_SYNC);
 292  20 config.setCacheLoaderConfig(getCacheLoaderConfig("location=" + getTempDir()));
 293  20 config.setExposeManagementStatistics(true);
 294  20 config.setClusterName(clusterName);
 295  20 if (optimistic)
 296    {
 297  10 config.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
 298  10 config.setNodeLockingScheme("OPTIMISTIC");
 299    }
 300   
 301  20 return config;
 302    }
 303   
 304  20 private static String getTempDir()
 305    {
 306  20 return System.getProperty("java.io.tempdir", "/tmp");
 307    }
 308   
 309  124 private static boolean getPre(Object data)
 310    {
 311  124 assertNotNull("User data is null, should be Object[]", data);
 312  124 assertTrue("User data is " + data.getClass().getName() + ", should be Object[]", data instanceof Object[]);
 313   
 314  124 Object[] parms = (Object[]) data;
 315  124 assertTrue("Parameter is " + parms[1].getClass().getName() + ", should be Boolean", parms[1] instanceof Boolean);
 316  124 return (Boolean) parms[1];
 317    }
 318   
 319  20 protected static CacheLoaderConfig getCacheLoaderConfig(String properties) throws Exception
 320    {
 321  20 String xml = "<config>\n" +
 322    "<passivation>true</passivation>\n" +
 323    "<preload></preload>\n" +
 324    "<shared>true</shared>\n" +
 325    "<cacheloader>\n" +
 326    "<class>org.jboss.cache.loader.FileCacheLoader</class>\n" +
 327    "<properties>" + properties + "</properties>\n" +
 328    "<async>false</async>\n" +
 329    "<fetchPersistentState>false</fetchPersistentState>\n" +
 330    "<ignoreModifications>false</ignoreModifications>\n" +
 331    "</cacheloader>\n" +
 332    "</config>";
 333  20 Element element = XmlHelper.stringToElement(xml);
 334  20 return XmlConfigurationParser.parseCacheLoaderConfig(element);
 335    }
 336   
 337  16 private static void validateHealthyListener(MyListener listener)
 338    {
 339  16 if (listener.failure != null)
 340  0 throw listener.failure;
 341  16 if (listener.exception != null)
 342  0 throw listener.exception;
 343    }
 344   
 345    private class MyListener implements NotificationListener
 346    {
 347    private RuntimeException exception;
 348    private AssertionFailedError failure;
 349    private final String emitterObjectName;
 350   
 351  16 MyListener(ObjectName emitter)
 352    {
 353  16 this.emitterObjectName = emitter.getCanonicalName();
 354    }
 355   
 356  160 public void handleNotification(Notification notification, Object handback)
 357    {
 358  160 try
 359    {
 360  160 String type = notification.getType();
 361  160 Object userData = notification.getUserData();
 362   
 363  160 if (type.equals(CacheNotificationBroadcaster.NOTIF_CACHE_STARTED))
 364    {
 365  12 events.add(Type.STARTED);
 366  12 assertEquals("Correct object name in start notification", emitterObjectName, userData);
 367    }
 368  148 else if (type.equals(CacheNotificationBroadcaster.NOTIF_CACHE_STOPPED))
 369    {
 370  12 events.add(Type.STOPPED);
 371  12 assertEquals("Correct object name in stop notification", emitterObjectName, userData);
 372    }
 373  136 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_CREATED))
 374    {
 375  40 if (getPre(userData))
 376    {
 377  20 events.add(Type.PRECREATE);
 378    }
 379    else
 380    {
 381  20 events.add(Type.POSTCREATE);
 382    }
 383    }
 384  96 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_EVICTED))
 385    {
 386  8 if (getPre(userData))
 387    {
 388  4 events.add(Type.PREEVICT);
 389    }
 390    else
 391    {
 392  4 events.add(Type.POSTEVICT);
 393    }
 394    }
 395  88 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_LOADED))
 396    {
 397  8 if (getPre(userData))
 398    {
 399  4 events.add(Type.PRELOAD);
 400    }
 401    else
 402    {
 403  4 events.add(Type.POSTLOAD);
 404    }
 405    }
 406  80 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_REMOVED))
 407    {
 408  8 if (getPre(userData))
 409    {
 410  4 events.add(Type.PREREMOVE);
 411    }
 412    else
 413    {
 414  4 events.add(Type.POSTREMOVE);
 415    }
 416    }
 417  72 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_VISITED))
 418    {
 419  16 if (getPre(userData))
 420    {
 421  8 events.add(Type.PREVISIT);
 422    }
 423    else
 424    {
 425  8 events.add(Type.POSTVISIT);
 426    }
 427    }
 428  56 else if (type.equals(CacheNotificationBroadcaster.NOTIF_VIEW_CHANGED))
 429    {
 430  12 events.add(Type.VIEWCHANGE);
 431    }
 432  44 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_ACTIVATED))
 433    {
 434  12 if (getPre(userData))
 435    {
 436  8 events.add(Type.PREACTIVATE);
 437    }
 438    else
 439    {
 440  4 events.add(Type.POSTACTIVATE);
 441    }
 442    }
 443  32 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_MODIFIED))
 444    {
 445  24 if (getPre(userData))
 446    {
 447  12 events.add(Type.PREMODIFY);
 448    }
 449    else
 450    {
 451  12 events.add(Type.POSTMODIFY);
 452    }
 453    }
 454  8 else if (type.equals(CacheNotificationBroadcaster.NOTIF_NODE_PASSIVATED))
 455    {
 456  8 if (getPre(userData))
 457    {
 458  4 events.add(Type.PREPASSIVATE);
 459    }
 460    else
 461    {
 462  4 events.add(Type.POSTPASSIVATE);
 463    }
 464    }
 465    }
 466    catch (RuntimeException e)
 467    {
 468    // Store so the test can rethrow
 469  0 exception = e;
 470    }
 471    catch (AssertionFailedError e)
 472    {
 473    // Store so the test can rethrow
 474  0 failure = e;
 475    }
 476    }
 477    }
 478   
 479    }