/* * Copyright 2013 Netflix, Inc. * * 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. */ package com.netflix.suro.queue; import com.netflix.suro.message.Message; import com.netflix.suro.message.MessageSerDe; import com.netflix.suro.message.StringSerDe; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.IOException; import java.util.Iterator; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.*; public class TestFileBlockingQueue { @Rule public TemporaryFolder tempDir = new TemporaryFolder(); @Test public void testOpenAndReadFromStart() throws IOException { final FileBlockingQueue<String> queue = getFileBlockingQueue(); createFile(queue, 3000); int count = 0; for (String m : new Iterable<String>() { @Override public Iterator<String> iterator() { return queue.iterator(); } }) { assertEquals(m, "testString" + count); ++count; } assertEquals(count, 3000); } private FileBlockingQueue<String> getFileBlockingQueue() throws IOException { return new FileBlockingQueue<String>( tempDir.newFolder().getAbsolutePath(), "default", 3600, new StringSerDe()); } @Test public void testOpenAndReadFromMark() throws IOException { final FileBlockingQueue<String> queue = getFileBlockingQueue(); createFile(queue, 3000); int count = 0; for (String m : new Iterable<String>() { @Override public Iterator<String> iterator() { return queue.iterator(); } }) { assertEquals(m, "testString" + count); ++count; } assertEquals(count, 3000); count = 0; createFile(queue, 3000); for (String m : new Iterable<String>() { @Override public Iterator<String> iterator() { return queue.iterator(); } }) { assertEquals(m, "testString" + count); ++count; } assertEquals(count, 3000); } @Test public void testPollWait() throws InterruptedException, IOException { final FileBlockingQueue<String> queue = getFileBlockingQueue(); final AtomicLong start = new AtomicLong(System.currentTimeMillis()); String m = queue.poll(1000, TimeUnit.MILLISECONDS); final AtomicLong duration = new AtomicLong(System.currentTimeMillis() - start.get()); assertTrue(duration.get() >= 1000 && duration.get() <= 2000); assertNull(m); ExecutorService e = Executors.newFixedThreadPool(1); e.execute(new Runnable() { @Override public void run() { start.set(System.currentTimeMillis()); String m = null; try { m = queue.poll(5000, TimeUnit.MILLISECONDS); } catch (InterruptedException e1) { throw new RuntimeException(e1); } assertNotNull(m); duration.set(System.currentTimeMillis() - start.get()); } }); Thread.sleep(1000); queue.offer("testString"); assertTrue(duration.get() < 4000); } private void createFile(FileBlockingQueue<String> queue, int count) throws IOException { for (int i = 0; i < count; ++i) { assertTrue(queue.offer("testString" + i)); } } @Test public void testMultithreaded() throws IOException, InterruptedException { final FileBlockingQueue<Message> queue = new FileBlockingQueue<Message>( tempDir.newFolder().getAbsolutePath(), "default", 3600, new MessageSerDe()); final int messagecount = 100; final int threadCount = 10; ExecutorService executors = Executors.newFixedThreadPool(threadCount); final CountDownLatch latch = new CountDownLatch(threadCount + 1); final CountDownLatch producerStartLatch = new CountDownLatch(1); final CountDownLatch consumerStartLatch = new CountDownLatch(1); for (int i = 0; i < threadCount; ++i) { executors.execute(new Runnable() { @Override public void run() { try { producerStartLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for (int j = 0; j < messagecount; ++j) { String str = generateRandomString(); Message msg = new Message("testRoutingKey", str.getBytes()); queue.offer(msg); } latch.countDown(); consumerStartLatch.countDown(); } }); } executors.execute(new Runnable() { @Override public void run() { try { consumerStartLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < threadCount * messagecount; ++i) { Message msg = queue.poll(); assertEquals(msg.getRoutingKey(), "testRoutingKey"); assertEquals(new String(msg.getPayload()).length(), 4096); } latch.countDown(); } }); producerStartLatch.countDown(); latch.await(); } public String generateRandomString() { Random rand = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 4096; ++i) { sb.append((char) (rand.nextInt(95) + 32)); } return sb.toString(); } }