/*
* Copyright 2009-2010 Brian S O'Neill
*
* 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 org.cojen.dirmi;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
/**
*
*
* @author Brian S O'Neill
*/
public class TestBatchedMethods extends AbstractTestSuite {
public static void main(String[] args) {
org.junit.runner.JUnitCore.main(TestBatchedMethods.class.getName());
}
protected SessionStrategy createSessionStrategy(Environment env) throws Exception {
return new PipedSessionStrategy(env, null, new RemoteBatchedServer());
}
@Test
public void oneTask() throws Exception {
RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
assertFalse(server instanceof RemoteBatchedServer);
Listener listener = new Listener();
server.register(listener);
server.startTask("one");
assertNull(listener.dequeue(1000));
// Force flush.
server.syncNop();
assertEquals("root", listener.dequeue(1000));
assertEquals("one", listener.dequeue(1000));
server.startTask("two");
assertNull(listener.dequeue(1000));
// Force flush with async immediate call mode.
server.asyncNop();
assertEquals("root", listener.dequeue(1000));
assertEquals("two", listener.dequeue(1000));
server.startTask("three");
assertNull(listener.dequeue(1000));
// This won't force a flush.
server.eventualNop();
assertNull(listener.dequeue(1000));
// This will force a flush.
sessionStrategy.localSession.flush();
assertEquals("root", listener.dequeue(1000));
assertEquals("three", listener.dequeue(1000));
}
@Test
public void taskFlood() throws Exception {
RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
Listener listener = new Listener();
server.register(listener);
int count = 10000;
for (int i=0; i<count; i++) {
server.startTask(Integer.toString(i));
}
// Some will have flushed, but some are still buffered.
int received = 0;
while (true) {
String name = listener.dequeue(0);
if (name == null) {
break;
}
assertEquals("root", name);
String op = listener.dequeue(1000);
assertEquals(Integer.toString(received), op);
received++;
}
assertTrue(received < count);
// Force flush.
server.syncNop();
while (true) {
String name = listener.dequeue(1000);
if (name == null) {
break;
}
assertEquals("root", name);
String op = listener.dequeue(1000);
assertEquals(Integer.toString(received), op);
received++;
}
assertEquals(count, received);
}
@Test
public void testChain() throws Exception {
RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
Listener listener = new Listener();
server.register(listener);
server.startTask("one");
assertNull(listener.dequeue(1000));
RemoteBatched server2 = server.chain("server2");
assertNull(listener.dequeue(1000));
server2.startTask("two");
assertNull(listener.dequeue(1000));
// Asking for the name will force a flush.
assertEquals("server2", server2.getName());
assertEquals("root", listener.dequeue(1000));
assertEquals("one", listener.dequeue(1000));
assertEquals("server2", listener.dequeue(1000));
assertEquals("two", listener.dequeue(1000));
}
@Test
public void testIsolation() throws Exception {
final RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
Listener listener = new Listener();
server.register(listener);
server.startTask("one");
assertNull(listener.dequeue(1000));
new Thread() {
public void run() {
try {
server.startTask("two");
server.syncNop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}.start();
// Confirms that task one was not flushed.
assertEquals("root", listener.dequeue(1000));
assertEquals("two", listener.dequeue(1000));
assertNull(listener.dequeue(1000));
server.syncNop();
assertEquals("root", listener.dequeue(1000));
assertEquals("one", listener.dequeue(1000));
}
@Test
public void testUnbatched() throws Exception {
final RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
Listener listener = new Listener();
server.register(listener);
server.startTask("one");
assertNull(listener.dequeue(1000));
server.unbatchedTask("two");
// Confirms that task one was not flushed.
assertEquals("root", listener.dequeue(1000));
assertEquals("two", listener.dequeue(1000));
assertNull(listener.dequeue(1000));
server.syncNop();
assertEquals("root", listener.dequeue(1000));
assertEquals("one", listener.dequeue(1000));
}
@Test
public void testCompletion() throws Exception {
final RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
Completion<String>[] completions = new Completion[1000];
for (int i=0; i<completions.length; i++) {
completions[i] = server.echo("hello_" + i);
}
server.syncNop();
for (int i=0; i<completions.length; i++) {
assertEquals("hello_" + i, completions[i].get());
}
}
@Test
public void testManyExceptions() throws Exception {
final RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
server.manyExceptions();
try {
server.syncNop();
fail();
} catch (UndeclaredThrowableException e) {
assert(e.getCause() instanceof InterruptedException);
}
server.manyExceptions();
try {
server.syncNop2();
fail();
} catch (UndeclaredThrowableException e) {
assert(e.getCause() instanceof InterruptedException);
}
server.manyExceptions();
try {
server.syncNop3();
fail();
} catch (InterruptedException e) {
}
}
@Test
public void testStreamReset() throws Exception {
RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
final Object obj = new LinkedBlockingQueue();
for (int i=0; i<3; i++) {
Completion<Boolean> c = server.testStreamReset(obj);
server.syncNop();
assertFalse(c.get());
}
}
@Test
public void testSharedRef() throws Exception {
RemoteBatched server = (RemoteBatched) sessionStrategy.remoteServer;
final Object obj = new LinkedBlockingQueue();
for (int i=0; i<3; i++) {
Completion<Boolean> c = server.testSharedRef(obj, obj);
server.syncNop();
assertTrue(c.get());
}
}
private static class Listener implements RemoteBatched.TaskListener {
private final BlockingQueue<String> mQueue;
Listener() {
mQueue = new LinkedBlockingQueue<String>();
}
public synchronized void started(String name, String op) {
mQueue.add(name);
mQueue.add(op);
}
String dequeue(long timeoutMillis) throws InterruptedException {
return mQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
}
}
}