package redis.client; import com.google.common.base.Charsets; import com.google.common.util.concurrent.SettableFuture; import org.junit.Test; import redis.Command; import redis.reply.BulkReply; import redis.reply.IntegerReply; import redis.reply.MultiBulkReply; import redis.reply.StatusReply; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicReference; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; import static redis.util.Encoding.numToBytes; /** * Test the boilerplate * <p/> * User: sam * Date: 11/5/11 * Time: 10:20 PM */ public class RedisClientTest { private static final byte[] VALUE = "value".getBytes(Charsets.UTF_8); private static final long CALLS = 100000l; @Test public void testIt() throws IOException, ExecutionException, InterruptedException { RedisClient redisClient = new RedisClient("localhost", 6379); redisClient.set("test", "value"); BulkReply test = redisClient.get("test"); assertEquals("value", test.asAsciiString()); assertEquals("value", test.asUTF8String()); RedisClient.Pipeline p = redisClient.pipeline(); p.set("increment", 0); p.incr("increment"); p.incr("increment"); assertEquals(3, (long) redisClient.incr("increment").data()); redisClient.del(new Object[] { "hash" }); redisClient.hset("hash", "field1", "value1"); redisClient.hset("hash", "field2", "value2"); redisClient.hset("hash", "field3", "value1"); MultiBulkReply hash = redisClient.hgetall("hash"); assertEquals("value2", hash.asStringMap(Charsets.UTF_8).get("field2")); assertEquals(6, hash.asStringList(Charsets.UTF_8).size()); assertEquals(5, hash.asStringSet(Charsets.UTF_8).size()); Object[] keys = {"test1", "test2", "test3"}; redisClient.del(keys); redisClient.set("test1", "value1"); redisClient.set("test2", "value2"); redisClient.set("test3", "value3"); MultiBulkReply values = redisClient.mget(keys); List<String> strings = values.asStringList(Charsets.UTF_8); assertEquals(3, strings.size()); assertEquals("value2", strings.get(1)); } @Test public void testTx() throws IOException, ExecutionException, InterruptedException { RedisClient redisClient1 = new RedisClient("localhost", 6379); RedisClient redisClient2 = new RedisClient("localhost", 6379); { redisClient1.set("txincr", 0); redisClient1.watch(new Object[]{"txincr"}); redisClient1.get("txincr"); redisClient1.multi(); RedisClient.Pipeline p = redisClient1.pipeline(); Future<IntegerReply> txincr1 = p.incr("txincr"); Future<IntegerReply> txincr2 = p.incr("txincr"); redisClient1.exec(); assertEquals(2l, (long) txincr2.get().data()); assertEquals(1l, (long) txincr1.get().data()); } { redisClient1.set("txincr", 0); redisClient1.watch(new Object[]{"txincr"}); redisClient1.get("txincr"); redisClient1.multi(); redisClient2.set("txincr", 1); RedisClient.Pipeline p = redisClient1.pipeline(); p.incr("txincr"); p.incr("txincr"); if (redisClient1.exec().get()) { fail("This should have failed"); } } redisClient1.close(); redisClient2.close(); } @Test public void testSubscriptions() throws IOException, ExecutionException, InterruptedException { RedisClient redisClient1 = new RedisClient("localhost", 6379); RedisClient redisClient2 = new RedisClient("localhost", 6379); final SettableFuture<String> messaged = SettableFuture.create(); final SettableFuture<String> pmessaged = SettableFuture.create(); final SettableFuture<String> subscribed = SettableFuture.create(); final SettableFuture<String> psubscribed = SettableFuture.create(); final SettableFuture<String> unsubscribed = SettableFuture.create(); final SettableFuture<String> punsubscribed = SettableFuture.create(); redisClient2.addListener(new ReplyListener() { public void subscribed(byte[] name, int channels) { subscribed.set(new String(name)); } public void psubscribed(byte[] name, int channels) { psubscribed.set(new String(name)); } public void unsubscribed(byte[] name, int channels) { unsubscribed.set(new String(name)); } public void punsubscribed(byte[] name, int channels) { punsubscribed.set(new String(name)); } public void message(byte[] channel, byte[] message) { messaged.set(new String(channel) + " " + new String(message)); } public void pmessage(byte[] pattern, byte[] channel, byte[] message) { pmessaged.set(new String(pattern) + " " + new String(message)); } }); redisClient2.subscribe("subscribe"); redisClient2.psubscribe("subscribe*"); redisClient1.publish("subscribe", "hello, world!"); assertEquals("subscribe hello, world!", messaged.get()); assertEquals("subscribe* hello, world!", pmessaged.get()); redisClient2.unsubscribe("subscribe"); redisClient2.punsubscribe("subscribe*"); assertEquals("subscribe", subscribed.get()); assertEquals("subscribe", unsubscribed.get()); assertEquals("subscribe*", psubscribed.get()); assertEquals("subscribe*", punsubscribed.get()); try { redisClient2.set("test", "fail"); fail("Should have failed"); } catch (RedisException e) { // fails } redisClient1.close(); redisClient2.close(); } @Test public void testAPI() throws IOException { RedisClient rc = new RedisClient("localhost", 6379); rc.set("test1".getBytes(), "value".getBytes()); rc.set("test2".getBytes(), "value"); assertEquals("value", ((BulkReply)(rc.mget(new Object[] { "test1".getBytes() }).data()[0])).asAsciiString()); } @Test public void benchmark() throws IOException { if (System.getenv().containsKey("CI") || System.getProperty("CI") != null) return; long start = System.currentTimeMillis(); RedisClient redisClient = new RedisClient("localhost", 6379); for (int i = 0; i < CALLS; i++) { redisClient.set(numToBytes(i, false), VALUE); } long end = System.currentTimeMillis(); System.out.println("Blocking: " + (CALLS * 1000) / (end - start) + " calls per second"); } @SuppressWarnings("unchecked") @Test public void benchmarkPipeline() throws IOException, ExecutionException, InterruptedException { if (System.getenv().containsKey("CI") || System.getProperty("CI") != null) return; long start = System.currentTimeMillis(); RedisClient redisClient = new RedisClient("localhost", 6379); redisClient.execute("INFO", new Command("INFO", "server")); RedisClient.Pipeline pipeline = redisClient.pipeline(); int PIPELINE_CALLS = 50; Future<StatusReply>[] replies = new Future[PIPELINE_CALLS]; for (int i = 0; i < CALLS * 10 / PIPELINE_CALLS; i++) { for (int j = 0; j < PIPELINE_CALLS; j++) { replies[j] = pipeline.set(numToBytes(i, false), VALUE); } for (int j = 0; j < PIPELINE_CALLS; j++) { replies[j].get(); } } long end = System.currentTimeMillis(); System.out.println("Pipelined: " + (CALLS * 10 * 1000) / (end - start) + " calls per second"); } @Test public void benchmarkPubsub() throws IOException, ExecutionException, InterruptedException { if (System.getenv().containsKey("CI") || System.getProperty("CI") != null) return; long start = System.currentTimeMillis(); byte[] hello = "hello".getBytes(); byte[] test = "test".getBytes(); RedisClient subscriberClient = new RedisClient("localhost", 6379); final AtomicReference<SettableFuture> futureRef = new AtomicReference<SettableFuture>(); subscriberClient.addListener(new MessageListener() { @SuppressWarnings("unchecked") @Override public void message(byte[] channel, byte[] message) { futureRef.get().set(null); } @SuppressWarnings("unchecked") @Override public void pmessage(byte[] pattern, byte[] channel, byte[] message) { futureRef.get().set(null); } }); subscriberClient.subscribe("test"); RedisClient publisherClient = new RedisClient("localhost", 6379); for (int i = 0; i < CALLS; i++) { SettableFuture<Object> future = SettableFuture.create(); futureRef.set(future); publisherClient.publish(test, hello); future.get(); } long end = System.currentTimeMillis(); System.out.println("Pub/sub: " + (CALLS * 1000) / (end - start) + " calls per second"); } @Test public void benchmarkPubsubPipelined() throws IOException, ExecutionException, InterruptedException { if (System.getenv().containsKey("CI") || System.getProperty("CI") != null) return; long start = System.currentTimeMillis(); byte[] hello = "hello".getBytes(); byte[] test = "test".getBytes(); RedisClient subscriberClient = new RedisClient("localhost", 6379); final Semaphore semaphore = new Semaphore(50); final AtomicReference<SettableFuture> futureRef = new AtomicReference<SettableFuture>(); subscriberClient.addListener(new MessageListener() { @Override public void message(byte[] channel, byte[] message) { semaphore.release(); } @Override public void pmessage(byte[] pattern, byte[] channel, byte[] message) { semaphore.release(); } }); subscriberClient.subscribe("test"); RedisClient.Pipeline publisherClient = new RedisClient("localhost", 6379).pipeline(); for (int i = 0; i < CALLS * 10; i++) { semaphore.acquire(); SettableFuture<Object> future = SettableFuture.create(); futureRef.set(future); publisherClient.publish(test, hello); } semaphore.acquire(50); long end = System.currentTimeMillis(); System.out.println("Pub/sub pipelined: " + (CALLS * 10 * 1000) / (end - start) + " calls per second"); } }