blob: 75366511b5a6c5b7c0da5987ef219232146cca6a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.processors.cache.ttl;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.cache.Cache;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.expiry.Duration;
import javax.cache.expiry.TouchedExpiryPolicy;
import javax.cache.integration.CacheLoaderException;
import javax.cache.integration.CacheWriterException;
import javax.cache.integration.CompletionListenerFuture;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy;
import org.apache.ignite.cache.query.SqlQuery;
import org.apache.ignite.cache.store.CacheStoreAdapter;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.apache.ignite.cache.CachePeekMode.BACKUP;
import static org.apache.ignite.cache.CachePeekMode.NEAR;
import static org.apache.ignite.cache.CachePeekMode.OFFHEAP;
import static org.apache.ignite.cache.CachePeekMode.ONHEAP;
import static org.apache.ignite.cache.CachePeekMode.PRIMARY;
import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
/**
* TTL test.
*/
public abstract class CacheTtlAbstractSelfTest extends GridCommonAbstractTest {
/** */
private static final int MAX_CACHE_SIZE = 5;
/** */
private static final int SIZE = 11;
/** */
private static final long DEFAULT_TIME_TO_LIVE = 2000;
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME);
ccfg.setCacheMode(cacheMode());
ccfg.setAtomicityMode(atomicityMode());
LruEvictionPolicy plc = new LruEvictionPolicy();
plc.setMaxSize(MAX_CACHE_SIZE);
ccfg.setEvictionPolicy(plc);
ccfg.setOnheapCacheEnabled(true);
ccfg.setIndexedTypes(Integer.class, Integer.class);
ccfg.setBackups(2);
ccfg.setWriteSynchronizationMode(FULL_SYNC);
ccfg.setRebalanceMode(SYNC);
ccfg.setCacheStoreFactory(singletonFactory(new CacheStoreAdapter() {
@Override public void loadCache(IgniteBiInClosure clo, Object... args) {
for (int i = 0; i < SIZE; i++)
clo.apply(i, i);
}
@Override public Object load(Object key) throws CacheLoaderException {
return key;
}
@Override public void write(Cache.Entry entry) throws CacheWriterException {
// No-op.
}
@Override public void delete(Object key) throws CacheWriterException {
// No-op.
}
}));
ccfg.setExpiryPolicyFactory(
FactoryBuilder.factoryOf(new TouchedExpiryPolicy(new Duration(MILLISECONDS, DEFAULT_TIME_TO_LIVE))));
cfg.setCacheConfiguration(ccfg);
return cfg;
}
/**
* @return Atomicity mode.
*/
protected abstract CacheAtomicityMode atomicityMode();
/**
* @return Cache mode.
*/
protected abstract CacheMode cacheMode();
/**
* @return GridCount
*/
protected abstract int gridCount();
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
startGrids(gridCount());
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
stopAllGrids();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLiveLoadCache() throws Exception {
IgniteCache<Integer, Integer> cache = jcache(0);
cache.loadCache(null);
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLiveLoadAll() throws Exception {
defaultTimeToLiveLoadAll(false);
defaultTimeToLiveLoadAll(true);
}
/**
* @param replaceExisting Replace existing value flag.
* @throws Exception If failed.
*/
private void defaultTimeToLiveLoadAll(boolean replaceExisting) throws Exception {
IgniteCache<Integer, Integer> cache = jcache(0);
CompletionListenerFuture fut = new CompletionListenerFuture();
Set<Integer> keys = new HashSet<>();
for (int i = 0; i < SIZE; ++i)
keys.add(i);
cache.loadAll(keys, replaceExisting, fut);
fut.get();
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLiveStreamerAdd() throws Exception {
try (IgniteDataStreamer<Integer, Integer> streamer = ignite(0).dataStreamer(DEFAULT_CACHE_NAME)) {
for (int i = 0; i < SIZE; i++)
streamer.addData(i, i);
}
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
try (IgniteDataStreamer<Integer, Integer> streamer = ignite(0).dataStreamer(DEFAULT_CACHE_NAME)) {
streamer.allowOverwrite(true);
for (int i = 0; i < SIZE; i++)
streamer.addData(i, i);
}
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLivePut() throws Exception {
IgniteCache<Integer, Integer> cache = jcache(0);
Integer key = 0;
cache.put(key, 1);
checkSizeBeforeLive(1);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLivePutAll() throws Exception {
IgniteCache<Integer, Integer> cache = jcache(0);
Map<Integer, Integer> entries = new HashMap<>();
for (int i = 0; i < SIZE; ++i)
entries.put(i, i);
cache.putAll(entries);
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDefaultTimeToLivePreload() throws Exception {
IgniteCache<Integer, Integer> cache = jcache(0);
Map<Integer, Integer> entries = new HashMap<>();
for (int i = 0; i < SIZE; ++i)
entries.put(i, i);
cache.putAll(entries);
startGrid(gridCount());
checkSizeBeforeLive(SIZE, gridCount() + 1);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive(gridCount() + 1);
}
/**
* @throws Exception If failed.
*/
@Test
public void testTimeToLiveTtl() throws Exception {
long time = DEFAULT_TIME_TO_LIVE + 2000;
IgniteCache<Integer, Integer> cache = this.<Integer, Integer>jcache(0).withExpiryPolicy(
new TouchedExpiryPolicy(new Duration(MILLISECONDS, time)));
for (int i = 0; i < SIZE; i++)
cache.put(i, i);
checkSizeBeforeLive(SIZE);
Thread.sleep(DEFAULT_TIME_TO_LIVE + 500);
checkSizeBeforeLive(SIZE);
Thread.sleep(time - DEFAULT_TIME_TO_LIVE + 500);
checkSizeAfterLive();
}
/**
* @param size Expected size.
* @throws Exception If failed.
*/
private void checkSizeBeforeLive(int size) throws Exception {
checkSizeBeforeLive(size, gridCount());
}
/**
* @param size Expected size.
* @param gridCnt Number of nodes.
* @throws Exception If failed.
*/
private void checkSizeBeforeLive(int size, int gridCnt) throws Exception {
for (int i = 0; i < gridCnt; ++i) {
IgniteCache<Integer, Integer> cache = jcache(i);
log.info("Size [node=" + i + ", " + cache.localSize(PRIMARY, BACKUP, NEAR) + ']');
assertEquals("Unexpected size, node: " + i, size, cache.localSize(PRIMARY, BACKUP, NEAR));
for (int key = 0; key < size; key++)
assertNotNull(cache.localPeek(key));
assertFalse(cache.query(new SqlQuery<>(Integer.class, "_val >= 0")).getAll().isEmpty());
}
}
/**
* @throws Exception If failed.
*/
private void checkSizeAfterLive() throws Exception {
checkSizeAfterLive(gridCount());
}
/**
* @param gridCnt Number of nodes.
* @throws Exception If failed.
*/
private void checkSizeAfterLive(int gridCnt) throws Exception {
for (int i = 0; i < gridCnt; ++i) {
IgniteCache<Integer, Integer> cache = jcache(i);
log.info("Size [node=" + i +
", heap=" + cache.localSize(ONHEAP) +
", offheap=" + cache.localSize(OFFHEAP) + ']');
assertEquals(0, cache.localSize());
assertEquals(0, cache.localSize(OFFHEAP));
assertEquals(0, cache.query(new SqlQuery<>(Integer.class, "_val >= 0")).getAll().size());
for (int key = 0; key < SIZE; key++)
assertNull(cache.localPeek(key));
}
}
}