package org.limewire.nio.statemachine;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import junit.framework.Test;
import org.limewire.nio.channel.ReadBufferChannel;
import org.limewire.nio.channel.WriteBufferChannel;
import org.limewire.util.BaseTestCase;
import org.limewire.util.StringUtils;
@SuppressWarnings("unchecked")
public class IOStateMachineTest extends BaseTestCase {
public IOStateMachineTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(IOStateMachineTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public void testInterestSetCorrectly() {
ReadBufferChannel readChannel = new ReadBufferChannel();
WriteBufferChannel writeChannel = new WriteBufferChannel();
StubIOStateObserver observer = new StubIOStateObserver();
StubIOState state1 = new StubIOState();
state1.setReading(true);
state1.setReturnTrueOnProcess(true);
StubIOState state2 = new StubIOState();
state2.setWriting(true);
state2.setReturnTrueOnProcess(true);
List states = new LinkedList();
states.add(state1);
states.add(state2);
IOStateMachine shake = new IOStateMachine(observer, states);
assertFalse(readChannel.isInterested());
shake.setReadChannel(readChannel);
assertTrue(readChannel.isInterested());
assertFalse(writeChannel.interested());
shake.setWriteChannel(writeChannel);
assertTrue(writeChannel.interested());
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// First state is reading, so let's see what happens if we set a write hit.
readChannel.interestRead(false);
shake.handleWrite();
assertFalse(readChannel.isInterested());
assertFalse(writeChannel.interested());
assertFalse(state1.isProcessed());
assertFalse(state2.isProcessed());
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// Now try a correct read...
readChannel.interestRead(true);
shake.handleRead();
assertTrue(readChannel.isInterested());
assertFalse(writeChannel.interested());
assertTrue(state1.isProcessed());
assertFalse(state2.isProcessed());
state1.clear();
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// What'll happen when this state finishes...
state1.setReturnTrueOnProcess(false);
shake.handleRead();
assertFalse(readChannel.isInterested());
assertTrue(writeChannel.interested());
assertTrue(state1.isProcessed());
assertFalse(state2.isProcessed());
state1.clear();
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// State is now state2, which is writing.. let's see what happens if we hit a read.
writeChannel.interestWrite(null, false);
shake.handleRead();
assertFalse(readChannel.isInterested());
assertFalse(writeChannel.interested());
assertFalse(state1.isProcessed());
assertFalse(state2.isProcessed());
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// Now let's try a correct write...
writeChannel.interestWrite(null, true);
shake.handleWrite();
assertFalse(readChannel.isInterested());
assertTrue(writeChannel.interested());
assertFalse(state1.isProcessed());
assertTrue(state2.isProcessed());
state2.clear();
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// And if the write is set to not continue?
state2.setReturnTrueOnProcess(false);
shake.handleWrite();
assertFalse(readChannel.isInterested());
assertFalse(writeChannel.interested());
assertFalse(state1.isProcessed());
assertTrue(state2.isProcessed());
state2.clear();
assertTrue(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
}
public void testStateIOX() throws Exception {
ReadBufferChannel readChannel = new ReadBufferChannel();
WriteBufferChannel writeChannel = new WriteBufferChannel();
StubIOStateObserver observer = new StubIOStateObserver();
StubIOState state1 = new StubIOState();
state1.setReading(true);
state1.setReturnTrueOnProcess(true);
List states = new LinkedList();
states.add(state1);
IOStateMachine shake = new IOStateMachine(observer, states);
shake.setReadChannel(readChannel);
shake.setWriteChannel(writeChannel);
state1.setThrowIOX(true);
shake.handleRead();
assertFalse(observer.isStatesFinished());
assertNotNull(observer.getIox());
assertFalse(observer.isShutdown());
observer.clear();
shake.shutdown(); // make sure it doesn't call stuff again
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
}
public void testShutdownShakerWhileOpen() throws Exception {
ReadBufferChannel readChannel = new ReadBufferChannel();
WriteBufferChannel writeChannel = new WriteBufferChannel();
StubIOStateObserver observer = new StubIOStateObserver();
StubIOState state1 = new StubIOState();
state1.setReading(true);
state1.setReturnTrueOnProcess(true);
List states = new LinkedList();
states.add(state1);
IOStateMachine shake = new IOStateMachine(observer, states);
shake.setReadChannel(readChannel);
shake.setWriteChannel(writeChannel);
shake.shutdown();
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// no more processing after this point!
shake.handleRead();
assertFalse(state1.isProcessed());
}
public void testShutdownShakerWhileClosed() throws Exception {
ReadBufferChannel readChannel = new ReadBufferChannel();
WriteBufferChannel writeChannel = new WriteBufferChannel();
StubIOStateObserver observer = new StubIOStateObserver();
StubIOState state1 = new StubIOState();
state1.setReading(true);
state1.setReturnTrueOnProcess(true);
List states = new LinkedList();
states.add(state1);
IOStateMachine shake = new IOStateMachine(observer, states);
shake.setReadChannel(readChannel);
shake.setWriteChannel(writeChannel);
readChannel.setClosed(true);
shake.shutdown();
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertTrue(observer.isShutdown());
observer.clear();
shake.shutdown(); // make sure it doesn't call stuff again
assertFalse(observer.isStatesFinished());
assertNull(observer.getIox());
assertFalse(observer.isShutdown());
// no more processing after this point!
shake.handleRead();
assertFalse(state1.isProcessed());
}
public void testReadBuffer() throws Exception {
ReadBufferChannel readChannel = new ReadBufferChannel();
WriteBufferChannel writeChannel = new WriteBufferChannel();
StubIOStateObserver observer = new StubIOStateObserver();
StubIOState state1 = new StubIOState();
state1.setReading(true);
state1.setReturnTrueOnProcess(true);
List states = new LinkedList();
states.add(state1);
IOStateMachine shake = new IOStateMachine(observer, states);
shake.setReadChannel(readChannel);
shake.setWriteChannel(writeChannel);
state1.setDataToPutInBuffer(StringUtils.toAsciiBytes("DATA"));
shake.handleRead();
ByteBuffer buffer = ByteBuffer.allocate(5);
shake.read(buffer);
assertEquals("DATA\0", StringUtils.getASCIIString(buffer.array()));
assertEquals(4, buffer.position());
}
}