package com.limegroup.gnutella.messages;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
import junit.framework.Test;
import com.limegroup.gnutella.GUID;
import com.limegroup.gnutella.RouterService;
import com.limegroup.gnutella.util.NameValue;
import com.limegroup.gnutella.util.PrivilegedAccessor;
import com.limegroup.gnutella.settings.ConnectionSettings;
import com.limegroup.gnutella.settings.ApplicationSettings;
import com.limegroup.gnutella.settings.UltrapeerSettings;
public class PingRequestTest extends com.limegroup.gnutella.util.BaseTestCase {
public PingRequestTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(PingRequestTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public void setUp() {
// runs before every testX method
}
public void tearDown() {
// runs after every testX method
}
public static void globalSetUp() {
// runs before the first testX
}
public static void globalTearDown() {
// runs after the last textX
}
//TODO: test other parts of ping!
public void testQueryKeyPing() throws Exception {
PingRequest pr = PingRequest.createQueryKeyRequest();
assertFalse(pr.isQueryKeyRequest()); // hasn't been hopped yet
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pr.write(baos);
ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
PingRequest prRead = (PingRequest) Message.read(bais);
prRead.hop();
assertTrue(prRead.isQueryKeyRequest());
}
public void testGGEPPing() throws Exception {
// first make a GGEP block....
GGEP ggepBlock = new GGEP(false);
ggepBlock.put(GGEP.GGEP_HEADER_QUERY_KEY_SUPPORT);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ggepBlock.write(baos);
byte[] ggepBytes = baos.toByteArray();
//Headers plus payload(6 bytes)
byte[] buffer = new byte[23+ggepBytes.length+1];
byte[] guid = GUID.makeGuid();//get a GUID
System.arraycopy(guid,0,buffer,0,guid.length);//copy GUID
int currByte = guid.length;
buffer[currByte] = Message.F_PING;
currByte++;
buffer[currByte] = 0x0001; // TTL
currByte++;
buffer[currByte] = 0x0000;// Hops
currByte++;
buffer[currByte] = (byte)(ggepBytes.length+1);//1st byte = 6
currByte++;
buffer[currByte] = 0x0000;//2nd byte = 0
currByte++;
buffer[currByte] = 0x0000;//3rd byte = 0
currByte++;
buffer[currByte] = 0x0000;//4th byte = 0 - remember it's little endian
currByte++;
// stick in GGEP
for (int i = 0; i < ggepBytes.length; i++)
buffer[currByte++] = ggepBytes[i];
buffer[currByte++] = 0; // trailing 0
assertGreaterThanOrEquals(buffer.length, currByte);
//OK, ggep ping ready
ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
Message m = null;
m = Message.read(stream);
PingRequest pr = null;
pr = (PingRequest)m;
assertTrue(!pr.isQueryKeyRequest());
pr.hop();
assertTrue(pr.isQueryKeyRequest());
//Came this far means its all OK
}
public void testBigPing() throws Exception {
byte[] buffer = new byte[23+16];//Headers plus payload(16 bytes)
//Note: We choose a size of 16 to make sure it does not create a
//group ping,
byte[] guid = GUID.makeGuid();//get a GUID
System.arraycopy(guid,0,buffer,0,guid.length);//copy GUID
int currByte = guid.length;
buffer[currByte] = Message.F_PING;
currByte++;
buffer[currByte] = 0x0004; // TTL
currByte++;
buffer[currByte] = 0x0000;// Hops
currByte++;
buffer[currByte] = 0x0010;//1st byte = 16, A thro' P
currByte++;
buffer[currByte] = 0x0000;//2nd byte = 0
currByte++;
buffer[currByte] = 0x0000;//3rd byte = 0
currByte++;
buffer[currByte] = 0x0000;//4th byte = 0 - remember it's little endian
currByte++;
byte c = 65;//"A"
byte[] payload = new byte[16];//to be used to test constrcutor
for(int i=0; i<16; i++){
buffer[currByte] = c;
payload[i] = buffer[currByte];
currByte++;
c++;
}
//OK, Big ping ready
ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
Message m = null;
m = Message.read(stream);
PingRequest pr = null;
pr = (PingRequest)m;
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
pr.write(outBuffer);
byte [] outb = outBuffer.toByteArray();
String out = new String(outb,23,outb.length-23);
assertEquals("Wrong payload", "ABCDEFGHIJKLMNOP", out);
//Test the new constructor for big pings read from the network
PingRequest bigPing = new PingRequest(GUID.makeGuid(),(byte)7,
(byte)0,payload);
assertEquals(0, bigPing.getHops());
assertEquals(7, bigPing.getTTL());
assertEquals("bad length", 16, bigPing.getLength());
//Came this far means its all OK
}
public void testStripNoPayload() {
byte[] guid=new byte[16]; guid[0]=(byte)0xFF;
PingRequest pr=new PingRequest(guid, (byte)3, (byte)4);
assertEquals(pr, pr.stripExtendedPayload());
}
public void testStripPayload() throws Exception {
byte[] guid=new byte[16]; guid[0]=(byte)0xFF;
byte[] payload=new byte[20]; payload[3]=(byte)0xBC;
PingRequest pr=new PingRequest(guid, (byte)3, (byte)4, payload);
PingRequest pr2=(PingRequest)pr.stripExtendedPayload();
assertEquals(pr.getHops(), pr2.getHops());
assertEquals(pr.getTTL(), pr2.getTTL());
assertTrue(Arrays.equals(pr.getGUID(), pr2.getGUID()));
assertEquals(pr2.getTotalLength(),23);
ByteArrayOutputStream out=new ByteArrayOutputStream();
pr2.write(out);
assertEquals(out.toByteArray().length, 23);
}
public void testAddIP() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//try a ping which doesn't ask for ip
PingRequest noRequest = new PingRequest((byte)1);
assertFalse(noRequest.requestsIP());
noRequest.write(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
PingRequest fromNet = (PingRequest) Message.read(bais);
assertFalse(fromNet.requestsIP());
//try a ping without any other ggeps except the ip request
byte []guid = GUID.makeGuid();
PingRequest noPayload = new PingRequest(guid,(byte)1,(byte)0);
assertFalse(noPayload.requestsIP());
noPayload.addIPRequest();
assertTrue(noPayload.requestsIP());
baos = new ByteArrayOutputStream();
noPayload.write(baos);
bais = new ByteArrayInputStream(baos.toByteArray());
fromNet = (PingRequest) Message.read(bais);
assertTrue(fromNet.requestsIP());
// now try a ping with locale
String original = ApplicationSettings.LANGUAGE.getValue();
ApplicationSettings.LANGUAGE.setValue("zz");
PingRequest withLocale = new PingRequest((byte)1);
ApplicationSettings.LANGUAGE.setValue(original);
withLocale.addIPRequest();
baos = new ByteArrayOutputStream();
withLocale.write(baos);
bais = new ByteArrayInputStream(baos.toByteArray());
fromNet = (PingRequest) Message.read(bais);
assertTrue(fromNet.requestsIP());
assertEquals("zz",fromNet.getLocale());
assertFalse(fromNet.supportsCachedPongs());
assertNull(fromNet.getSupportsCachedPongData());
}
public void testUDPPingRequest() {
PingRequest pr = PingRequest.createUDPPing();
assertTrue(pr.supportsCachedPongs());
UltrapeerSettings.MIN_CONNECT_TIME.setValue(0);
UltrapeerSettings.FORCE_ULTRAPEER_MODE.setValue(true);
ConnectionSettings.EVER_ACCEPTED_INCOMING.setValue(true);
ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false);
UltrapeerSettings.EVER_ULTRAPEER_CAPABLE.setValue(true);
assertTrue(RouterService.isSupernode());
pr = PingRequest.createUDPPing();
assertFalse(pr.requestsIP());
byte[] data = pr.getSupportsCachedPongData();
assertEquals(0x1, data[0] & 0x1);
UltrapeerSettings.DISABLE_ULTRAPEER_MODE.setValue(true);
UltrapeerSettings.FORCE_ULTRAPEER_MODE.setValue(false);
assertFalse(RouterService.isSupernode());
pr = PingRequest.createUDPPing();
assertFalse(pr.requestsIP());
data = pr.getSupportsCachedPongData();
assertEquals(0x0, data[0] & 0x1);
ConnectionSettings.EVER_ACCEPTED_INCOMING.setValue(false);
pr = PingRequest.createUDPPing();
assertTrue(pr.requestsIP());
}
public void testSupportsCachedPongData() throws Exception {
List ggeps = new LinkedList();
ggeps.add(new NameValue(GGEP.GGEP_HEADER_SUPPORT_CACHE_PONGS));
PingRequest pr = make(ggeps);
assertTrue(pr.supportsCachedPongs());
byte[] data = pr.getSupportsCachedPongData();
assertNotNull(data);
assertEquals(0, data.length);
ggeps.clear();
ggeps.add(new NameValue(GGEP.GGEP_HEADER_SUPPORT_CACHE_PONGS, new byte[1]));
pr = make(ggeps);
assertTrue(pr.supportsCachedPongs());
data = pr.getSupportsCachedPongData();
assertNotNull(data);
assertEquals(1, data.length);
}
private PingRequest make(List ggeps) throws Exception {
return (PingRequest)PrivilegedAccessor.invokeConstructor(
PingRequest.class,
new Object[] { new byte[16], new Byte((byte)1), ggeps },
new Class[] { byte[].class, byte.class, List.class });
}
}