package com.leansoft.luxun.producer;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.easymock.EasyMock;
import org.junit.Test;
import static com.leansoft.luxun.utils.CollectionEqualsMatcher.colEq;
import com.leansoft.luxun.api.generated.ProduceRequest;
import com.leansoft.luxun.common.exception.QueueClosedException;
import com.leansoft.luxun.common.exception.QueueFullException;
import com.leansoft.luxun.message.Message;
import com.leansoft.luxun.message.MessageList;
import com.leansoft.luxun.producer.SyncProducer;
import com.leansoft.luxun.producer.SyncProducerConfig;
import com.leansoft.luxun.producer.async.AsyncProducer;
import com.leansoft.luxun.producer.async.AsyncProducerConfig;
import com.leansoft.luxun.serializer.StringEncoder;
import com.leansoft.luxun.utils.TestUtils;
public class AsyncProducerTest {
private String messageContent1 = "test";
private String topic1 = "test-topic";
private Message message1 = new Message(messageContent1.getBytes());
private String messageContent2 = "test1";
private String topic2 = "test1$topic";
private Message message2 = new Message(messageContent2.getBytes());
@Test
public void testProducerQueueSize() throws Exception {
SyncProducer basicProducer = EasyMock.createMock(SyncProducer.class);
List<Message> messages = new ArrayList<Message>();
messages.add(message1);
List<ProduceRequest> produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 10).toThriftBuffer(), topic1));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall();
basicProducer.close();
EasyMock.expectLastCall();
EasyMock.replay(basicProducer);
Properties props = new Properties();
props.put("host", "127.0.0.1");
props.put("port", "9092");
props.put("queue.size", "10");
props.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
props.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(props);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
try {
for(int i = 0; i < 11; i++) {
producer.send(topic1, messageContent1);
}
fail("Queue should be full");
} catch (QueueFullException qfe) {
System.out.println("Queue is full");
}
producer.start();
producer.close();
Thread.sleep(2000);
EasyMock.verify(basicProducer);
}
@Test
public void testAddAfterQueueClosed() throws Exception {
SyncProducer basicProducer = EasyMock.createMock(SyncProducer.class);
List<Message> messages = new ArrayList<Message>();
messages.add(message1);
List<ProduceRequest> produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 10).toThriftBuffer(), topic1));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall();
basicProducer.close();
EasyMock.expectLastCall();
EasyMock.replay(basicProducer);
Properties props = new Properties();
props.put("host", "127.0.0.1");
props.put("port", "9092");
props.put("queue.size", "10");
props.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
props.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(props);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
producer.start();
for(int i = 0; i < 10; i++) {
producer.send(topic1, messageContent1);
}
producer.close();
try {
producer.send(topic1, messageContent1);
fail("Queue should be closed");
} catch (QueueClosedException e) {
// expected
}
EasyMock.verify(basicProducer);
}
@Test
public void testBatchSize() throws Exception {
SyncProducer basicProducer = EasyMock.createMock(SyncProducer.class);
List<Message> messages = new ArrayList<Message>();
messages.add(message1);
List<ProduceRequest> produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 5).toThriftBuffer(), topic1));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall().times(2);
produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 1).toThriftBuffer(), topic1));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall();
basicProducer.close();
EasyMock.expectLastCall();
EasyMock.replay(basicProducer);
Properties props = new Properties();
props.put("host", "127.0.0.1");
props.put("port", "9092");
props.put("queue.size", "10");
props.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
props.put("batch.size", "5");
props.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(props);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
producer.start();
for(int i = 0; i < 10; i++) {
producer.send(topic1, messageContent1);
}
Thread.sleep(100);
try {
producer.send(topic1, messageContent1);
} catch (QueueFullException qfe) {
fail("Queue should not be full");
}
producer.close();
EasyMock.verify(basicProducer);
}
@Test
public void testQueueTimeExpired() throws Exception {
SyncProducer basicProducer = EasyMock.createMock(SyncProducer.class);
List<Message> messages = new ArrayList<Message>();
messages.add(message1);
List<ProduceRequest> produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 3).toThriftBuffer(), topic1));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall();
basicProducer.close();
EasyMock.expectLastCall();
EasyMock.replay(basicProducer);
Properties props = new Properties();
props.put("host", "127.0.0.1");
props.put("port", "9092");
props.put("queue.size", "10");
props.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
props.put("queue.time", "200");
props.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(props);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
producer.start();
for(int i = 0; i < 3; i++) {
producer.send(topic1, messageContent1);
}
Thread.sleep(300);
producer.close();
EasyMock.verify(basicProducer);
}
@Test
public void testSenderThreadShutdown() throws Exception {
Properties syncProducerProps = new Properties();
syncProducerProps.put("host", "127.0.0.1");
syncProducerProps.put("port", "9092");
syncProducerProps.put("buffer.size", "1000");
syncProducerProps.put("connect.timeout.ms", "1000");
syncProducerProps.put("reconnect.interval", "1000");
SyncProducer basicProducer = new MockProducer(new SyncProducerConfig(syncProducerProps));
Properties asyncProducerProps = new Properties();
asyncProducerProps.put("host", "127.0.0.1");
asyncProducerProps.put("port", "9092");
asyncProducerProps.put("queue.size", "10");
asyncProducerProps.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
asyncProducerProps.put("queue.time", "100");
asyncProducerProps.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(asyncProducerProps);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
producer.start();
producer.send(topic1, messageContent1);
producer.close();
}
@Test
public void testCollateEvents() throws Exception {
SyncProducer basicProducer = EasyMock.createMock(SyncProducer.class);
List<Message> messages = new ArrayList<Message>();
messages.add(message1);
List<ProduceRequest> produceRequests = new ArrayList<ProduceRequest>();
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 5).toThriftBuffer(), topic1));
messages.clear();
messages.add(message2);
produceRequests.add(new ProduceRequest(this.getMessageListOfSize(messages, 5).toThriftBuffer(), topic2));
basicProducer.multiSend((List<ProduceRequest>) colEq(produceRequests));
EasyMock.expectLastCall();
basicProducer.close();
EasyMock.expectLastCall();
EasyMock.replay(basicProducer);
Properties props = new Properties();
props.put("host", "127.0.0.1");
props.put("port", "9092");
props.put("queue.size", "50");
props.put("serializer.class", "com.leansoft.luxun.serializer.StringEncoder");
props.put("batch.size", "10");
props.put("broker.list", TestUtils.brokerList);
AsyncProducerConfig config = new AsyncProducerConfig(props);
AsyncProducer<String> producer = new AsyncProducer<String>(config, basicProducer, new StringEncoder(), null, null, null, null);
producer.start();
for(int i = 0; i < 5; i++) {
producer.send(messageContent1 + "-topic", messageContent1);
producer.send(messageContent2 + "$topic", messageContent2);
}
producer.close();
EasyMock.verify(basicProducer);
}
private MessageList getMessageListOfSize(List<Message> messages, int count) {
MessageList messageList = new MessageList();
for(Message message : messages) {
for(int i = 0; i < count; i++) {
messageList.add(message);
}
}
return messageList;
}
static class MockProducer extends SyncProducer {
public MockProducer(SyncProducerConfig config) {
super(config);
}
@Override
public void send(String topic, MessageList messageList) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignore
}
}
@Override
public void multiSend(List<ProduceRequest> requests) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// ignore
}
}
}
}