2005-09-12 comwiz

* Migrated the router tests to junit
This commit is contained in:
comwiz
2005-09-13 09:06:07 +00:00
committed by zzz
parent 9865af4174
commit 4293a18726
20 changed files with 647 additions and 589 deletions

View File

@ -10,10 +10,10 @@ package net.i2p.data.i2np;
import java.util.Date;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataStructure;
import net.i2p.data.StructureTest;
import net.i2p.data.TestData;
import net.i2p.data.RouterInfo;
import net.i2p.data.RouterInfoTest;
import net.i2p.data.i2np.DatabaseStoreMessage;
@ -24,20 +24,18 @@ import net.i2p.util.Clock;
*
* @author jrandom
*/
class DatabaseStoreMessageTest extends StructureTest {
static {
TestData.registerTest(new DatabaseStoreMessageTest(), "DatabaseStoreMessage");
}
public class DatabaseStoreMessageTest extends StructureTest {
public DataStructure createDataStructure() throws DataFormatException {
DatabaseStoreMessage msg = new DatabaseStoreMessage(_context);
DatabaseStoreMessage msg = new DatabaseStoreMessage(I2PAppContext.getGlobalContext());
RouterInfo info = (RouterInfo)new RouterInfoTest().createDataStructure();
msg.setKey(info.getIdentity().getHash());
msg.setMessageExpiration(Clock.getInstance().now());
msg.setUniqueId(42);
msg.setUniqueId(666);
msg.setRouterInfo(info);
return msg;
}
public DataStructure createStructureToRead() { return new DatabaseStoreMessage(_context); }
public static void main(String args[]) { TestData.main(new String[] { "test", "i2np.DatabaseStoreMessage", "foo.dat" }); }
public DataStructure createStructureToRead() {
return new DatabaseStoreMessage(I2PAppContext.getGlobalContext());
}
}

View File

@ -13,7 +13,6 @@ import net.i2p.data.DataStructure;
import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import net.i2p.data.StructureTest;
import net.i2p.data.TestData;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.util.Log;
@ -23,34 +22,30 @@ import net.i2p.util.Log;
*
* @author jrandom
*/
class DeliveryInstructionsTest extends StructureTest {
private final static Log _log = new Log(DeliveryInstructionsTest.class);
static {
TestData.registerTest(new DeliveryInstructionsTest(), "DeliveryInstructions");
}
public class DeliveryInstructionsTest extends StructureTest {
public DataStructure createDataStructure() throws DataFormatException {
DeliveryInstructions instructions = new DeliveryInstructions();
instructions.setDelayRequested(true);
instructions.setDelaySeconds(42);
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_TUNNEL);
instructions.setEncrypted(true);
SessionKey key = new SessionKey();
byte keyData[] = new byte[SessionKey.KEYSIZE_BYTES];
for (int i = 0; i < keyData.length; i++)
keyData[i] = (byte)i;
key.setData(keyData);
instructions.setEncryptionKey(key);
Hash hash = new Hash();
byte hashData[] = new byte[32];
for (int i = 0; i < hashData.length; i++)
hashData[i] = (byte)(i%32);
hash.setData(hashData);
instructions.setRouter(hash);
TunnelId id = new TunnelId();
id.setTunnelId(666);
instructions.setTunnelId(id);
_log.debug("Instructions created: " + instructions + "\nBase 64: " + instructions.toBase64());
return instructions;
instructions.setDelayRequested(true);
instructions.setDelaySeconds(42);
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_TUNNEL);
instructions.setEncrypted(true);
SessionKey key = new SessionKey();
byte keyData[] = new byte[SessionKey.KEYSIZE_BYTES];
for (int i = 0; i < keyData.length; i++)
keyData[i] = (byte)i;
key.setData(keyData);
instructions.setEncryptionKey(key);
Hash hash = new Hash();
byte hashData[] = new byte[32];
for (int i = 0; i < hashData.length; i++)
hashData[i] = (byte)(i%32);
hash.setData(hashData);
instructions.setRouter(hash);
TunnelId id = new TunnelId();
id.setTunnelId(666);
instructions.setTunnelId(id);
return instructions;
}
public DataStructure createStructureToRead() { return new DeliveryInstructions(); }
}

View File

