package com.limegroup.gnutella.io; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.*; import java.util.zip.*; import java.net.*; import junit.framework.Test; import com.limegroup.gnutella.util.*; import com.limegroup.gnutella.connection.WriteBufferChannel; /** * Tests that ThrottleWriter throttles data correctly. */ public final class ThrottleWriterTest extends BaseTestCase { private FakeThrottle THROTTLE = new FakeThrottle(); private WriteBufferChannel SINK = new WriteBufferChannel(1024 * 1024); private ThrottleWriter WRITER = new ThrottleWriter(THROTTLE, SINK); private static Random RND = new Random(); private WriteBufferChannel SOURCE = new WriteBufferChannel(WRITER); public ThrottleWriterTest(String name) { super(name); } public static Test suite() { return buildTestSuite(ThrottleWriterTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public void setUp() { THROTTLE.clear(); } public void testInterestAndBandwidthAvailable() throws Exception { assertFalse(SINK.interested()); assertEquals(0, THROTTLE.interests()); WRITER.interest(SOURCE, false); assertFalse(SINK.interested()); assertEquals(0, THROTTLE.interests()); WRITER.interest(SOURCE, true); assertEquals(1, THROTTLE.interests()); assertFalse(SINK.interested()); WRITER.bandwidthAvailable(); assertTrue(SINK.interested()); } public void testeHandleWriteDataLeft() throws Exception { // Test when data is still left after available. // set up writer & SINK. WRITER.bandwidthAvailable(); assertTrue(SINK.interested()); assertEquals(0, SINK.written()); // set up SOURCE & THROTTLE. SOURCE.setBuffer(buffer(data(750))); assertEquals(1, THROTTLE.interests()); THROTTLE.setAvailable(250); assertFalse(THROTTLE.didRequest()); assertFalse(THROTTLE.didRelease()); assertTrue(WRITER.handleWrite()); // still data left to write. assertTrue(THROTTLE.didRequest()); assertTrue(THROTTLE.didRelease()); assertEquals(250, SINK.written()); // only wrote 250 assertEquals(0, THROTTLE.getAvailable()); // all throttle used up. assertEquals(500, SOURCE.remaining()); // data still in source assertEquals(2, THROTTLE.interests()); // is interested in more events. assertFalse(SINK.interested()); // sink should not give events. } public void testHandleWriteSourceEmptiesWithLeftover() throws Exception { SOURCE.setBuffer(buffer(data(500))); assertEquals(1, THROTTLE.interests()); THROTTLE.setAvailable(550); WRITER.bandwidthAvailable(); assertTrue(SINK.interested()); assertFalse(WRITER.handleWrite()); // all data written assertEquals(500, SINK.written()); // only wrote that we had. assertEquals(50, THROTTLE.getAvailable()); // throttle still has data assertEquals(1, THROTTLE.interests()); // didn't request interest again. assertFalse(SINK.interested()); // sink off. } public void testHandleWriteSourceEmptiesExactly() throws Exception { SOURCE.setBuffer(buffer(data(200))); assertEquals(1, THROTTLE.interests()); THROTTLE.setAvailable(200); WRITER.bandwidthAvailable(); assertEquals(0, SINK.written()); assertTrue(SINK.interested()); assertFalse(WRITER.handleWrite()); assertEquals(1, THROTTLE.interests()); assertEquals(200, SINK.written()); assertEquals(0, THROTTLE.getAvailable()); assertEquals(0, SOURCE.remaining()); assertFalse(SINK.interested()); } public void testHandleWriteSinkFills() throws Exception { // test to make sure if sink can't take data that we release & // say we wrote it all, even if we still had stuff to write. SINK.resize(100); SOURCE.setBuffer(buffer(data(250))); THROTTLE.setAvailable(300); WRITER.bandwidthAvailable(); assertEquals(1, THROTTLE.interests()); assertTrue(WRITER.handleWrite()); // data still leftover. assertEquals(100, SINK.written()); assertEquals(150, SOURCE.remaining()); assertEquals(200, THROTTLE.getAvailable()); assertEquals(2, THROTTLE.interests()); assertFalse(SINK.interested()); SINK.resize(150); THROTTLE.clear(); THROTTLE.setAvailable(200); WRITER.bandwidthAvailable(); assertEquals(0, THROTTLE.interests()); assertFalse(WRITER.handleWrite()); assertEquals(150, SINK.written()); assertEquals(50, THROTTLE.getAvailable()); assertEquals(0, THROTTLE.interests()); assertFalse(SINK.interested()); } public void testBandwidthAvailableWhenClosed() throws Exception { assertFalse(SINK.interested()); assertTrue(WRITER.bandwidthAvailable()); assertTrue(SINK.interested()); SINK.interest(null, false); assertFalse(SINK.interested()); SINK.close(); assertFalse(WRITER.bandwidthAvailable()); assertFalse(SINK.interested()); } private byte[] data(int size) { byte[] data = new byte[size]; RND.nextBytes(data); return data; } private ByteBuffer buffer(byte[] data) { return ByteBuffer.wrap(data); } }