// Copyright (C) 2011 - Will Glozer. All rights reserved.
package com.lambdaworks.redis;
import com.lambdaworks.redis.pubsub.*;
import org.junit.*;
import java.util.concurrent.*;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
public class PubSubCommandTest extends AbstractCommandTest implements RedisPubSubListener<String, String> {
private RedisPubSubConnection<String, String> pubsub;
private BlockingQueue<String> channels;
private BlockingQueue<String> patterns;
private BlockingQueue<String> messages;
private BlockingQueue<Long> counts;
private String channel = "channel0";
private String pattern = "channel*";
private String message = "msg!";
@Before
public void openPubSubConnection() throws Exception {
pubsub = client.connectPubSub();
pubsub.addListener(this);
channels = new LinkedBlockingQueue<String>();
patterns = new LinkedBlockingQueue<String>();
messages = new LinkedBlockingQueue<String>();
counts = new LinkedBlockingQueue<Long>();
}
@After
public void closePubSubConnection() throws Exception {
pubsub.close();
}
@Test
public void auth() throws Exception {
new WithPasswordRequired() {
@Override
protected void run(RedisClient client) throws Exception {
RedisPubSubConnection<String, String> connection = client.connectPubSub();
connection.addListener(PubSubCommandTest.this);
connection.auth(passwd);
connection.subscribe(channel);
assertEquals(channel, channels.take());
}
};
}
@Test(timeout = 100)
public void message() throws Exception {
pubsub.subscribe(channel);
assertEquals(channel, channels.take());
redis.publish(channel, message);
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
}
@Test(timeout = 100)
public void pmessage() throws Exception {
pubsub.psubscribe(pattern);
assertEquals(pattern, patterns.take());
redis.publish(channel, message);
assertEquals(pattern, patterns.take());
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
redis.publish("channel2", "msg 2!");
assertEquals(pattern, patterns.take());
assertEquals("channel2", channels.take());
assertEquals("msg 2!", messages.take());
}
@Test(timeout = 100)
public void psubscribe() throws Exception {
pubsub.psubscribe(pattern);
assertEquals(pattern, patterns.take());
assertEquals(1, (long) counts.take());
}
@Test(timeout = 100)
public void punsubscribe() throws Exception {
pubsub.punsubscribe(pattern);
assertEquals(pattern, patterns.take());
assertEquals(0, (long) counts.take());
}
@Test(timeout = 100)
public void subscribe() throws Exception {
pubsub.subscribe(channel);
assertEquals(channel, channels.take());
assertEquals(1, (long) counts.take());
}
@Test(timeout = 100)
public void unsubscribe() throws Exception {
pubsub.unsubscribe(channel);
assertEquals(channel, channels.take());
assertEquals(0, (long) counts.take());
}
@Test(timeout = 100)
public void utf8Channel() throws Exception {
String channel = "channelλ";
String message = "αβγ";
pubsub.subscribe(channel);
assertEquals(channel, channels.take());
redis.publish(channel, message);
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
}
@Test(timeout = 1000)
public void resubscribeChannelsOnReconnect() throws Exception {
pubsub.subscribe(channel);
assertEquals(channel, channels.take());
assertEquals(1, (long) counts.take());
pubsub.quit();
assertEquals(channel, channels.take());
assertEquals(1, (long) counts.take());
redis.publish(channel, message);
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
}
@Test(timeout = 1000)
public void resubscribePatternsOnReconnect() throws Exception {
pubsub.psubscribe(pattern);
assertEquals(pattern, patterns.take());
assertEquals(1, (long) counts.take());
pubsub.quit();
assertEquals(pattern, patterns.take());
assertEquals(1, (long) counts.take());
redis.publish(channel, message);
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
}
@Test(timeout = 100)
public void adapter() throws Exception {
final BlockingQueue<Long> localCounts = new LinkedBlockingQueue<Long>();
RedisPubSubAdapter<String, String> adapter = new RedisPubSubAdapter<String, String>() {
@Override
public void subscribed(String channel, long count) {
super.subscribed(channel, count);
localCounts.add(count);
}
@Override
public void unsubscribed(String channel, long count) {
super.unsubscribed(channel, count);
localCounts.add(count);
}
};
pubsub.addListener(adapter);
pubsub.subscribe(channel);
pubsub.psubscribe(pattern);
assertEquals(1L, (long) localCounts.take());
redis.publish(channel, message);
pubsub.punsubscribe(pattern);
pubsub.unsubscribe(channel);
assertEquals(0L, (long) localCounts.take());
}
@Test(timeout = 1000)
public void removeListener() throws Exception {
pubsub.subscribe(channel);
assertEquals(channel, channels.take());
redis.publish(channel, message);
assertEquals(channel, channels.take());
assertEquals(message, messages.take());
pubsub.removeListener(this);
redis.publish(channel, message);
assertNull(channels.poll(10, TimeUnit.MILLISECONDS));
assertNull(messages.poll(10, TimeUnit.MILLISECONDS));
}
// RedisPubSubListener implementation
@Override
public void message(String channel, String message) {
channels.add(channel);
messages.add(message);
}
@Override
public void message(String pattern, String channel, String message) {
patterns.add(pattern);
channels.add(channel);
messages.add(message);
}
@Override
public void subscribed(String channel, long count) {
channels.add(channel);
counts.add(count);
}
@Override
public void psubscribed(String pattern, long count) {
patterns.add(pattern);
counts.add(count);
}
@Override
public void unsubscribed(String channel, long count) {
channels.add(channel);
counts.add(count);
}
@Override
public void punsubscribed(String pattern, long count) {
patterns.add(pattern);
counts.add(count);
}
}