@Test public void simple_getBulkIdentified() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> put1 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<IdentifiedValue<String>>> get1 = cache.getIdentified("josie"); assertThat(get1, successful()); final IdentifiedValue<String> iv1 = unsafeJoin(get1).get(); assertThat(iv1.identifier(), notNullValue()); assertThat(iv1.value(), is("football")); final CompletionStage<Map<String, Optional<IdentifiedValue<String>>>> get2 = cache.getBulkIdentified("claira", "josie", "jasmin"); assertThat(get2, successful()); final Map<String, Optional<IdentifiedValue<String>>> ivMap1 = unsafeJoin(get2); assertThat(ivMap1.keySet(), containsInAnyOrder("jasmin", "claira", "josie")); assertThat(ivMap1.get("claira"), is(Optional.empty())); assertThat(ivMap1.get("jasmin"), is(Optional.empty())); final IdentifiedValue<String> iv2 = ivMap1.get("josie").get(); assertThat(iv2.identifier(), notNullValue()); assertThat(iv2.identifier(), equalTo(iv1.identifier())); assertThat(iv2.value(), is("football")); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(2L))); assertThat(cacheMetrics, hasSize(is(5))); }
/** * Tests where the cas id is genuinely unique, and not just a copy of the original value. */ @Test public void exact_getIdentified_removeIf() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> putFirst = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(putFirst, successfulWith(is(true))); final CompletionStage<Optional<IdentifiedValue<String>>> getFirst = cache.getIdentified("josie"); assertThat(getFirst, successful()); final IdentifiedValue<String> ivFirst = unsafeJoin(getFirst).get(); assertThat(ivFirst.identifier(), notNullValue()); assertThat(ivFirst.value(), is("football")); final CompletionStage<Boolean> putSecond = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(putSecond, successfulWith(is(true))); final CompletionStage<Boolean> rm1 = cache.removeIf("josie", ivFirst.identifier()); assertThat(rm1, successfulWith(is(false))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_REMOVE_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(5))); }
/** * Tests where the cas id is genuinely unique, and not just a copy of the original value. */ @Test public void exact_getIdentified_replaceIf() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> putFirst = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(putFirst, successfulWith(is(true))); final CompletionStage<Optional<IdentifiedValue<String>>> getFirst = cache.getIdentified("josie"); assertThat(getFirst, successful()); final IdentifiedValue<String> ivFirst = unsafeJoin(getFirst).get(); assertThat(ivFirst.identifier(), notNullValue()); assertThat(ivFirst.value(), is("football")); final CompletionStage<Boolean> putSecond = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(putSecond, successfulWith(is(true))); final CompletionStage<Boolean> rm1 = cache.replaceIf("josie", ivFirst.identifier(), "afl"); assertThat(rm1, successfulWith(is(false))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_REPLACE_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Test public void potential_deadlock() { final CompletionStage<String> get = cache.get("lockType", () -> { // People actually do this!! final CompletionStage<Void> rm = cache.remove("lockType"); assertThat(rm, successful()); return "lockwood"; }); assertThat(get, successfulWith(is("lockwood"))); } }
@Test public void simple_get_add() throws ExecutionException, InterruptedException { final CompletionStage<Optional<String>> eldestGet = cache.get("claira"); assertThat(eldestGet, successfulWith(is(Optional.empty()))); final CompletionStage<Boolean> eldestAdd = cache.put("claira", "dancing", PutPolicy.ADD_ONLY); assertThat(eldestAdd, successfulWith(is(true))); final CompletionStage<Optional<String>> eldestGet2 = cache.get("claira"); assertThat(eldestGet2, successfulWith(is(Optional.of("dancing")))); final CompletionStage<Boolean> eldestAdd2 = cache.put("claira", "singing", PutPolicy.ADD_ONLY); assertThat(eldestAdd2, successfulWith(is(false))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Test public void simple_removeAll() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> put1 = cache.put("claira", "", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.of("")))); final CompletionStage<Void> rm1 = cache.removeAll(); assertThat(rm1, successful()); final CompletionStage<Optional<String>> get2 = cache.get("claira"); assertThat(get2, successfulWith(is(Optional.empty()))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Test public void simple_getIdentified_replaceIf() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> put1 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<IdentifiedValue<String>>> get1 = cache.getIdentified("josie"); assertThat(get1, successful()); final IdentifiedValue<String> iv1 = unsafeJoin(get1).get(); assertThat(iv1.identifier(), notNullValue()); assertThat(iv1.value(), is("football")); final CompletionStage<Boolean> rm1 = cache.replaceIf("josie", iv1.identifier(), "soccer"); assertThat(rm1, successfulWith(is(true))); final CompletionStage<Boolean> put2 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS); assertThat(put2, successfulWith(is(true))); final CompletionStage<Optional<IdentifiedValue<String>>> get3 = cache.getIdentified("josie"); assertThat(get3, successful()); final IdentifiedValue<String> iv3 = unsafeJoin(get3).get(); assertThat(iv3.identifier(), notNullValue()); assertThat(iv3.value(), is("football")); final CompletionStage<Boolean> rm3 = cache.removeIf("josie", iv3.identifier()); assertThat(rm3, successfulWith(is(true))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_REPLACE_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_REMOVE_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(2L), is(2L))); assertThat(cacheMetrics, hasSize(is(6))); }
@Test public void putOperation() { final boolean result = fold(offlineCache.put("key", "value", PutPolicy.PUT_ALWAYS), t -> t, err -> false); assertThat(result, is(equalTo(false))); }
@Test public void directExternalCache_normal_marshaller() { final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder() .defaultTtl(Duration.ofSeconds(60)) .entryGrowthRateHint(ChangeRate.LOW_CHANGE) .dataChangeRateHint(ChangeRate.LOW_CHANGE) .entryCountHint(100) .build(); @SuppressWarnings("deprecation") final DirectExternalCache<String> cache = vCacheFactory().getDirectExternalCache( "my-direct-cache", MarshallerFactory.stringMarshaller(), settings); assertThat(cache, notNullValue()); assertThat(cache.getName(), is("my-direct-cache")); final CompletionStage<Void> rmall = cache.removeAll(); assertThat(rmall, successful()); final CompletionStage<Boolean> put1 = cache.put("one1", "eine", PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("one1"); assertThat(get1, successfulWith(is(Optional.of("eine")))); assertThat(vCacheManagement().allJvmCacheDetails().size(), is(0)); assertThat(vCacheManagement().allRequestCacheDetails().size(), is(0)); }
@SuppressWarnings("ConstantConditions") @Test public void check_null_detection() { assertThat(cache.get("kenny", () -> null), not(successful())); assertThat(cache.getIdentified("norway", () -> null), not(successful())); assertThat(cache.put("key", null, PutPolicy.ADD_ONLY), not(successful())); assertThat(cache.getBulk( strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> null)), "extra"), not(successful())); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); // isOneOf() on next line as Legacy test will fail in a different way when CAS not supported assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, isOneOf(1L, 2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_GET, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_IDENTIFIED_GET, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_PUT, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(10))); }
@SuppressWarnings("unchecked") @Test public void simple_getBulk() throws ExecutionException, InterruptedException { final CompletionStage<Map<String, Optional<String>>> get1 = cache.getBulk("claira", "jasmin", "josie", "josie"); assertThat(get1, successful()); assertThat(unsafeJoin(get1).keySet(), containsInAnyOrder("claira", "jasmin", "josie")); assertThat(unsafeJoin(get1).values(), containsInAnyOrder(Optional.empty(), Optional.empty(), Optional.empty())); final CompletionStage<Boolean> put1 = cache.put("claira", "youtube", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Map<String, Optional<String>>> get2 = cache.getBulk("jasmin", "claira", "josie", "claira"); assertThat(get2, successful()); assertThat(unsafeJoin(get2).keySet(), containsInAnyOrder("claira", "jasmin", "josie")); assertThat(unsafeJoin(get2).values(), containsInAnyOrder(Optional.of("youtube"), Optional.empty(), Optional.empty())); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(5L))); assertThat(cacheMetrics, hasSize(is(5))); }
@SuppressWarnings("ConstantConditions") @Test public void check_null_detection_with_cas() { final CompletionStage<IdentifiedValue<String>> geti = cache.getIdentified("temp", () -> "value"); assertThat(geti, successful()); assertThat(cache.replaceIf("temp", unsafeJoin(geti).identifier(), null), not(successful())); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_GET_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_IDENTIFIED_REPLACE_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_IDENTIFIED_REPLACE, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(6))); }
@Test public void simple_put_remove() throws ExecutionException, InterruptedException { final CompletionStage<Void> rm1 = cache.remove("claira"); assertThat(rm1, successful()); assertThat(unsafeJoin(rm1), nullValue()); final CompletionStage<Boolean> put1 = cache.put("claira", "dancing", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Void> rm2 = cache.remove("claira"); assertThat(rm2, successful()); final CompletionStage<Boolean> put2 = cache.put("claira", "dancing", PutPolicy.PUT_ALWAYS); assertThat(put2, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.of("dancing")))); final CompletionStage<Void> rm3 = cache.remove("josie", "claira", "jasmin"); assertThat(rm3, successful()); final CompletionStage<Optional<String>> get2 = cache.get("claira"); assertThat(get2, successfulWith(is(Optional.empty()))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_CALL, is(3L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(6))); }
return VCacheCasUtils.internalAtomicLoop( maxDuration, () -> fold(vcache.getIdentified(key), identifiedValue -> { if (!identifiedValue.isPresent()) { return fold(vcache.removeIf(key, identifiedValue.get().identifier()),
/** * Returns the {@link IdentifiedValue}'s that are associated with the specified keys. It is equivalent to calling * {@link #getBulkIdentified(Iterable)} passing {@code Arrays.asList(keys)} as the parameter. * * @param keys the keys to check. * @return A {@link Map} that is keyed on the {@code keys} specified. Each entry in the {@link Map} will have * {@link Optional} which may contain the {@link IdentifiedValue} associated with the key. */ @SuppressWarnings("unchecked") default CompletionStage<Map<String, Optional<IdentifiedValue<V>>>> getBulkIdentified(String... keys) { return getBulkIdentified(Arrays.asList(keys)); }
@Test public void getIdentifiedOperation() { final IdentifiedValue<String> result = fold(offlineCache.getIdentified("key", () -> "value"), t -> t, err -> null); assertThat(result, is(equalTo(null))); }
@Test public void getOperation() { final Optional<String> result = fold(offlineCache.get("key"), t -> t, err -> Optional.of("failed")); assertThat(result, is(equalTo(Optional.of("failed")))); }
@Test public void put_get_sync_unsuccessful2() throws Exception { cache().put("claira", "dancing", PutPolicy.ADD_ONLY); // Must be ADD_ONLY final CompletionStage<Optional<String>> get1 = cache().get("claira"); assertThat(get1, successfulWith(is(Optional.of("dancing")))); // Now use the directCache to verify no data has been written directCacheRefresh(); final CompletionStage<Optional<String>> get2 = directCache().get("claira"); assertThat(get2, successfulWith(is(Optional.empty()))); // Now add values to the backing cache using the directCache final CompletionStage<Map<String, String>> get3 = directCache().getBulk(keys -> Maps.asMap(keys, k -> k + "-1"), "claira", "josephine"); assertThat(get3, successful()); assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("claira", "josephine")); assertThat(unsafeJoin(get3).values(), containsInAnyOrder("claira-1", "josephine-1")); // Now sync the changes cacheTransactionSync(); // And check the cache is empty directCacheRefresh(); final CompletionStage<Map<String, Optional<String>>> get4 = directCache().getBulk("claira", "josephine"); assertThat(get4, successful()); assertThat(unsafeJoin(get4).keySet(), containsInAnyOrder("claira", "josephine")); assertThat(unsafeJoin(get4).values(), containsInAnyOrder(Optional.empty(), Optional.empty())); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(3))); }
@Test public void removeAllOperation() { // Just make sure no exceptions are thrown fold(offlineCache.removeAll(), t -> t, err -> null); } }
@Test public void getBulkOperation() { final Map<String, Optional<String>> result = fold(offlineCache.getBulk("key1", "key2"), t -> t, err -> Collections.emptyMap()); assertThat(result, is(equalTo(Collections.emptyMap()))); }