@Test
  public void testAddManager() throws Exception {
    LOG.info("START TEST");

    cacheName = "sampleCacheSyncBootstrap";
    if (manager1.getStatus() != Status.STATUS_SHUTDOWN) {
      manager1.shutdown();
    }

    manager1 = new CacheManager(CacheTestUtilities.ASYNC_CONFIG_URL1);
    CacheTestUtilities.waitForBootstrap(manager1, MAX_WAIT_TIME);

    final Ehcache cache1 = manager1.getEhcache(cacheName);
    final Ehcache cache2 = manager2.getEhcache(cacheName);
    final Ehcache cache3 = manager3.getEhcache(cacheName);
    final Ehcache cache4 = manager4.getEhcache(cacheName);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache1, cache2, cache3, cache4);

    cache1.put(new Element(1, new Date()));
    cache2.put(new Element(2, new Date()));

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(2, MAX_WAIT_TIME, cache1, cache2, cache3, cache4);

    assertEquals(2, cache1.getKeys().size());
    assertEquals(2, cache2.getKeys().size());
    assertEquals(2, cache3.getKeys().size());
    assertEquals(2, cache4.getKeys().size());

    LOG.info("END TEST");
  }
  @Test
  public void testBasicReplication() throws Exception {
    LOG.info("START TEST");

    final Ehcache cache1 = manager1.getEhcache(cacheName);
    final Ehcache cache2 = manager2.getEhcache(cacheName);
    final Ehcache cache3 = manager3.getEhcache(cacheName);
    final Ehcache cache4 = manager4.getEhcache(cacheName);

    for (int i = 0; i < NBR_ELEMENTS; i++) {
      cache1.put(new Element(i, "testdat"));
    }

    // Wait up to 3 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(NBR_ELEMENTS, MAX_WAIT_TIME, cache2, cache3, cache4);

    assertEquals(NBR_ELEMENTS, cache1.getKeys().size());
    assertEquals(NBR_ELEMENTS, cache2.getKeys().size());
    assertEquals(NBR_ELEMENTS, cache3.getKeys().size());
    assertEquals(NBR_ELEMENTS, cache4.getKeys().size());

    cache1.removeAll();

    // Wait up to 3 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache2, cache3, cache4);

    assertEquals(0, cache1.getKeys().size());
    assertEquals(0, cache2.getKeys().size());
    assertEquals(0, cache3.getKeys().size());
    assertEquals(0, cache4.getKeys().size());

    LOG.info("END TEST");
  }
  @Test
  public void testSimultaneousPutRemove() throws InterruptedException {
    LOG.info("START TEST");

    // Synced one
    cacheName = SAMPLE_CACHE2;
    Ehcache cache1 = manager1.getEhcache(cacheName);
    Ehcache cache2 = manager2.getEhcache(cacheName);

    Serializable key = "1";
    Serializable value = new Date();
    Element element = new Element(key, value);

    // Put
    cache1.put(element);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(1, MAX_WAIT_TIME, cache2);

    cache2.remove(element.getKey());

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache1);

    assertNull(cache1.get(element.getKey()));
    manager1.clearAll();

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache2);

    cache2.put(element);
    cache2.remove(element.getKey());

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache2);

    cache1.put(element);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(1, MAX_WAIT_TIME, cache2);

    assertNotNull(cache2.get(element.getKey()));

    manager1.clearAll();

    LOG.info("END TEST");
  }
  /**
   * What happens when two cache instances replicate to each other and a change is initiated
   *
   * @throws InterruptedException -
   */
  @Test
  public void testVariousPuts() throws InterruptedException {
    LOG.info("START TEST");

    cacheName = SAMPLE_CACHE1;
    Ehcache cache1 = manager1.getEhcache(cacheName);
    Ehcache cache2 = manager2.getEhcache(cacheName);

    Serializable key = "1";
    Serializable value = new Date();
    Element element = new Element(key, value);

    // Put
    cache1.put(element);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(1, MAX_WAIT_TIME, cache2);

    // Should have been replicated to cache2.
    Element element2 = cache2.get(key);
    assertEquals(element, element2);

    // Remove
    cache1.remove(key);
    assertNull(cache1.get(key));

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache2);

    element2 = cache2.get(key);
    assertNull(element2);

    // Put into 2
    Element element3 = new Element("3", "ddsfds");
    cache2.put(element3);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(1, MAX_WAIT_TIME, cache2);

    Element element4 = cache2.get("3");
    assertEquals(element3, element4);

    manager1.clearAll();

    LOG.info("END TEST");
  }
  @Before
  public void setUp() throws Exception {
    CacheTestUtilities.startTest(name.getMethodName());
    LOG.info("SETUP");

    manager1 = new CacheManager(CacheTestUtilities.ASYNC_CONFIG_URL1);
    CacheTestUtilities.waitForBootstrap(manager1, MAX_WAIT_TIME);

    manager2 = new CacheManager(CacheTestUtilities.ASYNC_CONFIG_URL2);
    CacheTestUtilities.waitForBootstrap(manager2, MAX_WAIT_TIME);

    manager3 = new CacheManager(CacheTestUtilities.ASYNC_CONFIG_URL3);
    CacheTestUtilities.waitForBootstrap(manager3, MAX_WAIT_TIME);

    manager4 = new CacheManager(CacheTestUtilities.ASYNC_CONFIG_URL4);
    CacheTestUtilities.waitForBootstrap(manager4, MAX_WAIT_TIME);

    cacheName = SAMPLE_CACHE1;
  }
  @Test
  public void testShutdownManager() throws Exception {
    LOG.info("START TEST");

    cacheName = SAMPLE_CACHE1;
    final Ehcache cache1 = manager1.getEhcache(cacheName);
    final Ehcache cache2 = manager2.getEhcache(cacheName);

    cache1.removeAll();

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(0, MAX_WAIT_TIME, cache2);

    CacheManagerPeerProvider provider =
        manager1.getCacheManagerPeerProvider(JGroupsCacheManagerPeerProvider.SCHEME_NAME);
    JGroupsCacheManagerPeerProvider jg = (JGroupsCacheManagerPeerProvider) provider;
    assertEquals(Status.STATUS_ALIVE, jg.getStatus());

    manager1.shutdown();
    assertEquals(Status.STATUS_UNINITIALISED, jg.getStatus());

    // Lets see if the other still replicate

    cache2.put(new Element(1, new Date()));

    final Ehcache cache3 = manager3.getEhcache(cacheName);
    final Ehcache cache4 = manager4.getEhcache(cacheName);

    // Wait up to 2 seconds for the caches to become coherent
    CacheTestUtilities.waitForReplication(1, MAX_WAIT_TIME, cache3, cache4);

    try {
      cache1.getKeys();
      fail("");
    } catch (IllegalStateException e) {
      // expected
    }
    assertEquals(1, cache2.getKeys().size());
    assertEquals(1, cache3.getKeys().size());
    assertEquals(1, cache4.getKeys().size());

    LOG.info("END TEST");
  }
  @After
  public void tearDown() throws Exception {
    LOG.debug("Tearing down cm1");
    manager1.shutdown();
    LOG.debug("Tearing down cm2");
    manager2.shutdown();
    LOG.debug("Tearing down cm3");
    manager3.shutdown();
    LOG.debug("Tearing down cm4");
    manager4.shutdown();

    LOG.info("TEARDOWN");
    CacheTestUtilities.endTest();
  }