/* * (C) 2007-2012 Alibaba Group Holding Limited. * * Licensed 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. * Authors: * wuhua <wq163@163.com> , boyan <killme2008@gmail.com> */ package com.taobao.metamorphosis.client.consumer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import org.easymock.classextension.EasyMock; import org.easymock.classextension.IMocksControl; import org.junit.Before; import org.junit.Test; import com.taobao.gecko.core.util.OpaqueGenerator; import com.taobao.metamorphosis.Message; import com.taobao.metamorphosis.client.RemotingClientWrapper; import com.taobao.metamorphosis.client.consumer.storage.OffsetStorage; import com.taobao.metamorphosis.client.producer.ProducerZooKeeper; import com.taobao.metamorphosis.cluster.Broker; import com.taobao.metamorphosis.cluster.Partition; import com.taobao.metamorphosis.consumer.MessageIterator; import com.taobao.metamorphosis.exception.MetaClientException; import com.taobao.metamorphosis.network.BooleanCommand; import com.taobao.metamorphosis.network.DataCommand; import com.taobao.metamorphosis.network.GetCommand; import com.taobao.metamorphosis.network.HttpStatus; import com.taobao.metamorphosis.network.OffsetCommand; public class SimpleMessageConsumerUnitTest { protected SimpleMessageConsumer consumer; protected ConsumerZooKeeper consumerZooKeeper; protected ProducerZooKeeper producerZooKeeper; protected OffsetStorage offsetStorage; protected IMocksControl mocksControl; protected ConsumerConfig consumerConfig; protected SubscribeInfoManager subscribeInfoManager; protected RecoverStorageManager recoverStorageManager; protected RemotingClientWrapper remotingClient; protected LoadBalanceStrategy loadBalanceStrategy; @Before public void setUp() { this.mocksControl = EasyMock.createControl(); this.consumerZooKeeper = this.mocksControl.createMock(ConsumerZooKeeper.class); this.producerZooKeeper = this.mocksControl.createMock(ProducerZooKeeper.class); this.remotingClient = this.mocksControl.createMock(RemotingClientWrapper.class); this.offsetStorage = this.mocksControl.createMock(OffsetStorage.class); this.subscribeInfoManager = new SubscribeInfoManager(); this.recoverStorageManager = this.mocksControl.createMock(RecoverStorageManager.class); this.consumerConfig = new ConsumerConfig(); this.loadBalanceStrategy = new DefaultLoadBalanceStrategy(); this.consumerConfig.setGroup("boyan"); this.consumer = new SimpleMessageConsumer(null, this.remotingClient, this.consumerConfig, this.consumerZooKeeper, this.producerZooKeeper, this.subscribeInfoManager, this.recoverStorageManager, this.offsetStorage, this.loadBalanceStrategy); EasyMock.makeThreadSafe(this.consumerZooKeeper, true); EasyMock.makeThreadSafe(this.producerZooKeeper, true); EasyMock.makeThreadSafe(this.remotingClient, true); EasyMock.makeThreadSafe(this.offsetStorage, true); EasyMock.makeThreadSafe(this.recoverStorageManager, true); } @Test public void testSubscribeCompleteSubscribe() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final MessageListener messageListener = new MessageListener() { @Override public void recieveMessages(final Message message) { } @Override public Executor getExecutor() { return null; } }; final ConcurrentHashMap<String/* topic */, SubscriberInfo> topicSubcriberRegistry = new ConcurrentHashMap<String, SubscriberInfo>(); topicSubcriberRegistry.put(topic, new SubscriberInfo(messageListener, null, maxSize)); this.consumerZooKeeper.registerConsumer(this.consumerConfig, this.consumer.getFetchManager(), topicSubcriberRegistry, this.offsetStorage, this.loadBalanceStrategy); EasyMock.expectLastCall(); this.mocksControl.replay(); this.consumer.subscribe(topic, maxSize, messageListener).completeSubscribe(); this.mocksControl.verify(); assertEquals(topicSubcriberRegistry, this.consumer.getTopicSubcriberRegistry()); } @Test(expected = MetaClientException.class) public void testSubscribeDuplicate() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final MessageListener messageListener = new MessageListener() { @Override public void recieveMessages(final Message message) { } @Override public Executor getExecutor() { return null; } }; this.consumer.subscribe(topic, maxSize, messageListener).subscribe(topic, maxSize, messageListener); } @Test public void testGet() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final Partition partition = new Partition("0-0"); final long offset = 12; final byte[] data = "hello".getBytes(); final String url = "meta://localhost:0"; final MessageIterator messageIterator = new MessageIterator(topic, data); this.producerZooKeeper.publishTopic(topic, this.consumer); EasyMock.expect(this.remotingClient.isConnected(url)).andReturn(true); EasyMock.expectLastCall(); EasyMock.expect(this.producerZooKeeper.selectBroker(topic, partition)).andReturn(url); EasyMock.expect( this.remotingClient.invokeToGroup(url, new GetCommand(topic, this.consumerConfig.getGroup(), partition.getPartition(), offset, maxSize, Integer.MIN_VALUE), 10000, TimeUnit.MILLISECONDS)).andReturn( new DataCommand(data, Integer.MIN_VALUE)); this.mocksControl.replay(); OpaqueGenerator.resetOpaque(); assertEquals(messageIterator, this.consumer.get(topic, partition, offset, maxSize)); this.mocksControl.verify(); } @Test public void testOffset() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final Partition partition = new Partition("0-0"); final long offset = 12; final String url = "meta://localhost:8123"; final Broker broker = new Broker(1, url); final long delay = 0; final TopicPartitionRegInfo topicPartitionRegInfo = new TopicPartitionRegInfo(topic, partition, offset); EasyMock.expect( this.remotingClient.invokeToGroup(url, new OffsetCommand(topic, this.consumerConfig.getGroup(), partition.getPartition(), offset, Integer.MIN_VALUE), this.consumerConfig.getFetchTimeoutInMills(), TimeUnit.MILLISECONDS)) .andReturn(new BooleanCommand(HttpStatus.Success, String.valueOf(offset), Integer.MIN_VALUE)); this.mocksControl.replay(); OpaqueGenerator.resetOpaque(); assertEquals(offset, this.consumer.offset(new FetchRequest(broker, delay, topicPartitionRegInfo, maxSize))); this.mocksControl.verify(); } @Test public void testGetFailed() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final Partition partition = new Partition("0-0"); final long offset = 12; final byte[] data = "hello".getBytes(); final String url = "meta://localhost:0"; final MessageIterator messageIterator = new MessageIterator(topic, data); this.producerZooKeeper.publishTopic(topic, this.consumer); EasyMock.expectLastCall(); EasyMock.expect(this.remotingClient.isConnected(url)).andReturn(true); EasyMock.expect(this.producerZooKeeper.selectBroker(topic, partition)).andReturn(url); EasyMock.expect( this.remotingClient.invokeToGroup(url, new GetCommand(topic, this.consumerConfig.getGroup(), partition.getPartition(), offset, maxSize, Integer.MIN_VALUE), 10000, TimeUnit.MILLISECONDS)).andReturn( new BooleanCommand(500, "test error", Integer.MIN_VALUE)); this.mocksControl.replay(); try { OpaqueGenerator.resetOpaque(); assertEquals(messageIterator, this.consumer.get(topic, partition, offset, maxSize)); fail(); } catch (final MetaClientException e) { } this.mocksControl.verify(); } @Test public void testGetNotFound() throws Exception { final String topic = "topic1"; final int maxSize = 1024; final Partition partition = new Partition("0-0"); final long offset = 12; final String url = "meta://localhost:0"; this.producerZooKeeper.publishTopic(topic, this.consumer); EasyMock.expectLastCall(); EasyMock.expect(this.remotingClient.isConnected(url)).andReturn(true); EasyMock.expect(this.producerZooKeeper.selectBroker(topic, partition)).andReturn(url); EasyMock.expect( this.remotingClient.invokeToGroup(url, new GetCommand(topic, this.consumerConfig.getGroup(), partition.getPartition(), offset, maxSize, Integer.MIN_VALUE), 10000, TimeUnit.MILLISECONDS)).andReturn( new BooleanCommand(404, "not found", Integer.MIN_VALUE)); this.mocksControl.replay(); OpaqueGenerator.resetOpaque(); assertNull(this.consumer.get(topic, partition, offset, maxSize)); this.mocksControl.verify(); } }