package org.infinispan.server.memcached;
import static org.infinispan.test.TestingUtil.k;
import static org.infinispan.test.TestingUtil.v;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.infinispan.commons.equivalence.ByteArrayEquivalence;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.testng.annotations.Test;
import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.internal.OperationFuture;
/**
* Tests replicated Infinispan Memcached servers.
*
* @author Galder ZamarreƱo
* @since 4.1
*/
@Test(groups = "functional", testName = "server.memcached.MemcachedReplicationTest")
public class MemcachedReplicationTest extends MemcachedMultiNodeTest {
@Override
protected EmbeddedCacheManager createCacheManager(int index) {
ConfigurationBuilder builder = new ConfigurationBuilder();
// When replicating data, old append/prepend byte[] value in the cache
// is a different instance (but maybe same contents) to the one shipped
// by the replace command itself, hence for those tests to work, value
// equivalence needs to be configured to compare byte array contents
// and not instance reference pointers.
builder.clustering().cacheMode(CacheMode.REPL_SYNC)
.dataContainer().valueEquivalence(ByteArrayEquivalence.INSTANCE);
return TestCacheManagerFactory.createClusteredCacheManager(
GlobalConfigurationBuilder.defaultClusteredBuilder().defaultCacheName(cacheName),
builder);
}
public void testReplicatedSet(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(0).get(k(m)), v(m));
}
public void testReplicatedGetMultipleKeys(Method m) throws InterruptedException, ExecutionException,
TimeoutException {
OperationFuture<Boolean> f1 = clients.get(0).set(k(m, "k1-"), 0, v(m, "v1-"));
OperationFuture<Boolean> f2 = clients.get(0).set(k(m, "k2-"), 0, v(m, "v2-"));
OperationFuture<Boolean> f3 = clients.get(0).set(k(m, "k3-"), 0, v(m, "v3-"));
assertTrue(f1.get(timeout, TimeUnit.SECONDS));
assertTrue(f2.get(timeout, TimeUnit.SECONDS));
assertTrue(f3.get(timeout, TimeUnit.SECONDS));
List<String> keys = Arrays.asList(k(m, "k1-"), k(m, "k2-"), k(m, "k3-"));
Map<String, Object> ret = clients.get(1).getBulk(keys);
assertEquals(ret.get(k(m, "k1-")), v(m, "v1-"));
assertEquals(ret.get(k(m, "k2-")), v(m, "v2-"));
assertEquals(ret.get(k(m, "k3-")), v(m, "v3-"));
}
public void testReplicatedAdd(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).add(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).get(k(m)), v(m));
}
public void testReplicatedReplace(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).add(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).get(k(m)), v(m));
f = clients.get(1).replace(k(m), 0, v(m, "v1-"));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(0).get(k(m)), v(m, "v1-"));
}
public void testReplicatedAppend(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).add(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).get(k(m)), v(m));
f = clients.get(1).append(0, k(m), v(m, "v1-"));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
String expected = v(m) + v(m, "v1-");
assertEquals(clients.get(0).get(k(m)), expected);
}
public void testReplicatedPrepend(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).add(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).get(k(m)), v(m));
f = clients.get(1).prepend(0, k(m), v(m, "v1-"));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
String expected = v(m, "v1-") + v(m);
assertEquals(clients.get(0).get(k(m)), expected);
}
public void testReplicatedGets(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
CASValue<Object> value = clients.get(1).gets(k(m));
assertEquals(value.getValue(), v(m));
assertTrue(value.getCas() != 0);
}
public void testReplicatedCasExists(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
CASValue<Object> value = clients.get(1).gets(k(m));
assertEquals(value.getValue(), v(m));
assertTrue(value.getCas() != 0);
long old = value.getCas();
CASResponse resp = clients.get(1).cas(k(m), value.getCas(), v(m, "v1-"));
value = clients.get(0).gets(k(m));
assertEquals(value.getValue(), v(m, "v1-"));
assertTrue(value.getCas() != 0);
assertTrue(value.getCas() != old);
resp = clients.get(0).cas(k(m), old, v(m, "v2-"));
assertEquals(resp, CASResponse.EXISTS);
resp = clients.get(1).cas(k(m), value.getCas(), v(m, "v2-"));
assertEquals(resp, CASResponse.OK);
}
public void testReplicatedDelete(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, v(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
f = clients.get(1).delete(k(m));
assertTrue(f.get(timeout, TimeUnit.SECONDS));
}
public void testReplicatedIncrement(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, "1");
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).incr(k(m), 1), 2);
}
public void testReplicatedDecrement(Method m) throws InterruptedException, ExecutionException, TimeoutException {
OperationFuture<Boolean> f = clients.get(0).set(k(m), 0, "1");
assertTrue(f.get(timeout, TimeUnit.SECONDS));
assertEquals(clients.get(1).decr(k(m), 1), 0);
}
}