/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* 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
*******************************************************************************/
//B''H
package org.ebayopensource.turmeric.runtime.tests.spf.local;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.ebayopensource.turmeric.runtime.spf.impl.transport.local.LocalTransportPoller;
import org.junit.Test;
public class LocalTransportPollerTest {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(Runtime
.getRuntime().availableProcessors(), Runtime.getRuntime()
.availableProcessors(), 200, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
@Test
public void simpleTake() throws Exception {
LocalTransportPoller completionQueue = new LocalTransportPoller();
Sleeper aSleeper = new Sleeper(200, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(aSleeper));
Future<?> future = completionQueue.take();
assertTrue(future == aSleeper.getFuture());
future.get();
}
@Test
public void simplePoll() throws Exception {
LocalTransportPoller completionQueue = new LocalTransportPoller();
Sleeper aSleeper = new Sleeper(500, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(aSleeper));
Future<?> future = completionQueue.poll();
assertNull(future);
for (int i = 0; i < 100 && future == null; i++) {
future = completionQueue.poll();
Thread.sleep(100);
}
assertTrue(future == aSleeper.getFuture());
future.get();
}
@Test
public void simpleBlockingPoll() throws Exception {
LocalTransportPoller completionQueue = new LocalTransportPoller();
Sleeper aSleeper = new Sleeper(200, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(aSleeper));
List<Future<?>> futures = completionQueue.poll(true);
assertTrue(futures.size() == 1);
futures.get(0).get();
}
@Test
public void simpleNonBlockingPoll() throws Exception {
LocalTransportPoller completionQueue = new LocalTransportPoller();
Sleeper aSleeper = new Sleeper(500, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(aSleeper));
List<Future<?>> futures = completionQueue.poll(false);
assertTrue(futures.size() == 0);
futures = null;
for (int i = 0; i < 10; i++) {
futures = completionQueue.poll(false);
if (futures.size() > 0)
break;
Thread.sleep(100);
}
assertTrue(futures.size() == 1);
futures.get(0).get();
}
@Test
public void blockingPoll() throws Exception {
testPoll(true);
}
@Test
public void nonBlockingPoll() throws Exception {
testPoll(false);
}
private void testPoll(boolean block) throws Exception {
LocalTransportPoller completionQueue = new LocalTransportPoller();
Sleeper sleeper1 = new Sleeper(500, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(sleeper1));
Sleeper sleeper2 = new Sleeper(200, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(sleeper2));
Sleeper sleeper3 = new Sleeper(100, completionQueue.getBlockingQueue());
executor.execute(new CustomFutureTask(sleeper3));
int size = 0;
List<Future<?>> futures = null;
boolean r1Done = false, r2Done = false, r3Done = false;
for (int i = 0; i < 300 && size < 3; i++) {
futures = completionQueue.poll(block);
if (block)
assertTrue(futures.size() > 0);
size += futures.size();
for (Future<?> future : futures) {
if (future == sleeper1.getFuture() && !r1Done)
r1Done = true;
else if (future == sleeper2.getFuture() && !r2Done)
r2Done = true;
else if (future == sleeper3.getFuture() && !r3Done)
r3Done = true;
else
fail("Duplicate or unrecognized response");
}
futures = null;
Thread.sleep(100);
}
assertTrue(size == 3);
assertTrue(r1Done && r2Done && r3Done);
}
private static class CustomFutureTask extends FutureTask<Long> {
public CustomFutureTask(Sleeper sleeper) {
super(sleeper);
sleeper.setFuture(this);
}
}
private static class Sleeper implements Callable<Long> {
private long wait = 100;
private final BlockingQueue<Future<?>> blockingQueue;
private FutureTask<Long> future;
public Sleeper(long wait, BlockingQueue<Future<?>> blockingQueue) {
this.wait = wait;
this.blockingQueue = blockingQueue;
}
public void setFuture(FutureTask<Long> future) {
this.future = future;
}
public FutureTask<Long> getFuture() {
return this.future;
}
public Long call() throws Exception {
try {
Thread.sleep(wait);
return new Long(wait);
} finally {
blockingQueue.add(future);
}
}
}
}