@ -17,64 +17,46 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.i2np.I2NPMessageReader;
import net.i2p.util.Log;
import net.i2p.router.RouterContext;
import junit.framework.TestCase;
/**
* Test harness for loading / storing I2NP DatabaseStore message objects
*
* @author jrandom
*/
class I2NPMessageReaderTest implements I2NPMessageReader.I2NPMessageEventListener {
private final static Log _log = new Log(I2NPMessageReaderTest.class);
private static RouterContext _context = new RouterContext(null);
public class I2NPMessageReaderTest extends TestCase implements I2NPMessageReader.I2NPMessageEventListener{
public static void main(String args[]) {
I2NPMessageReaderTest test = new I2NPMessageReaderTest();
test.runTest();
try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
}
public void setUp(){}
public void runTest() {
public void testI2NPMessageReader() throws IOException, DataFormatException{
InputStream data = getData();
test(data);
}
private InputStream getData() {
private InputStream getData() throws IOException, DataFormatException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
DatabaseStoreMessage msg = (DatabaseStoreMessage)new DatabaseStoreMessageTest().createDataStructure();
msg.writeBytes(baos);
msg.writeBytes(baos);
msg.writeBytes(baos);
_log.debug("DB Store message in tunnel contains: " + msg);
msg.writeBytes(baos);
} catch (DataFormatException dfe) {
_log.error("Error building data", dfe);
} catch (IOException ioe) {
_log.error("Error writing stream", ioe);
}
DatabaseStoreMessage msg = (DatabaseStoreMessage)new DatabaseStoreMessageTest().createDataStructure();
msg.writeBytes(baos);
msg.writeBytes(baos);
msg.writeBytes(baos);
msg.writeBytes(baos);
return new ByteArrayInputStream(baos.toByteArray());
}
private void test(InputStream in) {
_log.debug("Testing the input stream");
I2NPMessageReader reader = new I2NPMessageReader(_context, in, this);
_log.debug("Created, beginning reading");
I2NPMessageReader reader = new I2NPMessageReader(new RouterContext(null), in, this);
reader.startReading();
_log.debug("Reading commenced");
}
public void disconnected(I2NPMessageReader reader) {
_log.debug("Disconnected");
}
public void messageReceived(I2NPMessageReader reader, I2NPMessage message, long msToRead, int size) {
_log.debug("Message received: " + message);
}
public void readError(I2NPMessageReader reader, Exception error) {
_log.debug("Read error: " + error.getMessage(), error);
}
}

View File

@ -0,0 +1,79 @@
package net.i2p.router.networkdb.kademlia;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.RandomSource;
import junit.framework.TestCase;
/**
* Test KBucketImpl
*
* @author comwiz
*/
public class KBucketImplTest extends TestCase{
private I2PAppContext context;
public void setUp(){
context = I2PAppContext.getGlobalContext();
}
public void testLimits() {
int low = 0;
int high = 4;
KBucketImpl bucket = new KBucketImpl(I2PAppContext.getGlobalContext(), Hash.FAKE_HASH);
bucket.setRange(low, high);
Hash lowerBoundKey = bucket.getRangeBeginKey();
Hash upperBoundKey = bucket.getRangeEndKey();
assertTrue(bucket.shouldContain(lowerBoundKey));//
assertTrue(bucket.shouldContain(upperBoundKey));
}
public void testRand() {
int low = 1;
int high = 2000;
Hash local = Hash.FAKE_HASH;
local.prepareCache();
KBucketImpl bucket = new KBucketImpl(I2PAppContext.getGlobalContext(), local);
bucket.setRange(low, high);
Hash lowerBoundKey = bucket.getRangeBeginKey();
Hash upperBoundKey = bucket.getRangeEndKey();
for (int i = 0; i < 1000; i++) {
Hash rnd = bucket.generateRandomKey();
assertTrue(bucket.shouldContain(rnd));//
}
}
public void testRand2() {
int low = 1;
int high = 2000;
byte hash[] = new byte[Hash.HASH_LENGTH];
RandomSource.getInstance().nextBytes(hash);
Hash local = new Hash(hash);
local.prepareCache();
KBucketImpl bucket = new KBucketImpl(I2PAppContext.getGlobalContext(), local);
bucket.setRange(low, high);
Hash lowerBoundKey = bucket.getRangeBeginKey();
Hash upperBoundKey = bucket.getRangeEndKey();
for (int i = 0; i < 1000; i++) {
Hash rnd = bucket.generateRandomKey();
assertTrue(bucket.shouldContain(rnd));
}
}
}

View File

@ -0,0 +1,43 @@
package net.i2p.router.networkdb.kademlia;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import junit.framework.TestCase;
/**
* Test KBucketSet
*
* @author comwiz
*/
public class KBucketSetTest extends TestCase{
private I2PAppContext context;
private KBucketSet set;
public void setUp(){
context = I2PAppContext.getGlobalContext();
set = new KBucketSet(context, Hash.FAKE_HASH);
}
public void testRandom(){
for (int i = 0; i < 1000; i++) {
byte val[] = new byte[Hash.HASH_LENGTH];
context.random().nextBytes(val);
assertTrue(set.add(new Hash(val)));
}
}
public void testSelf() {
assertTrue(set.add(Hash.FAKE_HASH));
}
}

View File

@ -1,13 +1,25 @@
package net.i2p.router.transport;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import java.util.Properties;
import junit.framework.TestCase;
/**
* Stress out the bandwidth limiter by running a series of push and pull tests
* through bandwidth limited streams. This includes pushing data through
@ -19,19 +31,19 @@ import java.util.Properties;
* 10 concurrent threads is, well, slow.
*
*/
public class BandwidthLimiterTest {
public class BandwidthLimiterTest extends TestCase{
private RouterContext _context;
private Log _log;
private final static int NUM_MB = 1;
private final static int NUM_KB = 256;
public BandwidthLimiterTest() {
public void setUp() {
_context = new RouterContext(null);
_log = _context.logManager().getLog(BandwidthLimiterTest.class);
//_context.jobQueue().runQueue(1);
}
public void prepareLimiter(int inKBps, int outKBps, int inBurst, int outBurst) {
Properties props = new Properties();
public void tearDown(){
}
private void prepareLimiter(int inKBps, int outKBps, int inBurst, int outBurst) {
Properties props = System.getProperties();
props.setProperty(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH, ""+inKBps);
props.setProperty(FIFOBandwidthRefiller.PROP_OUTBOUND_BANDWIDTH, ""+outKBps);
props.setProperty(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH_PEAK, ""+inBurst);
@ -39,7 +51,6 @@ public class BandwidthLimiterTest {
//props.setProperty(TrivialBandwidthLimiter.PROP_REPLENISH_FREQUENCY, ""+10*1000);
System.setProperties(props);
_context.bandwidthLimiter().reinitialize();
_log.debug("Limiter prepared");
}
/**
@ -48,7 +59,7 @@ public class BandwidthLimiterTest {
* chunks.
*
*/
public long testOutboundThrottle(int numBytes, int numBytesPerWrite) {
private long testOutboundThrottle(int numBytes, int numBytesPerWrite) {
byte source[] = new byte[numBytesPerWrite];
new Random().nextBytes(source);
NullOutputStream target = new NullOutputStream();
@ -73,7 +84,7 @@ public class BandwidthLimiterTest {
* chunks.
*
*/
public long testInboundThrottle(int numBytes, int numBytesPerRead) {
private long testInboundThrottle(int numBytes, int numBytesPerRead) {
FakeInputStream source = new FakeInputStream(numBytes);
BandwidthLimitedInputStream in = new BandwidthLimitedInputStream(_context, source, null);
long before = System.currentTimeMillis();
@ -95,20 +106,33 @@ public class BandwidthLimiterTest {
*
*/
public void testOutbound() {
double error;
double predict;
prepareLimiter(-1, -1, -1, -1);
_log.info("Begin unlimited push of " + NUM_MB);
long ms = testOutboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** Unlimited pushed " + NUM_MB + "MB in " + ms + "ms");
prepareLimiter(-1, 4, -1, 4*1024);
ms = testOutboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 4KBps pushed " + NUM_MB + "MB in " + ms + "ms");
long ms = testOutboundThrottle(NUM_KB*1024, 1*1024);
/*prepareLimiter(-1, 4, -1, 4*1024);
ms = testOutboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/4)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);*/
prepareLimiter(-1, 32, -1, 32*1024);
ms = testOutboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 32KBps pushed " + NUM_MB + "MB in " + ms + "ms");
ms = testOutboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/32)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);
prepareLimiter(-1, 256, -1, 256*1024);
_log.info("Begin 256KBps push of " + NUM_MB);
ms = testOutboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 256KBps pushed " + NUM_MB + "MB in " + ms + "ms");
ms = testOutboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/256)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);
}
/**
@ -117,52 +141,68 @@ public class BandwidthLimiterTest {
*
*/
public void testInbound() {
double predict;
double error;
prepareLimiter(-1, -1, -1, -1);
long ms = testInboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** Unlimited pulled " + NUM_MB + "MB in " + ms + "ms");
prepareLimiter(4, -1, 4*1024, -1);
ms = testInboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 4KBps pulled " + NUM_MB + "MB in " + ms + "ms");
long ms = testInboundThrottle(NUM_KB*1024, 1*1024);
/*prepareLimiter(4, -1, 4*1024, -1);
ms = testInboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/4)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);*/
prepareLimiter(32, -1, 32*1024, -1);
ms = testInboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 32KBps pulled " + NUM_MB + "MB in " + ms + "ms");
ms = testInboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/32)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);
prepareLimiter(256, -1, 256*1024, -1);
ms = testInboundThrottle(NUM_MB*1024*1024, 1*1024);
_log.info("** 256KBps pulled " + NUM_MB + "MB in " + ms + "ms");
ms = testInboundThrottle(NUM_KB*1024, 1*1024);
predict = (NUM_KB/256)*1000;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);
}
public void testOutboundContention() {
double predict;
double error;
long ms;
long end;
long start;
prepareLimiter(-1, -1, -1, -1);
long start = System.currentTimeMillis();
long runningTimes[] = testOutboundContention(10, NUM_MB*1024*1024);
long end = System.currentTimeMillis();
_log.info("** Done with unlimited " + NUM_MB + "MB test with 10 concurrent threads after " + (end-start) + "ms: " + displayTimes(runningTimes));
start = System.currentTimeMillis();
//long runningTimes[] = testOutboundContention(10, NUM_KB*1024);
end = System.currentTimeMillis();
//prepareLimiter(-1, 4, -1, 5*1024*1024);
//start = System.currentTimeMillis();
//runningTimes = testOutboundContention(10, NUM_MB*1024*1024);
//runningTimes = testOutboundContention(10, NUM_KB*1024);
//end = System.currentTimeMillis();
//_log.info("** Done with 4KBps " + NUM_MB + "MB test with 10 concurrent threads after " + (end-start) + "ms: " + displayTimes(runningTimes));
prepareLimiter(-1, 32, -1, 32*1024);
start = System.currentTimeMillis();
runningTimes = testOutboundContention(10, NUM_MB*1024*1024);
end = System.currentTimeMillis();
_log.info("** Done with 32KBps " + NUM_MB + "MB test with 10 concurrent threads after " + (end-start) + "ms: " + displayTimes(runningTimes));
//prepareLimiter(-1, 32, -1, 32*1024);
//start = System.currentTimeMillis();
//runningTimes = testOutboundContention(10, NUM_KB*1024);
//end = System.currentTimeMillis();
prepareLimiter(-1, 256, -1, 256*1024);
start = System.currentTimeMillis();
runningTimes = testOutboundContention(10, NUM_MB*1024*1024);
testOutboundContention(10, NUM_KB*1024);
end = System.currentTimeMillis();
_log.info("** Done with 256KBps " + NUM_MB + "MB test with 10 concurrent threads after " + (end-start) + "ms: " + displayTimes(runningTimes));
}
private String displayTimes(long times[]) {
StringBuffer rv = new StringBuffer();
for (int i = 0; i < times.length; i++) {
rv.append(times[i]);
if (i + 1 <= times.length)
rv.append(' ');
}
return rv.toString();
ms = end-start;
predict = (NUM_KB/256)*1000*10;
error = predict/ms;
//assertTrue(error>.89);
assertTrue(error<1.05);
}
private long[] testOutboundContention(int numConcurrent, int numBytes) {
@ -170,7 +210,7 @@ public class BandwidthLimiterTest {
for (int i = 0; i < numConcurrent; i++) {
threads[i] = new OutboundRunner(numBytes);
}
_log.debug("Starting up outbound contention test for " + numBytes + " with " + numConcurrent + " runners");
for (int i = 0; i < numConcurrent; i++)
threads[i].start();
for (int i = 0; i < numConcurrent; i++) {
@ -196,17 +236,30 @@ public class BandwidthLimiterTest {
public void run() {
Thread.currentThread().setName("Out" + _runnerNum);
_runningTime = testOutboundThrottle(_numBytes, 8*1024);
_log.debug("Outbound runner " + _runnerNum + " pushed " + _numBytes + " in " + _runningTime + "ms");
}
public long getRunningTime() { return _runningTime; }
}
}
class NullOutputStream extends OutputStream {
public void write(int param) {}
}
class FakeInputStream extends InputStream {
private volatile int _numRead;
private int _size;
public static void main(String args[]) {
BandwidthLimiterTest test = new BandwidthLimiterTest();
test.testOutbound();
test.testInbound();
//test.testOutboundContention();
System.exit(0);
public FakeInputStream(int size) {
_size = size;
_numRead = 0;
}
public int read() {
int rv = 0;
if (_numRead >= _size)
rv = -1;
else
rv = 42;
_numRead++;
return rv;
}
}

View File

@ -1,27 +0,0 @@
package net.i2p.router.transport;
import java.io.InputStream;
/**
* Read up to a specified number of bytes, then EOF.
* Uses pretty much no memory.
*
*/
public class FakeInputStream extends InputStream {
private volatile int _numRead;
private int _size;
public FakeInputStream(int size) {
_size = size;
_numRead = 0;
}
public int read() {
int rv = 0;
if (_numRead >= _size)
rv = -1;
else
rv = 42;
_numRead++;
return rv;
}
}

View File

@ -1,11 +0,0 @@
package net.i2p.router.transport;
import java.io.OutputStream;
/**
* Output stream for when we don't care whats written
*
*/
public class NullOutputStream extends OutputStream {
public void write(int param) {}
}

View File

@ -0,0 +1,158 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.util.ArrayList;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DataMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.util.Log;
/**
* Test the batching behavior of the preprocessor with one, two, or three
* messages of various sizes and settings.
*
*/
public class BatchedFragmentTest extends FragmentTest {
public void setUp() {
super.setUp();
BatchedPreprocessor.DEFAULT_DELAY = 200;
}
protected TunnelGateway.QueuePreprocessor createPreprocessor(I2PAppContext ctx) {
return new BatchedPreprocessor(ctx);
}
/**
* Send a small message, wait a second, then send a large message, pushing
* the first one through immediately, with the rest of the large one passed
* after a brief delay.
*
*/
public void testBatched() {
TunnelGateway.Pending pending1 = createPending(10, false, false);
ArrayList messages = new ArrayList();
messages.add(pending1);
TunnelGateway.Pending pending2 = createPending(1024, false, false);
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
DefragmentedReceiverImpl handleReceiver = new DefragmentedReceiverImpl(pending1.getData(), pending2.getData());
FragmentHandler handler = new FragmentHandler(_context, handleReceiver);
ReceiverImpl receiver = new ReceiverImpl(handler, 0);
byte msg[] = pending1.getData();
boolean keepGoing = true;
boolean alreadyAdded = false;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if (keepGoing) {
try { Thread.sleep(150); } catch (InterruptedException ie) {}
if (!alreadyAdded) {
messages.add(pending2);
alreadyAdded = true;
}
}
}
assertTrue(handleReceiver.receivedOk());
}
/**
* Send a small message, wait a second, then send a large message, pushing
* the first one through immediately, with the rest of the large one passed
* after a brief delay.
*
*/
public void runBatches() {
//success += testBatched(1, false, false, 1024, false, false);
// this takes a long fucking time
for (int i = 1; i <= 1024; i++) {
testBatched(i, false, false, 1024, false, false, 1024, false, false);
testBatched(i, true, false, 1024, false, false, 1024, false, false);
testBatched(i, true, true, 1024, false, false, 1024, false, false);
testBatched(i, false, false, 1024, true, false, 1024, false, false);
testBatched(i, true, false, 1024, true, false, 1024, false, false);
testBatched(i, true, true, 1024, true, false, 1024, false, false);
testBatched(i, false, false, 1024, true, true, 1024, false, false);
testBatched(i, true, false, 1024, true, true, 1024, false, false);
testBatched(i, true, true, 1024, true, true, 1024, false, false);
testBatched(i, false, false, 1024, false, false, 1024, true, false);
testBatched(i, true, false, 1024, false, false, 1024, true, false);
testBatched(i, true, true, 1024, false, false, 1024, true, false);
testBatched(i, false, false, 1024, true, false, 1024, true, false);
testBatched(i, true, false, 1024, true, false, 1024, true, false);
testBatched(i, true, true, 1024, true, false, 1024, true, false);
testBatched(i, false, false, 1024, true, true, 1024, true, false);
testBatched(i, true, false, 1024, true, true, 1024, true, false);
testBatched(i, true, true, 1024, true, true, 1024, true, false);
testBatched(i, false, false, 1024, false, false, 1024, true, true);
testBatched(i, true, false, 1024, false, false, 1024, true, true);
testBatched(i, true, true, 1024, false, false, 1024, true, true);
testBatched(i, false, false, 1024, true, false, 1024, true, true);
testBatched(i, true, false, 1024, true, false, 1024, true, true);
testBatched(i, true, true, 1024, true, false, 1024, true, true);
testBatched(i, false, false, 1024, true, true, 1024, true, true);
testBatched(i, true, false, 1024, true, true, 1024, true, true);
testBatched(i, true, true, 1024, true, true, 1024, true, true);
}
}
private void testBatched(int firstSize, boolean firstRouter, boolean firstTunnel,
int secondSize, boolean secondRouter, boolean secondTunnel,
int thirdSize, boolean thirdRouter, boolean thirdTunnel) {
TunnelGateway.Pending pending1 = createPending(firstSize, firstRouter, firstTunnel);
TunnelGateway.Pending pending2 = createPending(secondSize, secondRouter, secondTunnel);
TunnelGateway.Pending pending3 = createPending(thirdSize, thirdRouter, thirdTunnel);
runBatch(pending1, pending2, pending3);
}
private void runBatch(TunnelGateway.Pending pending1, TunnelGateway.Pending pending2, TunnelGateway.Pending pending3) {
ArrayList messages = new ArrayList();
messages.add(pending1);
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
DefragmentedReceiverImpl handleReceiver = new DefragmentedReceiverImpl(pending1.getData(), pending2.getData(), pending3.getData());
FragmentHandler handler = new FragmentHandler(_context, handleReceiver);
ReceiverImpl receiver = new ReceiverImpl(handler, 0);
byte msg[] = pending1.getData();
boolean keepGoing = true;
int added = 0;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if ( (keepGoing) || ((messages.size() == 0) && (added < 2) ) ) {
try { Thread.sleep(150); } catch (InterruptedException ie) {}
if (added == 0) {
messages.add(pending2);
added++;
keepGoing = true;
} else if (added == 1) {
messages.add(pending3);
added++;
keepGoing = true;
}
}
}
assertTrue(handleReceiver.receivedOk());
}
}

View File

@ -0,0 +1,223 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.util.ArrayList;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DataMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.util.Log;
import junit.framework.TestCase;
/**
* Simple test to see if the fragmentation is working, testing the preprocessor,
* FragmentHandler, and FragmentedMessage operation.
*
*/
public class FragmentTest extends TestCase{
protected I2PAppContext _context;
public void setUp() {
_context = I2PAppContext.getGlobalContext();
_context.random().nextBoolean();
FragmentHandler.MAX_DEFRAGMENT_TIME = 10*1000;
}
protected TunnelGateway.QueuePreprocessor createPreprocessor(I2PAppContext ctx) {
return new TrivialPreprocessor(ctx);
}
/**
* Send a message that fits inside a single fragment through
*
*/
public void testSingle() {
TunnelGateway.Pending pending = createPending(949, false, false);
ArrayList messages = new ArrayList();
messages.add(pending);
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
DefragmentedReceiverImpl handleReceiver = new DefragmentedReceiverImpl(pending.getData());
FragmentHandler handler = new FragmentHandler(_context, handleReceiver);
ReceiverImpl receiver = new ReceiverImpl(handler, 0);
byte msg[] = pending.getData();
boolean keepGoing = true;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if (keepGoing)
try { Thread.sleep(100); } catch (InterruptedException ie) {}
}
assertTrue(handleReceiver.receivedOk());
}
/**
* Send a message with two fragments through with no delay
*
*/
public void testMultiple() {
TunnelGateway.Pending pending = createPending(2048, false, false);
ArrayList messages = new ArrayList();
messages.add(pending);
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
DefragmentedReceiverImpl handleReceiver = new DefragmentedReceiverImpl(pending.getData());
FragmentHandler handler = new FragmentHandler(_context, handleReceiver);
ReceiverImpl receiver = new ReceiverImpl(handler, 0);
byte msg[] = pending.getData();
boolean keepGoing = true;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if (keepGoing)
try { Thread.sleep(100); } catch (InterruptedException ie) {}
}
assertTrue(handleReceiver.receivedOk());
}
/**
* Send a fragmented message, except wait a while between each fragment, causing
* the defragmentation to fail (since the fragments will expire)
*
*/
public void runDelayed() {
TunnelGateway.Pending pending = createPending(2048, false, false);
ArrayList messages = new ArrayList();
messages.add(pending);
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
FragmentHandler handler = new FragmentHandler(_context, new DefragmentedReceiverImpl(pending.getData()));
ReceiverImpl receiver = new ReceiverImpl(handler, 11*1000);
byte msg[] = pending.getData();
boolean keepGoing = true;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if (keepGoing)
try { Thread.sleep(100); } catch (InterruptedException ie) {}
}
}
public void runVaried() {
for (int i = 0; i <= 4096; i++) {
assertTrue(runVaried(i, false, false));
assertTrue(runVaried(i, true, false));
assertTrue(runVaried(i, true, true));
}
}
protected boolean runVaried(int size, boolean includeRouter, boolean includeTunnel) {
TunnelGateway.Pending pending = createPending(size, includeRouter, includeTunnel);
ArrayList messages = new ArrayList();
messages.add(pending);
DefragmentedReceiverImpl handleReceiver = new DefragmentedReceiverImpl(pending.getData());
TunnelGateway.QueuePreprocessor pre = createPreprocessor(_context);
SenderImpl sender = new SenderImpl();
FragmentHandler handler = new FragmentHandler(_context, handleReceiver);
ReceiverImpl receiver = new ReceiverImpl(handler, 0);
byte msg[] = pending.getData();
boolean keepGoing = true;
while (keepGoing) {
keepGoing = pre.preprocessQueue(messages, new SenderImpl(), receiver);
if (keepGoing)
try { Thread.sleep(100); } catch (InterruptedException ie) {}
}
return handleReceiver.receivedOk();
}
protected TunnelGateway.Pending createPending(int size, boolean includeRouter, boolean includeTunnel) {
DataMessage m = new DataMessage(_context);
byte data[] = new byte[size];
_context.random().nextBytes(data);
m.setData(data);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
m.setMessageExpiration(_context.clock().now() + 60*1000);
Hash toRouter = null;
TunnelId toTunnel = null;
if (includeRouter) {
toRouter = new Hash(new byte[Hash.HASH_LENGTH]);
_context.random().nextBytes(toRouter.getData());
}
if (includeTunnel)
toTunnel = new TunnelId(_context.random().nextLong(TunnelId.MAX_ID_VALUE));
return new TunnelGateway.Pending(m, toRouter, toTunnel);
}
protected class SenderImpl implements TunnelGateway.Sender {
public void sendPreprocessed(byte[] preprocessed, TunnelGateway.Receiver receiver) {
receiver.receiveEncrypted(preprocessed);
}
}
protected class ReceiverImpl implements TunnelGateway.Receiver {
private FragmentHandler _handler;
private int _delay;
public ReceiverImpl(FragmentHandler handler, int delay) {
_handler = handler;
_delay = delay;
}
public void receiveEncrypted(byte[] encrypted) {
_handler.receiveTunnelMessage(encrypted, 0, encrypted.length);
try { Thread.sleep(_delay); } catch (Exception e) {}
}
}
protected class DefragmentedReceiverImpl implements FragmentHandler.DefragmentedReceiver {
private byte _expected[];
private byte _expected2[];
private byte _expected3[];
private int _received;
public DefragmentedReceiverImpl(byte expected[]) {
this(expected, null);
}
public DefragmentedReceiverImpl(byte expected[], byte expected2[]) {
this(expected, expected2, null);
}
public DefragmentedReceiverImpl(byte expected[], byte expected2[], byte expected3[]) {
_expected = expected;
_expected2 = expected2;
_expected3 = expected3;
_received = 0;
}
public void receiveComplete(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
boolean ok = false;
byte m[] = msg.toByteArray();
if ( (_expected != null) && (DataHelper.eq(_expected, m)) )
ok = true;
if (!ok && (_expected2 != null) && (DataHelper.eq(_expected2, m)) )
ok = true;
if (!ok && (_expected3 != null) && (DataHelper.eq(_expected3, m)) )
ok = true;
if (ok)
_received++;
//_log.info("** equal? " + ok);
}
public boolean receivedOk() {
if ( (_expected != null) && (_expected2 != null) && (_expected3 != null) )
return _received == 3;
else if ( (_expected != null) && (_expected2 != null) )
return _received == 2;
else if ( (_expected != null) || (_expected2 != null) )
return _received == 1;
else
return _received == 0;
}
}
}

View File

@ -0,0 +1,218 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DataMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.util.Log;
import junit.framework.TestCase;
/**
* Quick unit test for base functionality of inbound tunnel
* operation
*/
public class InboundGatewayTest extends TestCase{
private I2PAppContext _context;
private Log _log;
private TunnelCreatorConfig _config;
private TunnelGateway.QueuePreprocessor _preprocessor;
private TunnelGateway.Sender _sender;
private TestReceiver _receiver;
private TunnelGateway _gw;
public void setUp() {
_context = I2PAppContext.getGlobalContext();
_config = prepareConfig(8);
_preprocessor = new TrivialPreprocessor(_context);
_sender = new InboundSender(_context, _config.getConfig(0));
_receiver = new TestReceiver(_config);
_gw = new TunnelGateway(_context, _preprocessor, _sender, _receiver);
}
public void testSmall() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, null, null);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testRouter() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
Hash to = new Hash(new byte[Hash.HASH_LENGTH]);
java.util.Arrays.fill(to.getData(), (byte)0xFF);
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, to, null);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testTunnel() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
Hash to = new Hash(new byte[Hash.HASH_LENGTH]);
java.util.Arrays.fill(to.getData(), (byte)0xFF);
TunnelId tunnel = new TunnelId(42);
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, to, tunnel);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testLarge() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[1024]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, null, null);
}
long time = _context.clock().now() - start;
//try { Thread.sleep(60*1000); } catch (Exception e) {}
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
private class TestReceiver implements TunnelGateway.Receiver, FragmentHandler.DefragmentedReceiver {
private TunnelCreatorConfig _config;
private FragmentHandler _handler;
private List _received;
public TestReceiver(TunnelCreatorConfig config) {
_config = config;
_handler = new FragmentHandler(_context, TestReceiver.this);
_received = new ArrayList(1000);
}
public void receiveEncrypted(byte[] encrypted) {
// fake all the hops...
for (int i = 1; i <= _config.getLength() - 2; i++) {
HopProcessor hop = new HopProcessor(_context, _config.getConfig(i));
assertTrue(hop.process(encrypted, 0, encrypted.length, _config.getConfig(i).getReceiveFrom()));
}
// now handle it at the endpoint
InboundEndpointProcessor end = new InboundEndpointProcessor(_context, _config);
assertTrue(end.retrievePreprocessedData(encrypted, 0, encrypted.length, _config.getPeer(_config.getLength()-2)));
_handler.receiveTunnelMessage(encrypted, 0, encrypted.length);
}
public void receiveComplete(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
_received.add(msg);
}
public List clearReceived() {
List rv = _received;
_received = new ArrayList();
return rv;
}
}
private TunnelCreatorConfig prepareConfig(int numHops) {
Hash peers[] = new Hash[numHops];
byte tunnelIds[][] = new byte[numHops][4];
for (int i = 0; i < numHops; i++) {
peers[i] = new Hash();
peers[i].setData(new byte[Hash.HASH_LENGTH]);
_context.random().nextBytes(peers[i].getData());
_context.random().nextBytes(tunnelIds[i]);
}
TunnelCreatorConfig config = new TunnelCreatorConfig(numHops, false);
for (int i = 0; i < numHops; i++) {
config.setPeer(i, peers[i]);
HopConfig cfg = config.getConfig(i);
cfg.setExpiration(_context.clock().now() + 60000);
cfg.setIVKey(_context.keyGenerator().generateSessionKey());
cfg.setLayerKey(_context.keyGenerator().generateSessionKey());
if (i > 0)
cfg.setReceiveFrom(peers[i-1]);
else
cfg.setReceiveFrom(null);
cfg.setReceiveTunnelId(tunnelIds[i]);
if (i < numHops - 1) {
cfg.setSendTo(peers[i+1]);
cfg.setSendTunnelId(tunnelIds[i+1]);
} else {
cfg.setSendTo(null);
cfg.setSendTunnelId(null);
}
}
return config;
}
}

