/* * (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.server.store; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.concurrent.CountDownLatch; import junit.framework.Assert; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.taobao.metamorphosis.network.PutCommand; import com.taobao.metamorphosis.server.utils.MetaConfig; import com.taobao.metamorphosis.server.utils.TopicConfig; import com.taobao.metamorphosis.utils.IdWorker; public class MessageStoreManagerUnitTest { private MessageStoreManager messageStoreManager; private MetaConfig metaConfig; @Before public void setUp() throws Exception { this.metaConfig = new MetaConfig(); final String topic = "MessageStoreManagerUnitTest"; this.metaConfig.getTopics().add(topic); final TopicConfig topicConfig = new TopicConfig(topic, this.metaConfig); topicConfig.setDeletePolicy("delete,10s"); topicConfig.setDeleteWhen("0/1 * * * * ?"); this.metaConfig.getTopicConfigMap().put(topic, topicConfig); FileUtils.deleteDirectory(new File(this.metaConfig.getDataPath())); this.messageStoreManager = new MessageStoreManager(this.metaConfig, null); } @After public void tearDown() throws Exception { this.messageStoreManager.dispose(); } @Test public void testGetOrCreateMessageStore() throws Exception { final String topic = "MessageStoreManagerUnitTest"; final int partition = 0; final File dir = new File(this.metaConfig.getDataPath() + File.separator + topic + "-" + partition); assertFalse(dir.exists()); assertNull(this.messageStoreManager.getMessageStore(topic, partition)); final MessageStore store1 = this.messageStoreManager.getOrCreateMessageStore(topic, partition); assertTrue(dir.exists()); final MessageStore store2 = this.messageStoreManager.getMessageStore(topic, partition); assertSame(store1, store2); } @Test public void testGetOrCreateMessageStore_withOffset() throws Exception { final String topic = "MessageStoreManagerUnitTest"; final int partition = 0; final File dir = new File(this.metaConfig.getDataPath() + File.separator + topic + "-" + partition); assertFalse(dir.exists()); assertNull(this.messageStoreManager.getMessageStore(topic, partition)); final MessageStore store1 = this.messageStoreManager.getOrCreateMessageStore(topic, partition, 2048); assertTrue(dir.exists()); final MessageStore store2 = this.messageStoreManager.getMessageStore(topic, partition); assertSame(store1, store2); assertEquals(2048, store2.getMinOffset()); final IdWorker idWorker = new IdWorker(0); final PutCommand cmd1 = new PutCommand(topic, partition, "hello".getBytes(), null, 0, 0); final PutCommand cmd2 = new PutCommand(topic, partition, "world".getBytes(), null, 0, 0); store1.append(idWorker.nextId(), cmd1, new AppendCallback() { @Override public void appendComplete(final Location location) { assertEquals(2048, location.getOffset()); } }); store1.flush();// flushһ�� final long size = store1.getSegments().last().size(); store1.append(idWorker.nextId(), cmd2, new AppendCallback() { @Override public void appendComplete(final Location location) { assertEquals(2048 + size, location.getOffset()); } }); store1.flush(); assertEquals(1, dir.listFiles().length); assertTrue(dir.listFiles()[0].exists()); assertEquals(store1.nameFromOffset(2048), dir.listFiles()[0].getName()); store1.close(); for (final File file : dir.listFiles()) { file.delete(); } } @Test public void testChooseRandomPartition() { assertEquals(0, this.messageStoreManager.chooseRandomPartition("MessageStoreManagerUnitTest")); assertEquals(0, this.messageStoreManager.chooseRandomPartition("MessageStoreManagerUnitTest")); assertEquals(0, this.messageStoreManager.chooseRandomPartition("MessageStoreManagerUnitTest")); this.metaConfig.setNumPartitions(10); for (int i = 0; i < 100; i++) { assertTrue(this.messageStoreManager.chooseRandomPartition("MessageStoreManagerUnitTest") < 10); } } @Test public void testGetNumPartitions() { assertEquals(1, this.messageStoreManager.getNumPartitions("MessageStoreManagerUnitTest")); assertEquals(1, this.messageStoreManager.getNumPartitions("MessageStoreManagerUnitTest")); final TopicConfig topicConfig = new TopicConfig("MessageStoreManagerUnitTest", this.metaConfig); topicConfig.setNumPartitions(9999); this.metaConfig.getTopicConfigMap().put("MessageStoreManagerUnitTest", topicConfig); assertEquals(9999, this.messageStoreManager.getNumPartitions("MessageStoreManagerUnitTest")); assertEquals(9999, this.messageStoreManager.getNumPartitions("MessageStoreManagerUnitTest")); } @Test public void testInit() throws Exception { this.testInit0(false); } @Test public void testInitInParallel() throws Exception { this.testInit0(true); } private void testInit0(boolean inParallel) throws IOException, InterruptedException { final String topic = "MessageStoreManagerUnitTest"; IdWorker idWorker = new IdWorker(0); final TopicConfig topicConfig = new TopicConfig(topic, this.metaConfig); topicConfig.setNumPartitions(10); this.metaConfig.getTopicConfigMap().put("MessageStoreManagerUnitTest", topicConfig); this.metaConfig.setLoadMessageStoresInParallel(inParallel); for (int i = 0; i < 10; i++) { final MessageStore store = this.messageStoreManager.getMessageStore(topic, i); Assert.assertNull(store); } final CountDownLatch latch = new CountDownLatch(1000); for (int i = 0; i < 10; i++) { final MessageStore store = this.messageStoreManager.getOrCreateMessageStore(topic, i); for (int j = 0; j < 100; j++) { final PutCommand cmd = new PutCommand(topic, i, new byte[1024], null, 0, 0); final long id = idWorker.nextId(); store.append(id, cmd, new AppendCallback() { @Override public void appendComplete(Location location) { if (location == Location.InvalidLocaltion) { throw new IllegalStateException(); } latch.countDown(); } }); } } latch.await(); for (int i = 0; i < 10; i++) { final MessageStore store = this.messageStoreManager.getMessageStore(topic, i); Assert.assertNotNull(store); } this.messageStoreManager.dispose(); this.messageStoreManager = new MessageStoreManager(this.metaConfig, null); this.messageStoreManager.init(); for (int i = 0; i < 10; i++) { final MessageStore store = this.messageStoreManager.getMessageStore(topic, i); Assert.assertNotNull(store); } } @Test public void testRunDeletePolicy() throws Exception { this.metaConfig.setMaxSegmentSize(1024); this.messageStoreManager.init(); final String topic = "MessageStoreManagerUnitTest"; final int partition = 0; final File dir = new File(this.metaConfig.getDataPath() + File.separator + topic + "-" + partition); assertFalse(dir.exists()); assertNull(this.messageStoreManager.getMessageStore(topic, partition)); final MessageStore store = this.messageStoreManager.getOrCreateMessageStore(topic, partition); final IdWorker idWorker = new IdWorker(0); final byte[] data = new byte[1024]; final PutCommand cmd1 = new PutCommand(topic, partition, data, null, 0, 0); final PutCommand cmd2 = new PutCommand(topic, partition, data, null, 0, 0); store.append(idWorker.nextId(), cmd1, new AppendCallback() { @Override public void appendComplete(final Location location) { assertEquals(0, location.getOffset()); } }); store.flush();// flushһ�� store.append(idWorker.nextId(), cmd2, new AppendCallback() { @Override public void appendComplete(final Location location) { assertEquals(1044, location.getOffset()); } }); store.flush(); System.out.println(store.getSegmentInfos().size()); assertFalse(store.getSegmentInfos().isEmpty()); assertEquals(3, store.getSegmentInfos().size()); // Wait for 10 seconds Thread.sleep(15000); System.out.println(store.getSegmentInfos().size()); assertEquals(1, store.getSegmentInfos().size()); } @Test public void testIsLegalTopicWildChar() throws Exception { this.metaConfig.getTopics().add("TBCTU-*"); this.tearDown(); this.messageStoreManager = new MessageStoreManager(this.metaConfig, null); assertTrue(this.messageStoreManager.isLegalTopic("TBCTU-test")); assertTrue(this.messageStoreManager.isLegalTopic("TBCTU-2343")); assertTrue(this.messageStoreManager.isLegalTopic("TBCTU-TBCTU")); assertTrue(this.messageStoreManager.isLegalTopic("TBCTU-")); assertFalse(this.messageStoreManager.isLegalTopic("a-TBCTU-")); assertFalse(this.messageStoreManager.isLegalTopic("TCCTU-test")); } }