public void testReplaceFromNonOwner() throws Exception {
    String key = "k1", value = "value", value2 = "v2";
    initAndTest();

    for (Cache<Object, String> c : caches) {
      CacheStore store = TestingUtil.extractComponent(c, CacheLoaderManager.class).getCacheStore();
      if (isOwner(c, key)) {
        assertIsInContainerImmortal(c, key);
        assert store.load(key).getValue().equals(value);
      } else {
        assert !store.containsKey(key);
      }
    }

    Object retval = getFirstNonOwner(key).replace(key, value2);
    if (testRetVals) assert value.equals(retval);
    for (Cache<Object, String> c : caches) {
      CacheStore store = TestingUtil.extractComponent(c, CacheLoaderManager.class).getCacheStore();
      if (isOwner(c, key)) {
        assertIsInContainerImmortal(c, key);
        assert c.get(key).equals(value2);
        assert store.load(key).getValue().equals(value2);
      } else {
        assert !store.containsKey(key);
      }
    }
  }
  public void testPropagatingWrites() throws Exception {
    // put something in the store
    cs.store(InternalEntryFactory.create("k1", "v1"));
    cs.store(InternalEntryFactory.create("k2", "v2", lifespan));

    int i = 1;
    for (CacheStore s : stores) {
      assert s.containsKey("k1") : "Key k1 missing on store " + i;
      assert s.containsKey("k2") : "Key k2 missing on store " + i;
      assert s.load("k1").getValue().equals("v1");
      assert s.load("k2").getValue().equals("v2");
      assert s.load("k1").getLifespan() == -1;
      assert s.load("k2").getLifespan() == lifespan;
      i++;
    }

    cs.remove("k1");

    for (CacheStore s : stores) {
      assert !s.containsKey("k1");
      assert s.containsKey("k2");
      assert s.load("k1") == null;
      assert s.load("k2").getValue().equals("v2");
      assert s.load("k2").getLifespan() == lifespan;
    }

    cs.clear();

    for (CacheStore s : stores) {
      assert !s.containsKey("k1");
      assert !s.containsKey("k2");
      assert s.load("k1") == null;
      assert s.load("k2") == null;
    }

    cs.store(InternalEntryFactory.create("k1", "v1"));
    cs.store(InternalEntryFactory.create("k2", "v2", lifespan));
    cs.store(InternalEntryFactory.create("k3", "v3", 1000)); // short lifespan!

    for (CacheStore s : stores) {
      assert s.containsKey("k1");
      assert s.containsKey("k2");
      assert s.containsKey("k3");
    }

    Thread.sleep(1100);

    cs.purgeExpired();

    for (CacheStore s : stores) {
      assert s.containsKey("k1");
      assert s.containsKey("k2");
      assert !s.containsKey("k3");
    }
  }
  public void testPropagatingTwoPhaseCommit() throws Exception {
    List<Modification> list = new LinkedList<Modification>();
    list.add(new Store(InternalEntryFactory.create("k1", "v1")));
    list.add(new Store(InternalEntryFactory.create("k2", "v2", lifespan)));
    list.add(new Store(InternalEntryFactory.create("k3", "v3")));
    list.add(new Remove("k3"));
    list.add(new Clear());
    list.add(new Store(InternalEntryFactory.create("k4", "v4")));
    list.add(new Store(InternalEntryFactory.create("k5", "v5", lifespan)));
    list.add(new Store(InternalEntryFactory.create("k6", "v6")));
    list.add(new Remove("k6"));
    GlobalTransaction tx = gtf.newGlobalTransaction(null, false);
    cs.prepare(list, tx, false);

    CacheStore[] allStores = new CacheStore[] {cs, store1, store2}; // for iteration

    for (int i = 1; i < 7; i++) {
      for (CacheStore s : allStores) assert !s.containsKey("k" + i);
    }

    cs.commit(tx);

    for (int i = 1; i < 7; i++) {
      if (i < 4 || i == 6) {
        // these have been deleted
        for (CacheStore s : allStores) assert !s.containsKey("k" + i);
      } else {
        for (CacheStore s : allStores) {
          assert s.containsKey("k" + i);
          assert s.load("k" + i).getValue().equals("v" + i);
          assert s.load("k" + i).getLifespan() == (i == 5 ? lifespan : -1);
        }
      }
    }
  }
 public void testGetFromNonOwnerWithFlags() throws Exception {
   String key = "k2", value = "value2";
   for (Cache<Object, String> c : caches) assert c.isEmpty();
   Cache<Object, String> nonOwner = getFirstNonOwner(key);
   Cache<Object, String> owner = getFirstOwner(key);
   CacheStore ownerStore =
       TestingUtil.extractComponent(owner, CacheLoaderManager.class).getCacheStore();
   owner.put(key, value);
   assert value.equals(ownerStore.load(key).getValue());
   owner.getAdvancedCache().withFlags(Flag.SKIP_CACHE_STORE).clear();
   assert value.equals(ownerStore.load(key).getValue());
   assert owner.getAdvancedCache().withFlags(Flag.SKIP_CACHE_STORE).get(key) == null;
   assert nonOwner.getAdvancedCache().withFlags(Flag.SKIP_CACHE_STORE).get(key) == null;
   assert value.equals(nonOwner.get(key));
   // need to do the get() on all the owners first to load the values, otherwise
   // assertOwnershipAndNonOwnership might fail
   assertOnAllCaches(key, value);
   assertOwnershipAndNonOwnership(key, true);
 }
 @Test
 public void testSkip() throws IOException, CacheLoaderException {
   final long expected = (DATA_SIZE - 1);
   final byte[] data = randomData(DATA_SIZE);
   when(mockEntry.getValue()).thenReturn(data);
   when(mockStore.load(MOCK_FIRST_CHUNK)).thenReturn(mockEntry);
   final long actual = testObj.skip(expected);
   assertEquals(expected, actual);
   verify(mockStore).load(anyString());
   verify(mockStore).load(MOCK_FIRST_CHUNK);
   verify(mockEntry).getValue();
   assertTrue(testObj.read() > -1);
   assertEquals(-1, testObj.read());
 }
 @Test
 public void testAvailable() throws IOException, CacheLoaderException {
   final byte[] data = randomData(DATA_SIZE);
   when(mockEntry.getValue()).thenReturn(data);
   when(mockStore.load(MOCK_FIRST_CHUNK)).thenReturn(mockEntry);
   assertEquals(0, testObj.available());
   final int partition = 435;
   testObj.skip(partition);
   // part of the first buffer remains
   assertEquals(DATA_SIZE - partition, testObj.available());
   testObj.skip(DATA_SIZE - partition);
   // none of the first buffer remains
   assertEquals(0, testObj.available());
   testObj.skip(1);
   // no buffers remain
   assertEquals(-1, testObj.available());
 }
 public void testAtomicReplaceFromNonOwner() throws Exception {
   String key = "k1", value = "value", value2 = "v2";
   initAndTest();
   boolean replaced = getFirstNonOwner(key).replace(key, value2, value);
   assert !replaced;
   replaced = getFirstNonOwner(key).replace(key, value, value2);
   assert replaced;
   for (Cache<Object, String> c : caches) {
     c.get(key).equals(value2);
     if (isOwner(c, key)) {
       CacheStore store =
           TestingUtil.extractComponent(c, CacheLoaderManager.class).getCacheStore();
       assert store.containsKey(key);
       assert store.load(key).getValue().equals(value2);
     }
   }
 }
 @Test(
     enabled = false,
     description = "Temporary disabled : https://issues.jboss.org/browse/ISPN-2249")
 public void testAtomicPutIfAbsentFromNonOwner() throws Exception {
   String key = "k1", value = "value", value2 = "v2";
   for (Cache<Object, String> c : caches) assert c.isEmpty();
   String replaced = getFirstNonOwner(key).putIfAbsent("k1", value);
   assert replaced == null;
   replaced = getFirstNonOwner(key).putIfAbsent("k1", value2);
   assert value.equals(replaced);
   for (Cache<Object, String> c : caches) {
     c.get(key).equals(replaced);
     if (isOwner(c, key)) {
       CacheStore store =
           TestingUtil.extractComponent(c, CacheLoaderManager.class).getCacheStore();
       assert store.containsKey(key);
       assert store.load(key).getValue().equals(value);
     }
   }
 }
 @Test
 public void testBufferedRead() throws IOException, CacheLoaderException {
   final byte[] data = randomData(DATA_SIZE);
   when(mockEntry.getValue()).thenReturn(data);
   when(mockStore.load(anyString())).thenReturn(mockEntry).thenReturn(mockEntry).thenReturn(null);
   final int partition = 234;
   final int expected = (DATA_SIZE - partition);
   final byte[] buffer = new byte[DATA_SIZE];
   long actual = testObj.read(buffer, 0, expected);
   // can read less than a block of data
   assertEquals(expected, actual);
   // will not load the next chunk if more data is available
   actual = testObj.read(buffer, 0, DATA_SIZE);
   assertEquals(partition, actual);
   actual = testObj.read(buffer, 0, DATA_SIZE);
   // will load the next chunk if no data is available
   assertEquals(DATA_SIZE, actual);
   // and will report the end of the data accurately
   actual = testObj.read(buffer, 0, DATA_SIZE);
   assertEquals(-1, actual);
 }
 @Test
 public void testSkipMultipleBuffers() throws IOException, CacheLoaderException {
   final byte[] data = randomData(DATA_SIZE);
   when(mockEntry.getValue()).thenReturn(data);
   when(mockStore.load(anyString())).thenReturn(mockEntry).thenReturn(mockEntry).thenReturn(null);
   long expected = (DATA_SIZE);
   // ask for more than the buffer
   long actual = testObj.skip(DATA_SIZE + 1);
   // we should skip only one complete buffer
   assertEquals(expected, actual);
   // ok, skip all but the last byte remaining
   expected = (DATA_SIZE - 1);
   actual = testObj.skip(expected);
   // new buffer, mostly skipped
   assertEquals(expected, actual);
   // we should still have 1 more byte
   assertTrue(testObj.read() > -1);
   // but only the one
   assertEquals(-1, testObj.read());
   // and we only had two cacheEntries
   verify(mockEntry, times(2)).getValue();
 }