View File

@ -0,0 +1,87 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.Log;
import junit.framework.TestCase;
/**
* Quick unit test for base functionality of inbound tunnel
* operation
*
*/
public class InboundTest extends TestCase{
private I2PAppContext _context;
public void setUp() {
_context = I2PAppContext.getGlobalContext();
}
public void testInbound() {
int numHops = 8;
TunnelCreatorConfig config = prepareConfig(numHops);
byte orig[] = new byte[128];
byte message[] = new byte[128];
_context.random().nextBytes(orig); // might as well fill the IV
System.arraycopy(orig, 0, message, 0, message.length);
InboundGatewayProcessor p = new InboundGatewayProcessor(_context, config.getConfig(0));
p.process(message, 0, message.length, null);
for (int i = 1; i < numHops-1; i++) {
HopProcessor hop = new HopProcessor(_context, config.getConfig(i));
Hash prev = config.getConfig(i).getReceiveFrom();
assertTrue(hop.process(message, 0, message.length, prev));
}
InboundEndpointProcessor end = new InboundEndpointProcessor(_context, config);
assertTrue(end.retrievePreprocessedData(message, 0, message.length, config.getPeer(numHops-2)));
assertTrue(DataHelper.eq(orig, 16, message, 16, orig.length - 16));
}
private TunnelCreatorConfig prepareConfig(int numHops) {
Hash peers[] = new Hash[numHops];
byte tunnelIds[][] = new byte[numHops][4];
for (int i = 0; i < numHops; i++) {
peers[i] = new Hash();
peers[i].setData(new byte[Hash.HASH_LENGTH]);
_context.random().nextBytes(peers[i].getData());
_context.random().nextBytes(tunnelIds[i]);
}
TunnelCreatorConfig config = new TunnelCreatorConfig(numHops, false);
for (int i = 0; i < numHops; i++) {
config.setPeer(i, peers[i]);
HopConfig cfg = config.getConfig(i);
cfg.setExpiration(_context.clock().now() + 60000);
cfg.setIVKey(_context.keyGenerator().generateSessionKey());
cfg.setLayerKey(_context.keyGenerator().generateSessionKey());
if (i > 0)
cfg.setReceiveFrom(peers[i-1]);
else
cfg.setReceiveFrom(null);
cfg.setReceiveTunnelId(tunnelIds[i]);
if (i < numHops - 1) {
cfg.setSendTo(peers[i+1]);
cfg.setSendTunnelId(tunnelIds[i+1]);
} else {
cfg.setSendTo(null);
cfg.setSendTunnelId(null);
}
}
return config;
}
}

