package com.limegroup.gnutella.spam; import java.util.Collections; import java.util.HashSet; import java.util.Set; import junit.framework.Test; import com.limegroup.gnutella.GUID; import com.limegroup.gnutella.RemoteFileDesc; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.settings.SearchSettings; import com.limegroup.gnutella.util.BaseTestCase; import com.limegroup.gnutella.util.DataUtils; import com.limegroup.gnutella.xml.LimeXMLDocument; public class SpamManagerTest extends BaseTestCase { public SpamManagerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(SpamManagerTest.class); } /** various names of files - some tokens need to exist in each" */ private static final String badger = " badger "; private static final String mushroom = " mushroom "; private static final String snake = " snake "; /** addresses */ private static final String addr1 = "1.1.1.1"; private static final int port1 = 6346; private static final String addr2 = "2.2.2.2"; private static final int port2 = 6347; /** urns */ private static URN urn1, urn2, urn3; /** sizes */ private static final int size1 = 1000; private static final int size2 = 2000; /** xml docs */ private static final String xml1 = "<?xml version=\"1.0\"?><audios xsi:noNamespaceSchemaLocation=" + "\"http://www.limewire.com/schemas/audio.xsd\"><audio " + "title=\"badger\"" + "></audio></audios>"; private static final String xml2 = "<?xml version=\"1.0\"?><videos xsi:noNamespaceSchemaLocation=" + "\"http://www.limewire.com/schemas/video.xsd\"><video " + "title=\"mushroom\"" + "></video></videos>"; static LimeXMLDocument doc1, doc2; static SpamManager manager = SpamManager.instance(); public static void globalSetUp() { try { urn1 = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYPFB"); urn2 = URN.createSHA1Urn("urn:sha1:ZLSTHIPQGSSZTS5FJUPAKUZWUGZQYPFB"); urn3 = URN.createSHA1Urn("urn:sha1:YLSTHIPQGSSZTS5FJUPAKUZWUGZQYPFB"); doc1 = new LimeXMLDocument(xml1); doc2 = new LimeXMLDocument(xml2); } catch (Exception bad) { fail(bad); } } public void setUp() { SearchSettings.ENABLE_SPAM_FILTER.setValue(true); SearchSettings.FILTER_SPAM_RESULTS.revertToDefault(); manager.clearFilterData(); } /** * tests that when the user sets one result to be spammy, it affects * the rating of other results with similar tokens in them */ public void testSetSpam() throws Exception { RemoteFileDesc badgers = createRFD(addr1, port1, badger, null, urn1, size1); RemoteFileDesc badgerMushroom = createRFD(addr2, port2, badger+mushroom, null, urn2, size2); RemoteFileDesc mushroomSnake = createRFD(addr2, port2, mushroom+snake, null, urn2, size2); // originally, none of the rfds should be considered spam assertFalse(manager.isSpam(badgers)); assertFalse(manager.isSpam(badgerMushroom)); assertFalse(manager.isSpam(mushroomSnake)); assertTrue(badgers.getSpamRating() == 0); assertTrue(badgerMushroom.getSpamRating() == 0); assertTrue(mushroomSnake.getSpamRating() == 0); // lets say the user marks the badgers as spam manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers}); // the badgers should be spam, but the other rfd's not assertTrue(manager.isSpam(badgers)); assertFalse(manager.isSpam(badgerMushroom)); assertFalse(manager.isSpam(mushroomSnake)); // the badger & mushroom rfd should have some spam rating increase // but should not be as spammy as the badgers assertGreaterThan(0, badgerMushroom.getSpamRating()); assertLessThan(badgers.getSpamRating(), badgerMushroom.getSpamRating()); // the mushroom & snake rfd should still be 0 assertTrue(0 == mushroomSnake.getSpamRating()); } /** * tests that when the user sets one result to be not spam, it affects * the rating of other results with similar tokens in them */ public void testSetNotSpam() throws Exception { SearchSettings.FILTER_SPAM_RESULTS.setValue(0.5f); RemoteFileDesc badgers = createRFD(addr1, port1, badger, null, urn1, size1); RemoteFileDesc badgerMushroom = createRFD(addr1, port1, badger + mushroom, null, urn1, size1); RemoteFileDesc mushroomSnake = createRFD(addr1, port1, mushroom + snake, null, urn3, size1); // badgers & mushroom will be marked as spam, so we work with a very similar rfd RemoteFileDesc newBadgerMushroom = createRFD(addr1, port1, badger + mushroom, null, urn2, size1); // mark the badgers and mushrooms as spam manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers,badgerMushroom}); // the snake and new rfd should be brought above the spam treshold, but not be 100% // furthermore, rfd2new should have higher spam rating than the snake assertTrue("not spam? "+badgers.getSpamRating(),manager.isSpam(badgers)); assertTrue("not spam? "+badgerMushroom.getSpamRating(),manager.isSpam(badgerMushroom)); assertTrue("not spam? "+mushroomSnake.getSpamRating(),manager.isSpam(mushroomSnake)); assertTrue("not spam? "+newBadgerMushroom.getSpamRating(),manager.isSpam(newBadgerMushroom)); assertTrue("not spam? "+badgers.getSpamRating(),1f == badgers.getSpamRating()); assertTrue("not spam? "+badgerMushroom.getSpamRating(),1f == badgerMushroom.getSpamRating()); assertLessThan("not spam? "+mushroomSnake.getSpamRating(),1f,mushroomSnake.getSpamRating()); assertLessThan("not spam? "+mushroomSnake.getSpamRating(),1f,newBadgerMushroom.getSpamRating()); assertLessThan("not spam? "+newBadgerMushroom.getSpamRating(), newBadgerMushroom.getSpamRating(),mushroomSnake.getSpamRating()); // if the user says the mushroomSnake is not spammy at all, the badgerMushroom should drop manager.handleUserMarkedGood(new RemoteFileDesc[]{mushroomSnake}); assertFalse(manager.isSpam(mushroomSnake)); assertFalse(manager.isSpam(newBadgerMushroom)); assertTrue(manager.isSpam(badgers)); assertTrue(manager.isSpam(badgerMushroom)); assertTrue(1f == badgers.getSpamRating()); assertLessThan(1f,newBadgerMushroom.getSpamRating()); assertTrue(0f == mushroomSnake.getSpamRating()); } /** * tests that the URN is the most important factor when checking for spam */ public void testUrnOverrides() throws Exception { // the badgers and snake have nothing in common but the urn RemoteFileDesc badgers = createRFD(addr1, port1, badger, null, urn1, size1); RemoteFileDesc snakes = createRFD(addr2, port2, snake, null, urn1, size2); // marking one spam will automatically mark the other. manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers}); assertTrue(manager.isSpam(snakes)); // and vice versa manager.handleUserMarkedGood(new RemoteFileDesc[]{snakes}); assertFalse(manager.isSpam(badgers)); } /** * tests that the ratings are lowered for keywords the user searches for */ public void testQueryLowers() throws Exception { // make all the players slightly dependent, and mark the mushrooms as spam // the badgers and snake should have a little higher ratings because of that RemoteFileDesc mushroomBadgers = createRFD(addr1, port1, mushroom+badger, null, urn1, size1); RemoteFileDesc mushrooms = createRFD(addr2, port2, mushroom, null, urn2, size2); RemoteFileDesc mushroomSnakes = createRFD(addr1, port1, mushroom+snake, null, urn3, size1); manager.handleUserMarkedSpam(new RemoteFileDesc[]{mushrooms}); assertTrue(manager.isSpam(mushrooms)); assertFalse(manager.isSpam(mushroomBadgers)); assertFalse(manager.isSpam(mushroomSnakes)); float badgerRating = mushroomBadgers.getSpamRating(); float snakeRating = mushroomSnakes.getSpamRating(); assertGreaterThan(0f, badgerRating); assertGreaterThan(0f, snakeRating); // make the user send a query with a badger and a mushroom QueryRequest qr = QueryRequest.createQuery(mushroom); manager.startedQuery(qr); // if we receive results containing badgers and snakes their rating // should be lower than before RemoteFileDesc newBadger = createRFD(addr1,port1,mushroom + badger,null,urn1,size1); RemoteFileDesc newSnake = createRFD(addr1,port1,mushroom + snake,null,urn1,size1); assertFalse(manager.isSpam(newBadger)); assertFalse(manager.isSpam(newSnake)); assertLessThan(badgerRating, newBadger.getSpamRating()); assertLessThan(snakeRating, newSnake.getSpamRating()); } /** * tests that the address of the result is coming from affects the spam rating */ public void testAddressAffects() throws Exception { // create two completely different rfds except for the address RemoteFileDesc badgers = createRFD(addr1,port1,badger,null,urn1,size1); RemoteFileDesc snakes = createRFD(addr1,port1,mushroom,null,urn2,size2); assertFalse(manager.isSpam(badgers)); assertFalse(manager.isSpam(snakes)); assertTrue(0f == badgers.getSpamRating()); assertTrue(0f == snakes.getSpamRating()); // mark one of them as bad, the rating of the other should rise a little bit, // but not enough to consider it spam manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers}); assertFalse(manager.isSpam(snakes)); assertGreaterThan(0f, snakes.getSpamRating()); } /** * tests that the size of the result affects the spam rating */ public void testSizeAffects() throws Exception { // create two completely different rfds except for the size RemoteFileDesc badgers = createRFD(addr1,port1,badger,null,urn1,size1); RemoteFileDesc snakes = createRFD(addr2,port2,mushroom,null,urn2,size1); assertFalse(manager.isSpam(badgers)); assertFalse(manager.isSpam(snakes)); assertTrue(0f == badgers.getSpamRating()); assertTrue(0f == snakes.getSpamRating()); // mark one of them as bad, the rating of the other should rise a little bit, // but not enough to consider it spam manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers}); assertFalse(manager.isSpam(snakes)); assertGreaterThan(0f, snakes.getSpamRating()); } /** * tests that any xml documents in the result is affect the spam rating */ public void testXMLAffects() throws Exception { // create two completely different rfds except for the address RemoteFileDesc badgers = createRFD(addr1,port1,badger,doc1,urn1,size1); RemoteFileDesc snakes = createRFD(addr2,port2,mushroom,doc1,urn2,size2); assertFalse(manager.isSpam(badgers)); assertFalse(manager.isSpam(snakes)); assertTrue(0f == badgers.getSpamRating()); assertTrue(0f == snakes.getSpamRating()); // mark one of them as bad, the rating of the other should rise a little bit, // but not enough to consider it spam manager.handleUserMarkedSpam(new RemoteFileDesc[]{badgers}); assertFalse(manager.isSpam(snakes)); assertGreaterThan(0f, snakes.getSpamRating()); } private static RemoteFileDesc createRFD(String addr, int port, String name, LimeXMLDocument doc, URN urn, int size) { Set urns = new HashSet(); urns.add(urn); return new RemoteFileDesc(addr, port, 1, name, size, DataUtils.EMPTY_GUID, 3, false, 3, false, doc, urns, false,false, "ALT",0l, Collections.EMPTY_SET, 0l); } }