latches.addAll(Arrays.asList(new CountDownLatch(1), new CountDownLatch(1), new CountDownLatch(1))); AutoCloseable onCreate = rwMap.listeners().onCreate(created -> { assertEquals("created", created.get()); latches.get(0).countDown(); }); AutoCloseable onModify = rwMap.listeners().onModify((before, after) -> { assertEquals("created", before.get()); assertEquals("modified", after.get()); latches.get(1).countDown(); }); AutoCloseable onRemove = rwMap.listeners().onRemove(removed -> { assertEquals("modified", removed.get()); latches.get(2).countDown(); });
@Test(dataProvider = "owningModeAndReadMethod") public void testReadLoad(boolean isSourceOwner, ReadMethod method) { Object key = getKey(isSourceOwner, DIST); List<Cache<Object, Object>> owners = caches(DIST).stream() .filter(cache -> cache.getAdvancedCache().getDistributionManager().getLocality(key).isLocal()) .collect(Collectors.toList()); assertTrue(method.eval(key, ro, view -> { assertFalse(view.find().isPresent()); return true; })); // we can't add from read-only cache, so we put manually: cache(0, DIST).put(key, "value"); caches(DIST).forEach(cache -> assertEquals(cache.get(key), "value", getAddress(cache).toString())); caches(DIST).forEach(cache -> cache.evict(key)); caches(DIST).forEach(cache -> assertFalse(cache.getAdvancedCache().getDataContainer().containsKey(key), getAddress(cache).toString())); owners.forEach(cache -> { Set<DummyInMemoryStore> stores = cache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(DummyInMemoryStore.class); DummyInMemoryStore store = stores.iterator().next(); assertTrue(store.contains(key), getAddress(cache).toString()); }); assertEquals(method.eval(key, ro, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return "OK"; }), "OK"); } }
private FunctionalListenerAssertions(FunctionalListeners<K, V> listeners, Runnable runnable) { this.listeners = listeners; this.runnable = runnable; Listeners.ReadWriteListeners<K, V> rw = this.listeners.readWriteListeners(); closeables.add(rw.onCreate(c -> recorded.add( TestEvent.create(InternalTestType.LAMBDA_CREATE, c.get())))); closeables.add(rw.onModify((b, a) -> recorded.add( TestEvent.create(InternalTestType.LAMBDA_MODIFY, a.get(), b.get())))); closeables.add(rw.onRemove(r -> recorded.add( TestEvent.create(InternalTestType.LAMBDA_REMOVE, null, r.get())))); closeables.add(rw.add(new Listeners.ReadWriteListeners.ReadWriteListener<K, V>() { @Override public void onCreate(ReadEntryView<K, V> created) { recorded.add(TestEvent.create(InternalTestType.LISTENER_CREATE, created.get())); } @Override public void onModify(ReadEntryView<K, V> before, ReadEntryView<K, V> after) { recorded.add(TestEvent.create(InternalTestType.LISTENER_MODIFY, after.get(), before.get())); } @Override public void onRemove(ReadEntryView<K, V> removed) { recorded.add(TestEvent.create(InternalTestType.LISTENER_REMOVE, null, removed.get())); } })); Listeners.WriteListeners<K, V> wo = this.listeners.writeOnlyListeners(); closeables.add(wo.onWrite(w -> recorded.add( TestEvent.create(InternalTestType.LAMBDA_WRITE, w.find().orElse(null))))); closeables.add(wo.add(w -> recorded.add( TestEvent.create(InternalTestType.LISTENER_WRITE, w.find().orElse(null))))); }
@Test(dataProvider = "writeMethods") public void testWriteLoadLocal(WriteMethod method) { Integer key = 1; method.eval(key, lwo, lrw, view -> { assertFalse(view.find().isPresent()); return null; }, (view, nil) -> view.set("value"), getClass()); assertInvocations(1); Cache<Integer, String> cache = cacheManagers.get(0).getCache(); assertEquals(cache.get(key), "value"); cache.evict(key); assertFalse(cache.getAdvancedCache().getDataContainer().containsKey(key)); DummyInMemoryStore store = getStore(cache); assertTrue(store.contains(key)); method.eval(key, lwo, lrw, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return null; }, (view, nil) -> {}, getClass()); assertInvocations(2); }
private <K> void doLambdaWriteListeners(Supplier<K> keySupplier, WriteOnlyMap<K, String> wo, boolean isOwner) throws Exception { K key1 = keySupplier.get(), key2 = keySupplier.get(); List<CountDownLatch> latches = launderLatches(new ArrayList<>(), 1); AutoCloseable onWrite = wo.listeners().onWrite(read -> { assertEquals("write", read.get()); latches.get(0).countDown(); }); awaitEventIfOwnerAndLaunderLatch(isOwner, wo.eval(key1, new SetConstantOnWriteOnly("write")), latches); awaitEventIfOwnerAndLaunderLatch(isOwner, wo.eval(key1, new SetConstantOnWriteOnly("write")), latches); onWrite.close(); awaitNoEvent(wo.eval(key2, new SetConstantOnWriteOnly("write")), latches.get(0)); awaitNoEvent(wo.eval(key2, new SetConstantOnWriteOnly("write")), latches.get(0)); // TODO: Test other eval methods :) AutoCloseable onWriteRemove = wo.listeners().onWrite(read -> { assertFalse(read.find().isPresent()); latches.get(0).countDown(); }); awaitEventIfOwnerAndLaunderLatch(isOwner, wo.eval(key1, removeConsumer()), latches); onWriteRemove.close(); awaitNoEvent(wo.eval(key2, removeConsumer()), latches.get(0)); }
@Test(dataProvider = "owningModeAndReadMethod") public void testReadLoad(boolean isOwner, ReadMethod method) { Object key = getKey(isOwner, DIST); assertTrue(method.eval(key, ro, view -> { assertFalse(view.find().isPresent()); return true; })); // we can't add from read-only cache, so we put manually: cache(0, DIST).put(key, "value"); caches(DIST).forEach(cache -> assertEquals(cache.get(key), "value", getAddress(cache).toString())); caches(DIST).forEach(cache -> { if (cache.getAdvancedCache().getDistributionManager().getLocality(key).isLocal()) { assertTrue(cacheContainsKey(key, cache), getAddress(cache).toString()); } else { assertFalse(cacheContainsKey(key, cache), getAddress(cache).toString()); } }); assertEquals(method.eval(key, ro, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return "OK"; }), "OK"); }
@Test(dataProvider = "owningModeAndReadWrites") public void testWriteOnMissingValue(boolean isOwner, WriteMethod method) { Object key = getKey(isOwner, DIST); try { method.eval(key, null, rw, view -> view.get(), (view, nil) -> {}, getClass()); fail("Should throw CompletionException:CacheException:[RemoteException:]*NoSuchElementException"); } catch (CompletionException e) { // catches RemoteExceptions, too Throwable t = e; assertException(CompletionException.class, t); t = t.getCause(); assertExceptionNonStrict(CacheException.class, t); while (t.getCause() instanceof RemoteException && t != t.getCause()) { t = t.getCause(); } assertException(NoSuchElementException.class, t.getCause()); } }
@Test(dataProvider = "owningModeAndReadWrites") public void testWriteOnMissingValue(boolean isOwner, WriteMethod method) { Object key = getKey(isOwner, SCATTERED); try { method.eval(key, null, srw, view -> view.get(), (view, nil) -> {}, getClass()); fail("Should throw CompletionException:CacheException:[RemoteException:]*NoSuchElementException"); } catch (CompletionException e) { // catches RemoteExceptions, too Throwable t = e; assertException(CompletionException.class, t); t = t.getCause(); assertExceptionNonStrict(CacheException.class, t); while (t.getCause() instanceof RemoteException && t != t.getCause()) { t = t.getCause(); } assertException(NoSuchElementException.class, t.getCause()); } }
/** * Write-only allows for non-capturing values to be written along with metadata, * and read-only allows for both values and metadata to be retrieved. */ private <K> void doWriteValueAndReadValueAndMetadata(Supplier<K> keySupplier, ReadOnlyMap<K, String> map1, WriteOnlyMap<K, String> map2) { K key = keySupplier.get(); await( map2.eval(key, "one", SetValueAndConstantLifespan.getInstance()).thenCompose(r -> map1.eval(key, identity()).thenAccept(ro -> { assertNull(r); assertEquals(Optional.of("one"), ro.find()); assertEquals("one", ro.get()); assertEquals(Optional.of(new MetaLifespan(100000)), ro.findMetaParam(MetaLifespan.class)); } ) ) ); }
private <K> void testReadOnMissingValues(K[] keys, FunctionalMap.ReadOnlyMap<K, String> ro, ReadMethod method) throws Exception { tm.begin(); for (K key : keys) { Assert.assertEquals(ro.eval(key, view -> view.find().isPresent()).join(), Boolean.FALSE); } tm.commit(); tm.begin(); for (K key : keys) { expectExceptionNonStrict(CompletionException.class, CacheException.class, NoSuchElementException.class, () -> method.eval(key, ro, EntryView.ReadEntryView::get)); // The first exception should cause the whole transaction to fail assertEquals(Status.STATUS_MARKED_ROLLBACK, tm.getStatus()); tm.rollback(); break; } if (tm.getStatus() == Status.STATUS_ACTIVE) { tm.commit(); } }
@Test(dataProvider = "writeMethods") public void testWriteLoadLocal(WriteMethod method) { Integer key = 1; method.eval(key, lwo, lrw, view -> { assertFalse(view.find().isPresent()); return null; }, (view, nil) -> view.set("value"), getClass()); assertInvocations(1); assertEquals(cacheManagers.get(0).getCache().get(key), "value"); method.eval(key, lwo, lrw, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return null; }, (view, nil) -> {}, getClass()); assertInvocations(2); }
@Test(dataProvider = "owningModeAndWriteMethod") public void testWrite(boolean isOwner, WriteMethod method) { Object key = getKey(isOwner, SCATTERED); method.eval(key, swo, srw, view -> { assertFalse(view.find().isPresent()); return null; }, (view, nil) -> view.set("value"), getClass()); assertInvocations(1); caches(SCATTERED).forEach(cache -> assertEquals(cache.get(key), "value", getAddress(cache).toString())); Utils.assertOwnershipAndNonOwnership(caches(SCATTERED), key); method.eval(key, swo, srw, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return null; }, (view, nil) -> {}, getClass()); assertInvocations(2); }
@Test(dataProvider = "readMethods") public void testReadLoadsLocal(ReadMethod method) throws Exception { Integer[] keys = INT_KEYS; for (Integer key : keys) { cache(0).put(key, key); } tm.begin(); for (Integer key : keys) { assertEquals(method.eval(key, lro, e -> { assertTrue(e.find().isPresent()); assertEquals(e.get(), e.key()); return "OK"; }), "OK"); } tm.commit(); }
@Test(dataProvider = "readMethods") public void testReadLoadLocal(ReadMethod method) { Integer key = 1; assertTrue((Boolean) method.eval(key, lro, view -> { assertFalse(view.find().isPresent()); return true; })); // we can't add from read-only cache, so we put manually: Cache<Integer, String> cache = cacheManagers.get(0).getCache(); cache.put(key, "value"); assertEquals(cache.get(key), "value"); assertEquals(method.eval(key, lro, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return "OK"; }), "OK"); }
@Test(dataProvider = "owningModeAndReadMethod") public void testReadLoads(boolean isOwner, ReadMethod method) throws Exception { Object[] keys = getKeys(isOwner, NUM_KEYS); for (Object key : keys) { cache(0, DIST).put(key, key); } tm.begin(); for (Object key : keys) { assertEquals(method.eval(key, ro, e -> { assertTrue(e.find().isPresent()); assertEquals(e.get(), e.key()); return "OK"; }), "OK"); } tm.commit(); }
@Test(dataProvider = "owningModeAndReadMethod") public void testReadLoad(boolean isOwner, ReadMethod method) { Object key = getKey(isOwner, SCATTERED); assertTrue(method.eval(key, sro, view -> { assertFalse(view.find().isPresent()); return true; })); // we can't add from read-only cache, so we put manually: cache(0, SCATTERED).put(key, "value"); caches(SCATTERED).forEach(cache -> assertEquals(cache.get(key), "value", getAddress(cache).toString())); Utils.assertOwnershipAndNonOwnership(caches(SCATTERED), key); assertEquals(method.eval(key, sro, view -> { assertTrue(view.find().isPresent()); assertEquals(view.get(), "value"); return "OK"; }), "OK"); }
@Override public boolean containsValue(Object value) { return readOnly.entries().anyMatch(ro -> ro.get().equals(value)); }