View File

@ -0,0 +1,214 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DataMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.util.Log;
import junit.framework.TestCase;
/**
* Quick unit test for base functionality of outbound tunnel
* operation
*/
public class OutboundGatewayTest extends TestCase{
private I2PAppContext _context;
private TunnelCreatorConfig _config;
private TunnelGateway.QueuePreprocessor _preprocessor;
private TunnelGateway.Sender _sender;
private TestReceiver _receiver;
private TunnelGateway _gw;
public void setUp() {
_context = I2PAppContext.getGlobalContext();
_config = prepareConfig(8);
_preprocessor = new TrivialPreprocessor(_context);
_sender = new OutboundSender(_context, _config);
_receiver = new TestReceiver(_config);
_gw = new TunnelGateway(_context, _preprocessor, _sender, _receiver);
}
public void testSmall() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, null, null);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testRouter() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
Hash to = new Hash(new byte[Hash.HASH_LENGTH]);
java.util.Arrays.fill(to.getData(), (byte)0xFF);
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, to, null);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testTunnel() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[64]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
Hash to = new Hash(new byte[Hash.HASH_LENGTH]);
java.util.Arrays.fill(to.getData(), (byte)0xFF);
TunnelId tunnel = new TunnelId(42);
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, to, tunnel);
}
long time = _context.clock().now() - start;
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
public void testLarge() {
int runCount = 1;
List messages = new ArrayList(runCount);
long start = _context.clock().now();
for (int i = 0; i < runCount; i++) {
DataMessage m = new DataMessage(_context);
m.setData(new byte[1024]);
java.util.Arrays.fill(m.getData(), (byte)0xFF);
m.setMessageExpiration(_context.clock().now() + 60*1000);
m.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
byte data[] = m.toByteArray();
messages.add(m);
_gw.add(m, null, null);
}
long time = _context.clock().now() - start;
//try { Thread.sleep(60*1000); } catch (Exception e) {}
List received = _receiver.clearReceived();
for (int i = 0; i < messages.size(); i++) {
assertTrue(received.contains(((I2NPMessage)messages.get(i))));
}
}
private class TestReceiver implements TunnelGateway.Receiver, FragmentHandler.DefragmentedReceiver {
private TunnelCreatorConfig _config;
private FragmentHandler _handler;
private List _received;
public TestReceiver(TunnelCreatorConfig config) {
_config = config;
_handler = new FragmentHandler(_context, TestReceiver.this);
_received = new ArrayList(1000);
}
public void receiveEncrypted(byte[] encrypted) {
// fake all the hops...
for (int i = 1; i < _config.getLength(); i++) {
HopProcessor hop = new HopProcessor(_context, _config.getConfig(i));
assertTrue(hop.process(encrypted, 0, encrypted.length, _config.getConfig(i).getReceiveFrom()));
}
_handler.receiveTunnelMessage(encrypted, 0, encrypted.length);
}
public void receiveComplete(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
_received.add(msg);
}
public List clearReceived() {
List rv = _received;
_received = new ArrayList();
return rv;
}
}
private TunnelCreatorConfig prepareConfig(int numHops) {
Hash peers[] = new Hash[numHops];
byte tunnelIds[][] = new byte[numHops][4];
for (int i = 0; i < numHops; i++) {
peers[i] = new Hash();
peers[i].setData(new byte[Hash.HASH_LENGTH]);
_context.random().nextBytes(peers[i].getData());
_context.random().nextBytes(tunnelIds[i]);
}
TunnelCreatorConfig config = new TunnelCreatorConfig(numHops, false);
for (int i = 0; i < numHops; i++) {
config.setPeer(i, peers[i]);
HopConfig cfg = config.getConfig(i);
cfg.setExpiration(_context.clock().now() + 60000);
cfg.setIVKey(_context.keyGenerator().generateSessionKey());
cfg.setLayerKey(_context.keyGenerator().generateSessionKey());
if (i > 0)
cfg.setReceiveFrom(peers[i-1]);
else
cfg.setReceiveFrom(null);
cfg.setReceiveTunnelId(tunnelIds[i]);
if (i < numHops - 1) {
cfg.setSendTo(peers[i+1]);
cfg.setSendTunnelId(tunnelIds[i+1]);
} else {
cfg.setSendTo(null);
cfg.setSendTunnelId(null);
}
}
return config;
}
}

