package com.limegroup.bittorrent.dht;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import junit.framework.Test;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.limewire.mojito.EntityKey;
import org.limewire.mojito.KUID;
import org.limewire.mojito.MojitoDHT;
import org.limewire.mojito.concurrent.DHTFuture;
import org.limewire.mojito.concurrent.FixedDHTFuture;
import org.limewire.mojito.db.DHTValue;
import org.limewire.mojito.db.DHTValueEntity;
import org.limewire.mojito.db.impl.DHTValueImpl;
import org.limewire.mojito.result.FindValueResult;
import org.limewire.mojito.routing.Contact;
import org.limewire.mojito.routing.Version;
import org.limewire.util.BaseTestCase;
import com.google.inject.util.Providers;
import com.limegroup.bittorrent.ManagedTorrent;
import com.limegroup.bittorrent.TorrentLocation;
import com.limegroup.bittorrent.TorrentManager;
import com.limegroup.gnutella.ApplicationServices;
import com.limegroup.gnutella.NetworkManager;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.dht.DHTManager;
import com.limegroup.gnutella.dht.util.KUIDUtils;
public class DHTPeerLocatorImplTest extends BaseTestCase {
private String HASH1 = "urn:sha1:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
private String HASH2 = "urn:sha1:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
private byte[] IP;
private byte[] ID;
private int PORT = 4444;
private TorrentLocation torLoc = null;
private Mockery context;
private ManagedTorrent managedTorrentOne;
private ManagedTorrent managedTorrentTwo;
private DHTManager dhtManager;
private ApplicationServices applicationServices;
private NetworkManager networkManager;
private MojitoDHT dht;
private Contact contact;
private DHTPeerLocator dhtPeerLocator;
private KUID kuidOne;
private EntityKey eKeyOne;
private KUID kuidTwo;
private EntityKey eKeyTwo;
private URN urnOne;
private URN urnTwo;
private TorrentManager torrentManager;
public DHTPeerLocatorImplTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(DHTPeerLocatorImplTest.class);
}
@Override
public void setUp() throws Exception {
IP = "124.0.0.1".getBytes("US-ASCII");
ID = "123".getBytes("US-ASCII");
context = new Mockery();
managedTorrentOne = context.mock(ManagedTorrent.class);
managedTorrentTwo = context.mock(ManagedTorrent.class);
dhtManager = context.mock(DHTManager.class);
applicationServices = context.mock(ApplicationServices.class);
networkManager = context.mock(NetworkManager.class);
dht = context.mock(MojitoDHT.class);
torrentManager = context.mock(TorrentManager.class);
contact = context.mock(Contact.class);
try {
urnOne = URN.createSHA1Urn(HASH1);
urnTwo = URN.createSHA1Urn(HASH2);
} catch (IOException ie) {
fail(ie);
}
dhtPeerLocator = new DHTPeerLocatorImpl(Providers.of(dhtManager),
Providers.of(torrentManager));
kuidOne = KUIDUtils.toKUID(urnOne);
eKeyOne = EntityKey.createEntityKey(kuidOne, DHTPeerLocatorUtils.BT_PEER_TRIPLE);
kuidTwo = KUIDUtils.toKUID(urnTwo);
eKeyTwo = EntityKey.createEntityKey(kuidTwo, DHTPeerLocatorUtils.BT_PEER_TRIPLE);
}
// Tests if locatePeer properly stores the torrents in waiting list if a DHT
// was not available or did not support bootstrapping. It also test to
// ensure duplicate torrents do not get stored in the waiting list.
public void testLocatePeerWhichShouldPutTorrentsInWaitingList() {
context.checking(new Expectations() {
{
exactly(2).of(torrentManager).getTorrentForURN(with(equal(urnOne)));
will(returnValue(managedTorrentOne));
one(torrentManager).getTorrentForURN(with(equal(urnTwo)));
will(returnValue(managedTorrentTwo));
one(dhtManager).get(eKeyOne);
will(returnValue(null));
one(dhtManager).get(eKeyTwo);
will(returnValue(null));
}
});
// should store these torrents in the waiting list
dhtPeerLocator.locatePeer(urnOne);
dhtPeerLocator.locatePeer(urnTwo);
// should not store this in waiting list as it should already be stored
dhtPeerLocator.locatePeer(urnOne);
context.assertIsSatisfied();
}
// Tests if locatePeer properly locates a peer in DHT.
public void testLocatePeerWhichShouldLocateAPeerInDHT() {
context.checking(new Expectations() {
{
one(networkManager).getAddress();
will(returnValue(IP));
one(networkManager).getPort();
will(returnValue(PORT));
one(applicationServices).getMyBTGUID();
will(returnValue(ID));
exactly(2).of(dht).getLocalNode();
will(returnValue(contact));
one(contact).getNodeID();
will(returnValue(kuidOne));
}
});
byte[] msg = null;
try {
torLoc = new TorrentLocation(InetAddress.getByName(new String((networkManager
.getAddress()))), networkManager.getPort(), applicationServices.getMyBTGUID());
msg = DHTPeerLocatorUtils.encode(torLoc);
} catch (UnknownHostException uhe) {
fail(uhe);
} catch (IllegalArgumentException iae) {
fail(iae);
}
final DHTValue dhtValue = new DHTValueImpl(DHTPeerLocatorUtils.BT_PEER_TRIPLE,
Version.ZERO, msg);
DHTValueEntity entity = DHTValueEntity.createFromValue(dht, kuidOne, dhtValue);
Collection<DHTValueEntity> entities = new ArrayList<DHTValueEntity>();
entities.add(entity);
Collection<EntityKey> entityKeys = new ArrayList<EntityKey>();
entityKeys.add(eKeyOne);
FindValueResult result = new FindValueResult(eKeyOne, null, entities, entityKeys, 123123L, 10);
// a fake future with successful result to test if a successful search
// works
final DHTFuture<FindValueResult> future = new FixedDHTFuture<FindValueResult>(result);
context.checking(new Expectations() {
{
exactly(2).of(torrentManager).getTorrentForURN(with(equal(urnOne)));
will(returnValue(managedTorrentOne));
exactly(2).of(dhtManager).get(eKeyOne);
will(returnValue(future));
atLeast(1).of(managedTorrentOne).addEndpoint(with(equal(torLoc)));
}
});
// Should perform search successfully
dhtPeerLocator.locatePeer(urnOne);
context.assertIsSatisfied();
}
}