/**
* ZKBlockingQueueConcTest.java
*
* Copyright 2016 the original author or authors.
*
* We licenses this file to you 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 org.apache.niolex.queue;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.niolex.commons.test.MockUtil;
import org.apache.niolex.commons.util.Runner;
import org.apache.niolex.notify.AppTest;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* @author <a href="mailto:xiejiyun@foxmail.com">Xie, Jiyun</a>
* @version 2.1.2
* @since Jul 13, 2016
*/
public class ZKBlockingQueueConcTest {
private static String BS = "/queue/zkc/tmp-" + MockUtil.randInt(100, 999);
@BeforeClass
public static void setUpBeforeClass() throws Exception {
if (AppTest.APP.exists(BS))
AppTest.APP.deleteTree(BS);
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
AppTest.APP.deleteTree(BS);
}
ZKBlockingQueue<String> queue1;
ZKBlockingQueue<String> queue2;
@Before
public void setup() throws IOException {
queue1 = new ZKBlockingQueue<String>(AppTest.URL, 10000, BS);
queue2 = new ZKBlockingQueue<String>(AppTest.URL, 10000, BS + "/");
}
@After
public void clean() throws IOException {
queue1.close();
queue2.close();
}
@Test
public void testWholeQueue1() throws Exception {
queue1.offer("Hello");
queue1.offer("World");
queue1.offer("Lex");
queue1.offer("Nio");
assertEquals("Hello", queue2.poll(100, TimeUnit.MILLISECONDS));
assertEquals("World", queue2.poll());
assertEquals("Lex", queue1.peek());
assertEquals("Lex", queue2.peek());
assertEquals("Lex", queue2.poll());
assertEquals("Nio", queue1.poll());
assertEquals(0, queue1.size());
assertEquals(0, queue2.size());
}
public void generate(ZKBlockingQueue<String> queue, int size) throws InterruptedException {
while (size -- > 0) {
queue.put(MockUtil.randString(10));
}
}
private AtomicInteger cnt = new AtomicInteger(0);
public void take(ZKBlockingQueue<String> queue) throws InterruptedException {
String item;
int i = -1;
do {
item = queue.poll(10, TimeUnit.MILLISECONDS);
++i;
} while (item != null);
cnt.addAndGet(i);
}
@Test
public void testConcurrent() throws Exception {
final int ConcLevel = 8;
final int ItemCount = 100;
Thread[] tt = new Thread[ConcLevel];
for (int i = 0; i < ConcLevel; ++i) {
tt[i] = Runner.run(this, "generate", i % 2 == 0 ? queue1 : queue2, ItemCount);
}
for (int i = 0; i < ConcLevel; ++i) {
tt[i].join();
}
assertEquals(ConcLevel * ItemCount, queue1.size());
assertEquals(ConcLevel * ItemCount, queue2.size());
for (int i = 0; i < ConcLevel; ++i) {
tt[i] = Runner.run(this, "take", i % 2 == 0 ? queue1 : queue2);
}
for (int i = 0; i < ConcLevel; ++i) {
tt[i].join();
}
assertEquals(0, queue1.size());
assertEquals(0, queue2.size());
assertEquals(ConcLevel * ItemCount, cnt.get());
}
}