package com.limegroup.gnutella.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.limegroup.gnutella.Connection;
import com.limegroup.gnutella.ConnectionManager;
import com.limegroup.gnutella.messages.QueryRequest;
import com.limegroup.gnutella.routing.QueryRouteTable;
import com.limegroup.gnutella.settings.UltrapeerSettings;
/**
* Helper class that supplies the list of connections for searching.
*/
public final class TestConnectionManager extends ConnectionManager {
/**
* The list of ultrapeer <tt>Connection</tt> instances
*/
private final List CONNECTIONS = new LinkedList();
/**
* The list of leaf <tt>Connection</tt> instances
*/
private final List LEAF_CONNECTIONS = new LinkedList();
/**
* Constant for whether or not this should be considered an
* Ultrapeer.
*/
private final boolean ULTRAPEER;
/**
* Constant for the number of Ultrapeer connections that the
* test connection manager should maintain.
*/
private final int NUM_CONNECTIONS;
/**
* Constant for the number of leaf connections that the test
* connection manager should maintain.
*/
private final int NUM_LEAF_CONNECTIONS;
/**
* Constant array for the keywords that I should have (this node).
*/
private final String[] MY_KEYWORDS;
/**
* Constant array for the keywords that I should have (this node)
* by default, unless the caller specifies otherwise.
*/
private static final String[] DEFAULT_MY_KEYWORDS = {
"me",
};
/**
* Constant array for the keywords for Ultrapeers to use.
*/
private static final String[] ULTRAPEER_KEYWORDS = {
"qwe", "wer", "ert", "rty", "tyu",
"yui", "uio", "iop", "opa ", "pas",
"asd", "sdf", "dfg", "fgh", "ghj",
"hjk", "jkl", "klz", "lzx", "zxc",
"xcv", "cvb", "vbn", "bnm", "qwer",
"wert", "erty", "rtyu", "tyui", "yuio",
};
/**
* Constant array for the keywords for leaves to use.
*/
private static final String[] LEAF_KEYWORDS = {
"this", "is", "a", "test", "for",
"query", "routing", "in", "all", "its",
"forms", "including", "both", "leaves", "and",
"Ultrapeers", "which", "should", "both", "work",
"like", "we", "expect", "them", "to",
"at", "least", "in", "theory", "and",
"hopefully", "in", "fact", "as", "well",
"but", "it's", "hard", "to", "know",
};
/**
* Array of keywords that should not match anything in the routing
* tables.
*/
private static final String[] UNMATCHING_KEYWORDS = {
"miss", "NCWEPHCE", "IEYWHFDSNC", "UIYRIEH", "dfjaivuih",
};
/**
* Factory method for generating a test manager with varied route tables from leaves.
*
* @return a new <tt>TestConnectionManager</tt> with varied leaf route tables for
* use in tests that require varied tables
*/
public static TestConnectionManager createManagerWithVariedLeaves() {
return new TestConnectionManager(20, true, 20,
UltrapeerSettings.MAX_LEAVES.getValue(), DEFAULT_MY_KEYWORDS, true);
}
/**
* Creates a standard manager.
*/
public static TestConnectionManager createManager() {
return new TestConnectionManager(20);
}
/**
* Convenience constructor that creates a new
* <tt>TestConnectionManager</tt> with all of the default settings.
*/
public TestConnectionManager() {
this(20);
}
public TestConnectionManager(String[] myKeywords) {
this(20, true, 20, UltrapeerSettings.MAX_LEAVES.getValue(), myKeywords, false);
}
/**
* Creates a new <tt>ConnectionManager</tt> with a list of
* <tt>TestConnection</tt>s for testing.
*
* @param numNewConnections the number of new connections to
* include in the set of connections
*/
public TestConnectionManager(int numNewConnections) {
this(numNewConnections, true);
}
/**
* Creates a new <tt>ConnectionManager</tt> with a list of
* <tt>TestConnection</tt>s for testing.
*
* @param numNewConnections the number of new connections to
* include in the set of connections
* @param ultrapeer whether or not this should be considered
* an ultrapeer
*/
public TestConnectionManager(int numNewConnections, boolean ultrapeer) {
this(numNewConnections, ultrapeer, 20, UltrapeerSettings.MAX_LEAVES.getValue(),
DEFAULT_MY_KEYWORDS, false);
}
/**
* Creates a new <tt>ConnectionManager</tt> with a list of
* <tt>TestConnection</tt>s for testing.
*
* @param numNewConnections the number of new connections to
* include in the set of connections
* @param ultrapeer whether or not this should be considered
* an ultrapeer
* @param useVaried boolean specifying whether or not leaves should
* have variable routing tables
*/
public TestConnectionManager(int numNewConnections, boolean ultrapeer,
int numConnections, int numLeafConnections,
String[] myKeywords, boolean useVaried) {
super();
NUM_CONNECTIONS = numConnections;
NUM_LEAF_CONNECTIONS = numLeafConnections;
MY_KEYWORDS = myKeywords;
for(int i=0; i<NUM_CONNECTIONS; i++) {
Connection curConn = null;
if(i < numNewConnections) {
curConn =
new UltrapeerConnection(new String[]{ULTRAPEER_KEYWORDS[i]});
} else {
curConn = new OldConnection(15);
}
CONNECTIONS.add(curConn);
}
// now, give ourselves the desired number of leaves
for(int i=0; i<NUM_LEAF_CONNECTIONS; i++) {
Connection conn;
if(useVaried && i >= (NUM_LEAF_CONNECTIONS/2)) {
conn = LeafConnection.createAltLeafConnection();
} else {
conn = LeafConnection.createWithKeywords(new String[]{LEAF_KEYWORDS[i]});
}
LEAF_CONNECTIONS.add(conn);
}
ULTRAPEER = ultrapeer;
}
/**
* Test to make sure that the given <tt>QueryRouteTable</tt> has matches
* for all of the expected keywords and that it doesn't have matches
* for any of the unexpected keywords.
*
* @param qrt the <tt>QueryRouteTable</tt> instance to test
*/
public boolean runQRPMatch(QueryRouteTable qrt) {
for(int i=0; i<MY_KEYWORDS.length; i++) {
QueryRequest qr = QueryRequest.createQuery(MY_KEYWORDS[i]);
if(!qrt.contains(qr)) return false;
}
for(int i=0; i<NUM_LEAF_CONNECTIONS; i++) {
QueryRequest qr = QueryRequest.createQuery(LEAF_KEYWORDS[i]);
if(!qrt.contains(qr)) return false;
}
for(int i=0; i<UNMATCHING_KEYWORDS.length; i++) {
QueryRequest qr =
QueryRequest.createQuery(UNMATCHING_KEYWORDS[i]);
if(qrt.contains(qr)) return false;
}
return true;
}
/**
* Accessor for the custom list of connections.
*/
public List getInitializedConnections() {
return CONNECTIONS;
}
public List getInitializedClientConnections() {
return LEAF_CONNECTIONS;
}
public boolean isSupernode() {
return ULTRAPEER;
}
/**
* Returns the total number of queries received over all Ultrapeer connections.
*/
public int getNumUltrapeerQueries() {
return getNumQueries(CONNECTIONS);
}
/**
* Returns the total number of queries received over all leaf connections.
*/
public int getNumLeafQueries() {
return getNumQueries(LEAF_CONNECTIONS);
}
/**
* Returns the total number of queries received over all leaf connections.
*/
private static int getNumQueries(Collection connections) {
int numQueries = 0;
Iterator iter = connections.iterator();
while(iter.hasNext()) {
TestConnection tc = (TestConnection)iter.next();
numQueries += tc.getNumQueries();
}
return numQueries;
}
/**
* Returns the total number of queries received over all old connections.
*/
public int getNumOldConnectionQueries() {
int numQueries = 0;
Iterator iter = CONNECTIONS.iterator();
while(iter.hasNext()) {
TestConnection tc = (TestConnection)iter.next();
if(tc instanceof OldConnection) {
numQueries += tc.getNumQueries();
}
}
return numQueries;
}
/**
* Returns the total number of queries received over all old connections.
*/
public int getNumNewConnectionQueries() {
int numQueries = 0;
Iterator iter = CONNECTIONS.iterator();
while(iter.hasNext()) {
TestConnection tc = (TestConnection)iter.next();
if(tc instanceof NewConnection) {
numQueries += tc.getNumQueries();
}
}
return numQueries;
}
public boolean isClientSupernodeConnection() {
return false;
}
}