/** * Copyright 2015, Xiaomi. * All rights reserved. * Author: yongxing@xiaomi.com */ package com.xiaomi.infra.galaxy.talos.producer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import com.xiaomi.infra.galaxy.talos.client.TalosClientConfigKeys; import com.xiaomi.infra.galaxy.talos.client.Utils; import com.xiaomi.infra.galaxy.talos.thrift.ErrorCode; import com.xiaomi.infra.galaxy.talos.thrift.GalaxyTalosException; import com.xiaomi.infra.galaxy.talos.thrift.Message; import com.xiaomi.infra.galaxy.talos.thrift.MessageService; import com.xiaomi.infra.galaxy.talos.thrift.MessageType; import com.xiaomi.infra.galaxy.talos.thrift.PutMessageRequest; import com.xiaomi.infra.galaxy.talos.thrift.PutMessageResponse; import com.xiaomi.infra.galaxy.talos.thrift.TopicTalosResourceName; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.when; public class PartitionSenderTest { private static final String resourceName = "12345#TopicName#july777777000999"; private static final String topicName = "TopicName"; private static TopicTalosResourceName talosResourceName; private static TalosProducerConfig talosProducerConfig; private static PartitionSender partitionSender; private static MessageService.Iface messageClientMock; private static TalosProducer producerMock; private static MessageCallback messageCallback; private static ExecutorService messageCallbackExecutors; private static UserMessage userMessage1; private static UserMessage userMessage2; private static UserMessage userMessage3; private static UserMessage userMessage4; private static final Object globalLock = new Object(); private static final int producerMaxBufferedMillSecs = 10; private static final int producerMaxPutMsgNumber = 5; private static final int producerMaxPutMsgBytes = 50; private static final int producerMaxBufferedMsgNum = 50; private static final int partitionId = 0; private static final AtomicLong requestId = new AtomicLong(1); private static List<UserMessage> userMessageList; private static volatile int msgPutSuccessCount; private static volatile int msgPutFailureCount; private class MessageCallback implements UserMessageCallback { @Override public void onSuccess(UserMessageResult userMessageResult) { msgPutSuccessCount += userMessageResult.getMessageList().size(); } @Override public void onError(UserMessageResult userMessageResult) { msgPutFailureCount += userMessageResult.getMessageList().size(); } } private void clearCounter() { msgPutFailureCount = 0; msgPutSuccessCount = 0; } @Before public void setUp() { Properties properties = new Properties(); properties.setProperty( TalosClientConfigKeys.GALAXY_TALOS_PRODUCER_MAX_BUFFERED_MILLI_SECS, String.valueOf(producerMaxBufferedMillSecs)); properties.setProperty( TalosClientConfigKeys.GALAXY_TALOS_PRODUCER_MAX_PUT_MESSAGE_NUMBER, String.valueOf(producerMaxPutMsgNumber)); properties.setProperty( TalosClientConfigKeys.GALAXY_TALOS_PRODUCER_MAX_PUT_MESSAGE_BYTES, String.valueOf(producerMaxPutMsgBytes)); properties.setProperty( TalosClientConfigKeys.GALAXY_TALOS_PRODUCER_MAX_BUFFERED_MESSAGE_NUMBER, String.valueOf(producerMaxBufferedMsgNum)); properties.setProperty( TalosClientConfigKeys.GALAXY_TALOS_SERVICE_ENDPOINT, "testURI"); talosProducerConfig = new TalosProducerConfig(properties, false); talosResourceName = new TopicTalosResourceName(resourceName); messageCallback = new MessageCallback(); messageCallbackExecutors = Executors.newFixedThreadPool( talosProducerConfig.getThreadPoolsize()); messageClientMock = Mockito.mock(MessageService.Iface.class); producerMock = Mockito.mock(TalosProducer.class); userMessageList = new ArrayList<UserMessage>(); userMessage1 = new UserMessage( new Message(ByteBuffer.wrap("hello".getBytes())).setMessageType(MessageType.BINARY)); userMessage2 = new UserMessage( new Message(ByteBuffer.wrap("world".getBytes())).setMessageType(MessageType.BINARY)); userMessage3 = new UserMessage( new Message(ByteBuffer.wrap("nice day".getBytes())).setMessageType(MessageType.BINARY)); userMessage4 = new UserMessage( new Message(ByteBuffer.wrap("good guy".getBytes())).setMessageType(MessageType.BINARY)); } @After public void tearDown() {} @Test public void testPartitionSenderSuccessPut() throws Exception { userMessageList.add(userMessage1); userMessageList.add(userMessage2); userMessageList.add(userMessage3); userMessageList.add(userMessage4); doReturn(new PutMessageResponse()).when(messageClientMock).putMessage(any(PutMessageRequest.class)); doReturn(true).doReturn(false).when(producerMock).isActive(); partitionSender = new PartitionSender(partitionId, topicName, talosResourceName, requestId, Utils.generateClientId(), talosProducerConfig, messageClientMock, messageCallback, messageCallbackExecutors, globalLock, producerMock); int addCount = 50; while (addCount-- > 0) { partitionSender.addMessage(userMessageList); } partitionSender.shutdown(); assertEquals(200, msgPutSuccessCount); clearCounter(); } @Test public void testPartitionSenderFailedPut() throws Exception { userMessageList.add(userMessage1); userMessageList.add(userMessage2); userMessageList.add(userMessage3); userMessageList.add(userMessage4); when(messageClientMock.putMessage(any(PutMessageRequest.class))) .thenThrow(new GalaxyTalosException().setErrMsg("put failed")); doReturn(true).doReturn(false).when(producerMock).isActive(); partitionSender = new PartitionSender(partitionId, topicName, talosResourceName, requestId, Utils.generateClientId(), talosProducerConfig, messageClientMock, messageCallback, messageCallbackExecutors, globalLock, producerMock); partitionSender.addMessage(userMessageList); partitionSender.shutdown(); assertEquals(0, msgPutSuccessCount); assertEquals(4, msgPutFailureCount); clearCounter(); } @Test public void testPartitionQueueWaitToPut() throws Exception { userMessageList.add(userMessage1); userMessageList.add(userMessage2); doReturn(new PutMessageResponse()).when(messageClientMock).putMessage(any(PutMessageRequest.class)); doReturn(true).doReturn(false).when(producerMock).isActive(); partitionSender = new PartitionSender(partitionId, topicName, talosResourceName, requestId, Utils.generateClientId(), talosProducerConfig, messageClientMock, messageCallback, messageCallbackExecutors, globalLock, producerMock); partitionSender.addMessage(userMessageList); partitionSender.shutdown(); assertEquals(2, msgPutSuccessCount); clearCounter(); } @Test public void testPartitiionNotServingDelay() throws Exception { userMessageList.add(userMessage1); userMessageList.add(userMessage2); when(messageClientMock.putMessage(any(PutMessageRequest.class))) .thenThrow(new GalaxyTalosException().setErrorCode( ErrorCode.PARTITION_NOT_SERVING)); doReturn(true).doReturn(false).when(producerMock).isActive(); partitionSender = new PartitionSender(partitionId, topicName, talosResourceName, requestId, Utils.generateClientId(), talosProducerConfig, messageClientMock, messageCallback, messageCallbackExecutors, globalLock, producerMock); partitionSender.addMessage(userMessageList); partitionSender.shutdown(); assertEquals(2, msgPutFailureCount); clearCounter(); } }