forked from I2P_Developers/i2p.i2p
Test: Add random delay and drop options to LocalClientManager
Return failure codes from LCM to client (ticket #1939)
This commit is contained in:
@ -223,7 +223,11 @@
|
|||||||
<!-- warning - The junit.test target below doesn't actually include i2ptest.jar in the classpath,
|
<!-- warning - The junit.test target below doesn't actually include i2ptest.jar in the classpath,
|
||||||
only the build/obj directory.
|
only the build/obj directory.
|
||||||
-->
|
-->
|
||||||
<jar destfile="./build/i2ptest.jar" basedir="./build/obj" includes="**/*.class **/test.data **/baseDblPrecmp **/basePrecmp" />
|
<jar destfile="./build/i2ptest.jar" basedir="./build/obj" >
|
||||||
|
<fileset dir="./build/obj" includes="**/*.class **/test.data **/baseDblPrecmp **/basePrecmp" />
|
||||||
|
<!-- the getopt translation files -->
|
||||||
|
<fileset dir="src" includes="${translation.includes}" />
|
||||||
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
<!-- preparation of code coverage tool of choice -->
|
<!-- preparation of code coverage tool of choice -->
|
||||||
<target name="prepareClover" depends="compile" if="with.clover">
|
<target name="prepareClover" depends="compile" if="with.clover">
|
||||||
|
@ -8,12 +8,15 @@ package net.i2p.router.client;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import gnu.getopt.Getopt;
|
||||||
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Payload;
|
import net.i2p.data.Payload;
|
||||||
import net.i2p.data.i2cp.MessageId;
|
import net.i2p.data.i2cp.MessageId;
|
||||||
import net.i2p.data.i2cp.MessageStatusMessage;
|
import net.i2p.data.i2cp.MessageStatusMessage;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
|
import net.i2p.util.SimpleTimer2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For testing clients without a full router.
|
* For testing clients without a full router.
|
||||||
@ -25,6 +28,7 @@ import net.i2p.util.I2PThread;
|
|||||||
* @since 0.9.8
|
* @since 0.9.8
|
||||||
*/
|
*/
|
||||||
class LocalClientManager extends ClientManager {
|
class LocalClientManager extends ClientManager {
|
||||||
|
private static int dropX1000 = 0, jitter = 0, latency = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context stub, may be constructed with new RouterContext(null),
|
* @param context stub, may be constructed with new RouterContext(null),
|
||||||
@ -45,7 +49,7 @@ class LocalClientManager extends ClientManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local only
|
* Local only
|
||||||
* TODO: add simulated delay and random drops to test streaming.
|
* TODO: we could have per-destination delay/drop parameters in the client options
|
||||||
*
|
*
|
||||||
* @param flags ignored for local
|
* @param flags ignored for local
|
||||||
*/
|
*/
|
||||||
@ -56,9 +60,31 @@ class LocalClientManager extends ClientManager {
|
|||||||
ClientConnectionRunner sender = getRunner(fromDest);
|
ClientConnectionRunner sender = getRunner(fromDest);
|
||||||
ClientConnectionRunner runner = getRunner(toDest);
|
ClientConnectionRunner runner = getRunner(toDest);
|
||||||
if (runner != null) {
|
if (runner != null) {
|
||||||
runner.receiveMessage(toDest, fromDest, payload);
|
if (dropX1000 > 0) {
|
||||||
if (sender != null)
|
if (100 * 1000 * _ctx.random().nextFloat() < dropX1000) {
|
||||||
sender.updateMessageDeliveryStatus(fromDest, msgId, messageNonce, MessageStatusMessage.STATUS_SEND_SUCCESS_LOCAL);
|
System.out.println("Message " + msgId + " DROPPED randomly");
|
||||||
|
if (sender != null) {
|
||||||
|
// pretend success
|
||||||
|
sender.updateMessageDeliveryStatus(fromDest, msgId, messageNonce, MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latency > 0 || jitter > 0) {
|
||||||
|
int delay = latency;
|
||||||
|
if (jitter > 0)
|
||||||
|
delay += (int) (jitter * _ctx.random().nextGaussian());
|
||||||
|
if (delay > 0) {
|
||||||
|
System.out.println("Message " + msgId + " DELAYED " + delay + " ms");
|
||||||
|
DelayedSend ds = new DelayedSend(_ctx, sender, runner, fromDest, toDest, payload, msgId, messageNonce);
|
||||||
|
ds.schedule(delay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean ok = runner.receiveMessage(toDest, fromDest, payload);
|
||||||
|
if (sender != null) {
|
||||||
|
int rc = ok ? MessageStatusMessage.STATUS_SEND_SUCCESS_LOCAL : MessageStatusMessage.STATUS_SEND_FAILURE_LOCAL;
|
||||||
|
sender.updateMessageDeliveryStatus(fromDest, msgId, messageNonce, rc);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// remote. ignore.
|
// remote. ignore.
|
||||||
System.out.println("Message " + msgId + " is targeting a REMOTE destination - DROPPED");
|
System.out.println("Message " + msgId + " is targeting a REMOTE destination - DROPPED");
|
||||||
@ -67,13 +93,87 @@ class LocalClientManager extends ClientManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class DelayedSend extends SimpleTimer2.TimedEvent {
|
||||||
|
private final ClientConnectionRunner s, r;
|
||||||
|
private final Destination fd, td;
|
||||||
|
private final Payload pl;
|
||||||
|
private final MessageId id;
|
||||||
|
private final long nonce;
|
||||||
|
|
||||||
|
public DelayedSend(RouterContext ctx, ClientConnectionRunner sender, ClientConnectionRunner runner,
|
||||||
|
Destination fromDest, Destination toDest, Payload payload,
|
||||||
|
MessageId msgId, long messageNonce) {
|
||||||
|
super(ctx.simpleTimer2());
|
||||||
|
s = sender; r = runner; fd = fromDest;
|
||||||
|
td = toDest; pl = payload;
|
||||||
|
id = msgId; nonce = messageNonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void timeReached() {
|
||||||
|
boolean ok = r.receiveMessage(td, fd, pl);
|
||||||
|
if (s != null) {
|
||||||
|
int rc = ok ? MessageStatusMessage.STATUS_SEND_SUCCESS_LOCAL : MessageStatusMessage.STATUS_SEND_FAILURE_LOCAL;
|
||||||
|
s.updateMessageDeliveryStatus(fd, id, nonce, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
|
int dropX1000 = 0, jitter = 0, latency = 0;
|
||||||
|
boolean error = false;
|
||||||
|
Getopt g = new Getopt("router", args, "d:j:l:");
|
||||||
|
try {
|
||||||
|
int c;
|
||||||
|
while ((c = g.getopt()) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
dropX1000 = (int) (1000 * Double.parseDouble(g.getOptarg()));
|
||||||
|
if (dropX1000 < 0 || dropX1000 >= 100 * 1000)
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
jitter = Integer.parseInt(g.getOptarg());
|
||||||
|
if (jitter < 0)
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
latency = Integer.parseInt(g.getOptarg());
|
||||||
|
if (latency < 0)
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
if (error || args.length - g.getOptind() > 0) {
|
||||||
|
usage();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
RouterContext ctx = new RouterContext(null);
|
RouterContext ctx = new RouterContext(null);
|
||||||
int port = ClientManagerFacadeImpl.DEFAULT_PORT;
|
int port = ClientManagerFacadeImpl.DEFAULT_PORT;
|
||||||
ClientManager mgr = new LocalClientManager(ctx, port);
|
LocalClientManager mgr = new LocalClientManager(ctx, port);
|
||||||
|
mgr.dropX1000 = dropX1000;
|
||||||
|
mgr.jitter = jitter;
|
||||||
|
mgr.latency = latency;
|
||||||
mgr.start();
|
mgr.start();
|
||||||
System.out.println("Listening on port " + port);
|
System.out.println("Listening on port " + port);
|
||||||
try { Thread.sleep(60*60*1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(60*60*1000); } catch (InterruptedException ie) {}
|
||||||
System.out.println("Done listening on port " + port);
|
System.out.println("Done listening on port " + port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void usage() {
|
||||||
|
System.err.println("usage: LocalClientManager\n" +
|
||||||
|
" [-d droppercent] // 0.0 - 99.99999 (default 0)\n" +
|
||||||
|
" [-j jitter] // (integer ms for 1 std. deviation, default 0)\n" +
|
||||||
|
" [-l latency] // (integer ms, default 0)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user