package org.limewire.io;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Random;
import junit.framework.Test;
import org.limewire.util.BaseTestCase;
/**
* Tests {@link BandwidthThrottle} and {@link ThrottledOutputStream}.
*/
// TODO: test fairness when sharing one throttle among multiple streams
public class BandwidthThrottleTest extends BaseTestCase {
/** Time per test. */
private final int TIME = 1000; // 1 second
/** bytesSent should be the desired value + or - FUDGE_FACTOR */
private static final float FUDGE_FACTOR = 0.12f; // 12 percent
private BandwidthThrottle throttle;
private Random random;
private long startTime;
private long stopTime;
private int bytesSent;
private long expectedBytes;
private PipedOutputStream pout;
private PipedInputStream pin;
private OutputStream out;
public BandwidthThrottleTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(BandwidthThrottleTest.class);
}
@Override
protected void setUp() throws IOException {
// each test sets rate
throttle = new BandwidthThrottle(0);
random = new Random();
bytesSent = 0;
pout = new PipedOutputStream();
pin = new PipedInputStream(pout);
out = new ThrottledOutputStream(pout, throttle);
}
/**
* @param rate bytes / second
*/
public void initExpectedBytes(int rate) {
throttle.setRate(rate);
expectedBytes = TIME / 1000 * rate;
startTime = System.currentTimeMillis();
stopTime = startTime + TIME;
}
public void testBandwidthThrottleSlow() {
initExpectedBytes(100);
while (System.currentTimeMillis() < stopTime) {
int bytesToSend = random.nextInt(12);
bytesSent += throttle.request(bytesToSend);
}
assertLessThan("Sent " + bytesSent + " of " + expectedBytes, FUDGE_FACTOR
* expectedBytes, Math.abs(bytesSent - expectedBytes));
}
public void testThrottledOutputStreamFast() throws Exception {
initExpectedBytes(20 * 1000);
while (System.currentTimeMillis() < stopTime) {
byte b = (byte) random.nextInt();
out.write(b);
assertTrue("Bad byte", (byte) pin.read() == b);
assertEquals("Too many bytes in stream", 0, pin.available());
bytesSent++;
}
assertLessThan("Sent " + bytesSent + " of " + expectedBytes, FUDGE_FACTOR
* expectedBytes, Math.abs(bytesSent - expectedBytes));
}
public void testThrottledOutputStreamWritePartialByteArray() throws Exception {
initExpectedBytes(1000);
byte[] buf = new byte[120];
while (System.currentTimeMillis() < stopTime) {
random.nextBytes(buf);
int n = random.nextInt(buf.length);
out.write(buf, 0, n);
for (int i = 0; i < n; i++)
assertTrue("Bad byte", (byte) pin.read() == buf[i]);
assertEquals("Too many bytes in stream", 0, pin.available());
bytesSent += n;
}
assertLessThan("Sent " + bytesSent + " of " + expectedBytes, FUDGE_FACTOR
* expectedBytes, Math.abs(bytesSent - expectedBytes));
}
public void testThrottledOutputStreamWriteFullByteArray() throws Exception {
initExpectedBytes(1000);
byte[] buf = new byte[120];
while (System.currentTimeMillis() < stopTime) {
random.nextBytes(buf);
out.write(buf);
for (int i = 0; i < buf.length; i++)
assertTrue("Bad byte", (byte) pin.read() == buf[i]);
assertEquals("Too many bytes in stream", 0, pin.available());
bytesSent += buf.length;
}
assertLessThan("Sent " + bytesSent + " of " + expectedBytes, FUDGE_FACTOR
* expectedBytes, Math.abs(bytesSent - expectedBytes));
}
}