/* * 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.geode.memcached; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.internal.AvailablePort; import org.apache.geode.memcached.GemFireMemcachedServer.Protocol; import org.apache.geode.test.junit.categories.FlakyTest; import org.apache.geode.test.junit.categories.IntegrationTest; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.logging.Logger; import java.util.logging.StreamHandler; import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; import static org.junit.Assert.*; @Category(IntegrationTest.class) public class GemcachedDevelopmentJUnitTest { private static final Logger logger = Logger.getLogger(GemcachedDevelopmentJUnitTest.class.getCanonicalName()); protected static int PORT = 0; private GemFireMemcachedServer server; @Before public void setUp() throws Exception { System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, "0"); PORT = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET); this.server = new GemFireMemcachedServer("", PORT, getProtocol()); server.start(); logger.addHandler(new StreamHandler()); } @After public void tearDown() throws Exception { System.getProperties().remove(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT); this.server.shutdown(); } protected Protocol getProtocol() { return Protocol.ASCII; } @Test public void testPutGet() throws Exception { MemcachedClient client = createMemcachedClient(); Future<Boolean> f = client.add("key", 10, "myStringValue"); assertTrue(f.get()); Future<Boolean> f1 = client.add("key1", 10, "myStringValue1"); assertTrue(f1.get()); assertEquals("myStringValue", client.get("key")); assertEquals("myStringValue1", client.get("key1")); assertNull(client.get("nonExistentkey")); // zero exp f = client.add("Hello", 0, "World"); Thread.sleep(1100); assertEquals("World", client.get("Hello")); } @Test public void testSet() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> f = client.set("key", 10, "myStringValue"); assertTrue(f.get()); } @Test public void testAdd() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> f = client.add("key", 10, "newVal"); assertFalse(f.get()); } @Test public void testReplace() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.replace("key", 10, "newVal"); assertTrue(b.get()); b = client.replace("nonExistentkey", 10, "val"); assertFalse(b.get()); b = client.replace("key", 10, "myStringValue"); assertTrue(b.get()); } @Test public void testMultiGet() throws Exception { MemcachedClient client = bootstrapClient(); Map<String, Object> val = client.getBulk("key", "key1"); assertEquals(2, val.size()); assertEquals("myStringValue", val.get("key")); assertEquals("myStringValue1", val.get("key1")); Future<Boolean> f = client.add("Hello", 0, "World"); Thread.sleep(1100); assertEquals("World", client.get("Hello")); } @Test public void testDelete() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.delete("key"); assertTrue(b.get()); b = client.delete("nonExistentkey"); assertFalse(b.get()); } @Test public void testFlush() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.flush(); assertTrue(b.get()); assertNull(client.get("key")); assertNull(client.get("key1")); } @Test public void testFlushDelay() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.flush(5); assertTrue(b.get()); assertNotNull(client.get("key")); assertNotNull(client.get("key1")); Thread.sleep(8 * 1000); assertNull(client.get("key")); assertNull(client.get("key1")); } @Category(FlakyTest.class) // GEODE-1140: time sensitive, thread sleep @Test public void testExpiration() throws Exception { MemcachedClient client = bootstrapClient(); Thread.sleep(15 * 1000); // we add with expiration 10 seconds assertNull(client.get("key")); } @Test public void testLongExpiration() throws Exception { MemcachedClient client = bootstrapClient(); client.add("newKey", (int) System.currentTimeMillis() - 60 * 1000, "newValue"); Thread.sleep(15 * 1000); assertEquals("newValue", client.get("newKey")); } @Test public void testAppend() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.append(0, "key", "WithAddition"); assertTrue(b.get()); assertEquals("myStringValueWithAddition", client.get("key")); b = client.append(0, "appendkey", "val"); assertFalse(b.get()); assertNull(client.get("appendkey")); } @Test public void testPrepend() throws Exception { MemcachedClient client = bootstrapClient(); Future<Boolean> b = client.prepend(0, "key", "prepended"); assertTrue(b.get()); assertEquals("prependedmyStringValue", client.get("key")); b = client.prepend(0, "prependkey", "val"); assertFalse(b.get()); assertNull(client.get("prependkey")); } @Test public void testIncr() throws Exception { MemcachedClient client = bootstrapClient(); client.add("incrkey", 10, 99).get(); assertEquals(104, client.incr("incrkey", 5)); assertEquals(105, client.incr("incrkey", 1)); assertEquals(-1, client.incr("inckey1", 10)); } @Test public void testDecr() throws Exception { MemcachedClient client = bootstrapClient(); client.add("decrkey", 10, 99).get(); assertEquals(95, client.decr("decrkey", 4)); assertEquals(94, client.decr("decrkey", 1)); assertEquals(-1, client.decr("decrkey1", 77)); } @Test public void testGets() throws Exception { MemcachedClient client = bootstrapClient(); client.add("getskey", 10, "casValue").get(); CASValue<Object> val = client.gets("getskey"); long oldCas = val.getCas(); assertEquals("casValue", val.getValue()); client.replace("getskey", 10, "myNewVal").get(); val = client.gets("getskey"); assertEquals(oldCas + 1, val.getCas()); assertEquals("myNewVal", val.getValue()); } @Test public void testCas() throws Exception { MemcachedClient client = bootstrapClient(); client.add("caskey", 10, "casValue").get(); CASValue<Object> val = client.gets("caskey"); assertEquals("casValue", val.getValue()); CASResponse r = client.cas("caskey", val.getCas(), "newValue"); assertEquals(CASResponse.OK, r); r = client.cas("caskey", val.getCas(), "newValue2"); assertEquals(CASResponse.EXISTS, r); } @Test public void testStats() throws Exception { MemcachedClient client = bootstrapClient(); Map stats = client.getStats(); logger.info("stats:" + stats + " val:" + stats.values().toArray()[0]); assertEquals(1, stats.size()); assertTrue(((Map) stats.values().toArray()[0]).isEmpty()); assertTrue(client.add("keystats", 1, "stats").get()); } private MemcachedClient bootstrapClient() throws IOException, UnknownHostException, InterruptedException, ExecutionException { MemcachedClient client = createMemcachedClient(); Future<Boolean> f = client.add("key", 10, "myStringValue"); f.get(); Future<Boolean> f1 = client.add("key1", 10, "myStringValue1"); f1.get(); return client; } protected MemcachedClient createMemcachedClient() throws IOException, UnknownHostException { MemcachedClient client = new MemcachedClient(new InetSocketAddress(InetAddress.getLocalHost(), PORT)); return client; } }