package org.infinispan.server.test.cs.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.infinispan.arquillian.core.InfinispanResource;
import org.infinispan.arquillian.core.RemoteInfinispanServer;
import org.infinispan.arquillian.core.RunningServer;
import org.infinispan.arquillian.core.WithRunningServer;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.server.test.category.CacheStore;
import org.infinispan.server.test.client.memcached.MemcachedClient;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
/**
* Tests remote cache store under the following circumstances:
* <p/>
* passivation == true --cache entries should get to the remote cache store only when evicted
* preload == false --after server restart, entries should be be preloaded to the cache
* purge == false --all entries should remain in the cache store after server restart
* (must be false so that we can test preload)
* <p/>
* Other attributes like singleton, shared, fetch-state do not make sense in single node cluster.
*
* @author <a href="mailto:mgencur@redhat.com">Martin Gencur</a>
* @author <a href="mailto:tsykora@redhat.com">Tomas Sykora</a>
*/
@RunWith(Arquillian.class)
@Category(CacheStore.class)
@WithRunningServer({@RunningServer(name = "standalone-rcs-remote")})
public class RemoteCacheStoreIT {
private final String CONTAINER_LOCAL = "standalone-rcs-local"; // manual container
private final String CONTAINER_REMOTE = "standalone-rcs-remote"; // suite container
public static final String LOCAL_CACHE_MANAGER = "local";
private final String LOCAL_CACHE_NAME = "memcachedCache";
private final String READONLY_CACHE_NAME = "readOnlyCache";
private MemcachedClient mc;
RemoteCache<Object, Object> cache;
@InfinispanResource(CONTAINER_LOCAL)
RemoteInfinispanServer server1;
@InfinispanResource(CONTAINER_REMOTE)
RemoteInfinispanServer server2;
@ArquillianResource
ContainerController controller;
RemoteCacheManager rcm1;
@Before
public void setUp() throws Exception {
Configuration conf = new ConfigurationBuilder().addServer().host(server2.getHotrodEndpoint().getInetAddress().getHostName()).port(server2
.getHotrodEndpoint().getPort()).build();
cache = new RemoteCacheManager(conf).getCache();
}
/**
* Test for read-only attribute of store - if true, no entries will be written into store
*/
@Test
@WithRunningServer({@RunningServer(name = CONTAINER_LOCAL)})
public void testReadOnly() throws Exception {
Configuration conf = new ConfigurationBuilder().addServer().host(server1.getHotrodEndpoint().getInetAddress().getHostName()).port(server1
.getHotrodEndpoint().getPort()).build();
rcm1 = new RemoteCacheManager(conf);
RemoteCache<String, String> rc1 = rcm1.getCache(READONLY_CACHE_NAME);
// put 3 keys, k1 is evicted, but not stored
rc1.put("k1", "v1");
rc1.put("k2", "v2");
rc1.put("k3", "v3");
assertEquals(0, server2.getCacheManager(LOCAL_CACHE_MANAGER).getDefaultCache().getNumberOfEntriesInMemory());
assertEquals(2, server1.getCacheManager(LOCAL_CACHE_MANAGER).getCache(READONLY_CACHE_NAME).getNumberOfEntriesInMemory());
assertNull(rc1.get("k1"));
assertEquals("v2", rc1.get("k2"));
assertEquals("v3", rc1.get("k3"));
}
/*
* 1. store 3 entries in the local cache
* 2. verify that there are only 2 in the local cache (third one evicted)
* 3. verify the evicted entry (and not anything else) is in the remote cache
* 4. retrieve the evicted entry from local cache (should call remote cache internally)
* 5. verify the evicted entry was removed from the remote cache
*/
@Test
@WithRunningServer({@RunningServer(name = CONTAINER_LOCAL)})
public void testPassivateAfterEviction() throws Exception {
mc = new MemcachedClient(server1.getMemcachedEndpoint().getInetAddress().getHostName(), server1.getMemcachedEndpoint()
.getPort());
assertCleanCacheAndStore();
mc.set("k1", "v1");
mc.set("k2", "v2");
// not yet in store (eviction.max-entries=2, LRU)
assertEquals(0, server2.getCacheManager(LOCAL_CACHE_MANAGER).getDefaultCache().getNumberOfEntries());
mc.set("k3", "v3");
// now k1 evicted and stored in store
assertEquals(2, server1.getCacheManager(LOCAL_CACHE_MANAGER).getCache(LOCAL_CACHE_NAME).getNumberOfEntriesInMemory());
assertEquals(1, server2.getCacheManager(LOCAL_CACHE_MANAGER).getDefaultCache().getNumberOfEntriesInMemory());
// retrieve from store to cache and remove from store, another key must be evicted (k2)
assertEquals("v1", mc.get("k1"));
assertEquals("v2", mc.get("k2"));
assertEquals("v3", mc.get("k3"));
mc.delete("k1");
mc.delete("k2");
mc.delete("k3");
}
private void assertCleanCacheAndStore() throws Exception {
mc.delete("k1");
mc.delete("k2");
mc.delete("k3");
cache.clear();
assertEquals(0, server1.getCacheManager(LOCAL_CACHE_MANAGER).getCache(LOCAL_CACHE_NAME).getNumberOfEntries());
assertEquals(0, server2.getCacheManager(LOCAL_CACHE_MANAGER).getDefaultCache().getNumberOfEntries());
}
}