package com.limegroup.gnutella.filters;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.Test;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.limewire.concurrent.SimpleTimer;
import org.limewire.core.settings.FilterSettings;
import org.limewire.gnutella.tests.LimeTestCase;
import org.limewire.util.Base32;
import org.limewire.util.Visitor;
import com.limegroup.gnutella.Response;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.messages.QueryReply;
import com.limegroup.gnutella.spam.SpamManager;
public class URNFilterTest extends LimeTestCase {
private Mockery context;
private URNFilter urnFilter;
private SpamManager spamManager;
private final String good, badLocal, badRemote, badFile;
public URNFilterTest(String name) {
super(name);
byte[] urn = new byte[20];
for(int i = 0; i < 20; i++) {
urn[i] = (byte)i;
}
good = Base32.encode(urn);
for(int i = 0; i < 20; i++) {
urn[i] = (byte)(i + 1);
}
badLocal = Base32.encode(urn);
for(int i = 0; i < 20; i++) {
urn[i] = (byte)(i + 2);
}
badRemote = Base32.encode(urn);
for(int i = 0; i < 20; i++) {
urn[i] = (byte)(i + 3);
}
badFile = Base32.encode(urn);
}
public static Test suite() {
return buildTestSuite(URNFilterTest.class);
}
@Override
protected void setUp() throws InterruptedException {
FilterSettings.FILTERED_URNS_LOCAL.set(new String[] {badLocal});
FilterSettings.FILTERED_URNS_REMOTE.set(new String[] {badRemote});
context = new Mockery();
spamManager = context.mock(SpamManager.class);
urnFilter = new URNFilterImpl(spamManager,
new StubURNBlacklistManager(), new SimpleTimer(true));
final CountDownLatch loaded = new CountDownLatch(1);
SpamFilter.LoadCallback callback = new SpamFilter.LoadCallback() {
@Override
public void spamFilterLoaded() {
loaded.countDown();
}
};
// The blacklist should not have been loaded yet
assertNull(urnFilter.getBlacklist());
urnFilter.refreshURNs(callback);
assertTrue(loaded.await(10, TimeUnit.SECONDS));
// The blacklist should now have been loaded
assertNotNull(urnFilter.getBlacklist());
context.assertIsSatisfied();
}
@Override
protected void tearDown() {
FilterSettings.FILTERED_URNS_LOCAL.revertToDefault();
FilterSettings.FILTERED_URNS_REMOTE.revertToDefault();
}
public void testRefreshURNs() {
// The blacklist should contain three URNs: one each from the local
// setting, the remote setting, and the blacklist manager's file
assertEquals(3, urnFilter.getBlacklist().size());
assertTrue(urnFilter.getBlacklist().contains(badLocal));
assertTrue(urnFilter.getBlacklist().contains(badRemote));
assertTrue(urnFilter.getBlacklist().contains(badFile));
context.assertIsSatisfied();
}
public void testAllow() throws Exception {
final Set<URN> badURNs = new HashSet<URN>();
badURNs.add(URN.createSHA1Urn("urn:sha1:" + badLocal));
final Set<URN> goodURNs = new HashSet<URN>();
goodURNs.add(URN.createSHA1Urn("urn:sha1:" + good));
final Response response = context.mock(Response.class);
final QueryReply queryReply = context.mock(QueryReply.class);
context.checking(new Expectations() {{
// The first reply should be rejected and passed to the spam manager
one(queryReply).getResultsArray();
will(returnValue(new Response[] {response}));
one(response).getUrns();
will(returnValue(badURNs));
one(spamManager).handleSpamQueryReply(queryReply);
// The second reply should be accepted
one(queryReply).getResultsArray();
will(returnValue(new Response[] {response}));
one(response).getUrns();
will(returnValue(goodURNs));
}});
assertFalse(urnFilter.allow(queryReply));
assertTrue(urnFilter.allow(queryReply));
context.assertIsSatisfied();
}
public void testIsBlacklistedQueryReply() throws Exception {
final Set<URN> badURNs = new HashSet<URN>();
badURNs.add(URN.createSHA1Urn("urn:sha1:" + badLocal));
final Set<URN> goodURNs = new HashSet<URN>();
goodURNs.add(URN.createSHA1Urn("urn:sha1:" + good));
final Response response = context.mock(Response.class);
final QueryReply queryReply = context.mock(QueryReply.class);
context.checking(new Expectations() {{
// The first reply should be rejected but not passed to the spam mgr
one(queryReply).getResultsArray();
will(returnValue(new Response[] {response}));
one(response).getUrns();
will(returnValue(badURNs));
// The second reply should be accepted
one(queryReply).getResultsArray();
will(returnValue(new Response[] {response}));
one(response).getUrns();
will(returnValue(goodURNs));
}});
assertTrue(urnFilter.isBlacklisted(queryReply));
assertFalse(urnFilter.isBlacklisted(queryReply));
context.assertIsSatisfied();
}
public void testIsBlacklistedURN() throws Exception {
URN badURN = URN.createSHA1Urn("urn:sha1:" + badLocal);
URN goodURN = URN.createSHA1Urn("urn:sha1:" + good);
assertTrue(urnFilter.isBlacklisted(badURN));
assertFalse(urnFilter.isBlacklisted(goodURN));
context.assertIsSatisfied();
}
private class StubURNBlacklistManager implements URNBlacklistManager {
@Override
public void loadURNs(Visitor<String> visitor) {
visitor.visit(badFile);
}
}
}