package com.taobao.metamorphosis.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.TimeUnit; import org.easymock.EasyMock; import org.easymock.IMocksControl; import org.junit.Before; import org.junit.Test; import com.taobao.metamorphosis.Message; import com.taobao.metamorphosis.MessageAccessor; import com.taobao.metamorphosis.client.consumer.MessageConsumer; import com.taobao.metamorphosis.cluster.Partition; import com.taobao.metamorphosis.consumer.MessageIterator; import com.taobao.metamorphosis.utils.CheckSum; import com.taobao.metamorphosis.utils.MessageUtils; public class MetaTopicBrowserUnitTest { private MetaTopicBrowser browser; private List<Partition> partitions; private final String topic = "test"; private final int maxSize = 1024; private final long timeoutInMills = 1000L; private MessageConsumer consumer; private IMocksControl control; @Before public void setUp() { this.control = EasyMock.createControl(); this.consumer = this.control.createMock(MessageConsumer.class); this.partitions = new ArrayList<Partition>(); for (int i = 0; i < 3; i++) { this.partitions.add(new Partition("0-" + i)); } this.browser = new MetaTopicBrowser(this.topic, this.maxSize, this.timeoutInMills, this.consumer, this.partitions); } private byte[] createMessageBuffer() { final ByteBuffer buf = ByteBuffer.allocate(MessageUtils.HEADER_LEN + 5); buf.putInt(5);// msg length buf.putInt(CheckSum.crc32("hello".getBytes())); // checksum buf.putLong(9999); // id buf.putInt(0); // flag buf.position(MessageUtils.HEADER_LEN); buf.put("hello".getBytes()); return buf.array(); } private void assertMsg(Message msg) { assertNotNull(msg); assertEquals(9999L, msg.getId()); assertEquals("test", msg.getTopic()); assertFalse(msg.hasAttribute()); assertEquals(0, MessageAccessor.getFlag(msg)); assertEquals("hello", new String(msg.getData())); } @Test public void testIteratorInSamePartition() throws Exception { EasyMock .expect( this.consumer.get(this.topic, new Partition("0-0"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-0"), 25L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); this.control.replay(); Iterator<Message> it = this.browser.iterator(); if (it.hasNext()) { this.assertMsg(it.next()); } if (it.hasNext()) { this.assertMsg(it.next()); } this.control.verify(); MetaTopicBrowser.Itr mit = (MetaTopicBrowser.Itr) it; assertEquals(2, mit.partitions.size()); assertFalse(mit.partitions.contains(new Partition("0-0"))); } @Test public void testIteratorMoveOnPartition() throws Exception { EasyMock .expect( this.consumer.get(this.topic, new Partition("0-0"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); EasyMock.expect( this.consumer.get(this.topic, new Partition("0-0"), 25L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(null); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-1"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); this.control.replay(); Iterator<Message> it = this.browser.iterator(); if (it.hasNext()) { this.assertMsg(it.next()); } if (it.hasNext()) { this.assertMsg(it.next()); } this.control.verify(); MetaTopicBrowser.Itr mit = (MetaTopicBrowser.Itr) it; assertEquals(1, mit.partitions.size()); assertFalse(mit.partitions.contains(new Partition("0-0"))); assertFalse(mit.partitions.contains(new Partition("0-1"))); } @Test public void testIteratorToEnd() throws Exception { EasyMock .expect( this.consumer.get(this.topic, new Partition("0-0"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); EasyMock.expect( this.consumer.get(this.topic, new Partition("0-0"), 25L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(null); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-1"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-1"), 25L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(null).once(); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-2"), 0L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(new MessageIterator(this.topic, this.createMessageBuffer())) .once(); EasyMock .expect( this.consumer.get(this.topic, new Partition("0-2"), 25L, this.maxSize, this.timeoutInMills, TimeUnit.MILLISECONDS)).andReturn(null).once(); this.control.replay(); Iterator<Message> it = this.browser.iterator(); if (it.hasNext()) { this.assertMsg(it.next()); } if (it.hasNext()) { this.assertMsg(it.next()); } if (it.hasNext()) { this.assertMsg(it.next()); } assertFalse(it.hasNext()); assertFalse(it.hasNext()); assertFalse(it.hasNext()); this.control.verify(); MetaTopicBrowser.Itr mit = (MetaTopicBrowser.Itr) it; assertEquals(0, mit.partitions.size()); try { it.next(); fail(); } catch (NoSuchElementException e) { } } }