View File

@ -0,0 +1,84 @@
package net.i2p.router.tunnel;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.Log;
import junit.framework.TestCase;
/**
* Quick unit test for base functionality of outbound tunnel
* operation
*
*/
public class OutboundTest extends TestCase{
private I2PAppContext _context;
public void setUp() {
_context = I2PAppContext.getGlobalContext();
}
public void testOutbound() {
int numHops = 8;
TunnelCreatorConfig config = prepareConfig(numHops);
byte orig[] = new byte[1024];
byte message[] = new byte[1024];
_context.random().nextBytes(orig); // might as well fill the IV
System.arraycopy(orig, 0, message, 0, message.length);
OutboundGatewayProcessor p = new OutboundGatewayProcessor(_context, config);
p.process(message, 0, message.length);
for (int i = 0; i < numHops; i++) {
HopProcessor hop = new HopProcessor(_context, config.getConfig(i));
Hash prev = config.getConfig(i).getReceiveFrom();
assertTrue(hop.process(message, 0, message.length, prev));
}
boolean eq = DataHelper.eq(orig, 16, message, 16, orig.length - 16);
}
private TunnelCreatorConfig prepareConfig(int numHops) {
Hash peers[] = new Hash[numHops];
byte tunnelIds[][] = new byte[numHops][4];
for (int i = 0; i < numHops; i++) {
peers[i] = new Hash();
peers[i].setData(new byte[Hash.HASH_LENGTH]);
_context.random().nextBytes(peers[i].getData());
_context.random().nextBytes(tunnelIds[i]);
}
TunnelCreatorConfig config = new TunnelCreatorConfig(numHops, false);
for (int i = 0; i < numHops; i++) {
config.setPeer(i, peers[i]);
HopConfig cfg = config.getConfig(i);
cfg.setExpiration(_context.clock().now() + 60000);
cfg.setIVKey(_context.keyGenerator().generateSessionKey());
cfg.setLayerKey(_context.keyGenerator().generateSessionKey());
if (i > 0)
cfg.setReceiveFrom(peers[i-1]);
else
cfg.setReceiveFrom(null);
cfg.setReceiveTunnelId(tunnelIds[i]);
if (i < numHops - 1) {
cfg.setSendTo(peers[i+1]);
cfg.setSendTunnelId(tunnelIds[i+1]);
} else {
cfg.setSendTo(null);
cfg.setSendTunnelId(null);
}
}
return config;
}
}