commit 0d426f38df0e77a6b8aed84a7295a061062cf9ca Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Feb 19 13:09:24 2015 +0100
Move test classes to subpackages. --- .../org/torproject/onionoo/DummyBridgeStatus.java | 43 - .../org/torproject/onionoo/DummyConsensus.java | 114 -- .../torproject/onionoo/DummyDescriptorSource.java | 90 -- .../org/torproject/onionoo/DummyDocumentStore.java | 120 -- .../org/torproject/onionoo/DummyStatusEntry.java | 92 -- .../java/org/torproject/onionoo/DummyTime.java | 16 - .../org/torproject/onionoo/LookupServiceTest.java | 596 --------- .../torproject/onionoo/ResourceServletTest.java | 1383 ------------------- .../onionoo/UptimeDocumentWriterTest.java | 260 ---- .../onionoo/UptimeStatusUpdaterTest.java | 184 --- .../onionoo/docs/BandwidthStatusTest.java | 2 +- .../onionoo/docs/DummyDocumentStore.java | 120 ++ .../onionoo/server/ResourceServletTest.java | 1385 ++++++++++++++++++++ .../onionoo/updater/DummyBridgeStatus.java | 43 + .../torproject/onionoo/updater/DummyConsensus.java | 114 ++ .../onionoo/updater/DummyDescriptorSource.java | 90 ++ .../onionoo/updater/DummyStatusEntry.java | 92 ++ .../onionoo/updater/LookupServiceTest.java | 596 +++++++++ .../onionoo/updater/UptimeStatusUpdaterTest.java | 182 +++ .../org/torproject/onionoo/util/DummyTime.java | 16 + .../onionoo/writer/UptimeDocumentWriterTest.java | 262 ++++ 21 files changed, 2901 insertions(+), 2899 deletions(-)
diff --git a/src/test/java/org/torproject/onionoo/DummyBridgeStatus.java b/src/test/java/org/torproject/onionoo/DummyBridgeStatus.java deleted file mode 100644 index 35a9036..0000000 --- a/src/test/java/org/torproject/onionoo/DummyBridgeStatus.java +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.torproject.descriptor.BridgeNetworkStatus; -import org.torproject.descriptor.NetworkStatusEntry; - -public class DummyBridgeStatus implements BridgeNetworkStatus { - - public byte[] getRawDescriptorBytes() { - return null; - } - - public List<String> getAnnotations() { - return null; - } - - public List<String> getUnrecognizedLines() { - return null; - } - - private long publishedMillis; - public void setPublishedMillis(long publishedMillis) { - this.publishedMillis = publishedMillis; - } - public long getPublishedMillis() { - return this.publishedMillis; - } - - private SortedMap<String, NetworkStatusEntry> statusEntries = - new TreeMap<String, NetworkStatusEntry>(); - public void addStatusEntry(NetworkStatusEntry statusEntry) { - this.statusEntries.put(statusEntry.getFingerprint(), statusEntry); - } - public SortedMap<String, NetworkStatusEntry> getStatusEntries() { - return this.statusEntries; - } -} - diff --git a/src/test/java/org/torproject/onionoo/DummyConsensus.java b/src/test/java/org/torproject/onionoo/DummyConsensus.java deleted file mode 100644 index 3fa0fdd..0000000 --- a/src/test/java/org/torproject/onionoo/DummyConsensus.java +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import java.util.List; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; - -import org.torproject.descriptor.DirSourceEntry; -import org.torproject.descriptor.DirectorySignature; -import org.torproject.descriptor.NetworkStatusEntry; -import org.torproject.descriptor.RelayNetworkStatusConsensus; - -public class DummyConsensus implements RelayNetworkStatusConsensus { - - public byte[] getRawDescriptorBytes() { - return null; - } - - public List<String> getAnnotations() { - return null; - } - - public List<String> getUnrecognizedLines() { - return null; - } - - public int getNetworkStatusVersion() { - return 0; - } - - public String getConsensusFlavor() { - return null; - } - - public int getConsensusMethod() { - return 0; - } - - private long validAfterMillis; - public void setValidAfterMillis(long validAfterMillis) { - this.validAfterMillis = validAfterMillis; - } - public long getValidAfterMillis() { - return this.validAfterMillis; - } - - public long getFreshUntilMillis() { - return 0; - } - - public long getValidUntilMillis() { - return 0; - } - - public long getVoteSeconds() { - return 0; - } - - public long getDistSeconds() { - return 0; - } - - public List<String> getRecommendedServerVersions() { - return null; - } - - public List<String> getRecommendedClientVersions() { - return null; - } - - public SortedSet<String> getKnownFlags() { - return null; - } - - public SortedMap<String, Integer> getConsensusParams() { - return null; - } - - public SortedMap<String, DirSourceEntry> getDirSourceEntries() { - return null; - } - - private SortedMap<String, NetworkStatusEntry> statusEntries = - new TreeMap<String, NetworkStatusEntry>(); - public void addStatusEntry(NetworkStatusEntry statusEntry) { - this.statusEntries.put(statusEntry.getFingerprint(), statusEntry); - } - public SortedMap<String, NetworkStatusEntry> getStatusEntries() { - return this.statusEntries; - } - - public boolean containsStatusEntry(String fingerprint) { - return false; - } - - public NetworkStatusEntry getStatusEntry(String fingerprint) { - return null; - } - - public SortedMap<String, DirectorySignature> getDirectorySignatures() { - return null; - } - - public SortedMap<String, Integer> getBandwidthWeights() { - return null; - } - - public String getConsensusDigest() { - return null; - } -} - diff --git a/src/test/java/org/torproject/onionoo/DummyDescriptorSource.java b/src/test/java/org/torproject/onionoo/DummyDescriptorSource.java deleted file mode 100644 index 4dbf066..0000000 --- a/src/test/java/org/torproject/onionoo/DummyDescriptorSource.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.torproject.onionoo; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.torproject.descriptor.Descriptor; -import org.torproject.onionoo.updater.DescriptorListener; -import org.torproject.onionoo.updater.DescriptorSource; -import org.torproject.onionoo.updater.DescriptorType; - -public class DummyDescriptorSource extends DescriptorSource { - - private Map<DescriptorType, Set<Descriptor>> descriptors = - new HashMap<DescriptorType, Set<Descriptor>>(); - - public void provideDescriptors(DescriptorType descriptorType, - Collection<Descriptor> descriptors) { - for (Descriptor descriptor : descriptors) { - this.addDescriptor(descriptorType, descriptor); - } - } - - public void addDescriptor(DescriptorType descriptorType, - Descriptor descriptor) { - this.getDescriptorsByType(descriptorType).add(descriptor); - } - - private Set<Descriptor> getDescriptorsByType( - DescriptorType descriptorType) { - if (!this.descriptors.containsKey(descriptorType)) { - this.descriptors.put(descriptorType, new HashSet<Descriptor>()); - } - return this.descriptors.get(descriptorType); - } - - private Map<DescriptorType, Set<DescriptorListener>> - descriptorListeners = new HashMap<DescriptorType, - Set<DescriptorListener>>(); - - public void registerDescriptorListener(DescriptorListener listener, - DescriptorType descriptorType) { - if (!this.descriptorListeners.containsKey(descriptorType)) { - this.descriptorListeners.put(descriptorType, - new HashSet<DescriptorListener>()); - } - this.descriptorListeners.get(descriptorType).add(listener); - } - - public void readDescriptors() { - Set<DescriptorType> descriptorTypes = new HashSet<DescriptorType>(); - descriptorTypes.addAll(this.descriptorListeners.keySet()); - for (DescriptorType descriptorType : descriptorTypes) { - boolean relay; - switch (descriptorType) { - case RELAY_CONSENSUSES: - case RELAY_SERVER_DESCRIPTORS: - case RELAY_EXTRA_INFOS: - case EXIT_LISTS: - relay = true; - break; - case BRIDGE_STATUSES: - case BRIDGE_SERVER_DESCRIPTORS: - case BRIDGE_EXTRA_INFOS: - case BRIDGE_POOL_ASSIGNMENTS: - default: - relay = false; - break; - } - if (this.descriptors.containsKey(descriptorType) && - this.descriptorListeners.containsKey(descriptorType)) { - Set<DescriptorListener> listeners = - this.descriptorListeners.get(descriptorType); - for (Descriptor descriptor : - this.getDescriptorsByType(descriptorType)) { - for (DescriptorListener listener : listeners) { - listener.processDescriptor(descriptor, relay); - } - } - } - } - } - - public void writeHistoryFiles() { - /* Nothing to do here. */ - } -} - diff --git a/src/test/java/org/torproject/onionoo/DummyDocumentStore.java b/src/test/java/org/torproject/onionoo/DummyDocumentStore.java deleted file mode 100644 index f5601b0..0000000 --- a/src/test/java/org/torproject/onionoo/DummyDocumentStore.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.torproject.onionoo; - -import java.util.HashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.torproject.onionoo.docs.Document; -import org.torproject.onionoo.docs.DocumentStore; - -public class DummyDocumentStore extends DocumentStore { - - private Map<Class<? extends Document>, SortedMap<String, Document>> - storedDocuments = new HashMap<Class<? extends Document>, - SortedMap<String, Document>>(); - - private static final String FINGERPRINT_NULL = ""; - - private <T extends Document> SortedMap<String, Document> - getStoredDocumentsByClass(Class<T> documentType) { - if (!this.storedDocuments.containsKey(documentType)) { - this.storedDocuments.put(documentType, - new TreeMap<String, Document>()); - } - return this.storedDocuments.get(documentType); - } - - public <T extends Document> void addDocument(T document, - String fingerprint) { - this.getStoredDocumentsByClass(document.getClass()).put( - fingerprint == null ? FINGERPRINT_NULL : fingerprint, document); - } - - public <T extends Document> T getDocument(Class<T> documentType, - String fingerprint) { - return documentType.cast(this.getStoredDocumentsByClass(documentType). - get(fingerprint == null ? FINGERPRINT_NULL : fingerprint)); - } - - public void flushDocumentCache() { - /* Nothing to do. */ - } - - public String getStatsString() { - /* No statistics to return. */ - return null; - } - - private int performedListOperations = 0; - public int getPerformedListOperations() { - return this.performedListOperations; - } - - public <T extends Document> SortedSet<String> list( - Class<T> documentType, long modifiedAfter) { - return this.list(documentType); - } - - public <T extends Document> SortedSet<String> list( - Class<T> documentType) { - this.performedListOperations++; - SortedSet<String> fingerprints = new TreeSet<String>( - this.getStoredDocumentsByClass(documentType).keySet()); - fingerprints.remove(FINGERPRINT_NULL); - return fingerprints; - } - - private int performedRemoveOperations = 0; - public int getPerformedRemoveOperations() { - return this.performedRemoveOperations; - } - - public <T extends Document> boolean remove(Class<T> documentType) { - return this.remove(documentType, null); - } - - public <T extends Document> boolean remove(Class<T> documentType, - String fingerprint) { - this.performedRemoveOperations++; - return this.getStoredDocumentsByClass(documentType).remove( - fingerprint) != null; - } - - private int performedRetrieveOperations = 0; - public int getPerformedRetrieveOperations() { - return this.performedRetrieveOperations; - } - - public <T extends Document> T retrieve(Class<T> documentType, - boolean parse) { - return this.retrieve(documentType, parse, null); - } - - public <T extends Document> T retrieve(Class<T> documentType, - boolean parse, String fingerprint) { - this.performedRetrieveOperations++; - return documentType.cast(this.getStoredDocumentsByClass(documentType). - get(fingerprint == null ? FINGERPRINT_NULL : fingerprint)); - } - - private int performedStoreOperations = 0; - public int getPerformedStoreOperations() { - return this.performedStoreOperations; - } - - public <T extends Document> boolean store(T document) { - return this.store(document, null); - } - - public <T extends Document> boolean store(T document, - String fingerprint) { - this.performedStoreOperations++; - this.getStoredDocumentsByClass(document.getClass()).put( - fingerprint == null ? FINGERPRINT_NULL : fingerprint, document); - return true; - } -} - diff --git a/src/test/java/org/torproject/onionoo/DummyStatusEntry.java b/src/test/java/org/torproject/onionoo/DummyStatusEntry.java deleted file mode 100644 index 8fdc5cd..0000000 --- a/src/test/java/org/torproject/onionoo/DummyStatusEntry.java +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.torproject.descriptor.NetworkStatusEntry; - -public class DummyStatusEntry implements NetworkStatusEntry { - - public DummyStatusEntry(String fingerprint) { - this.fingerprint = fingerprint; - } - - public byte[] getStatusEntryBytes() { - return null; - } - - @Override - public String getNickname() { - return null; - } - - private String fingerprint; - public String getFingerprint() { - return this.fingerprint; - } - - public String getDescriptor() { - return null; - } - - public long getPublishedMillis() { - return 0; - } - - public String getAddress() { - return null; - } - - public int getOrPort() { - return 0; - } - - public int getDirPort() { - return 0; - } - - public Set<String> getMicrodescriptorDigests() { - return null; - } - - public List<String> getOrAddresses() { - return null; - } - - private SortedSet<String> flags = new TreeSet<String>(); - public void addFlag(String flag) { - this.flags.add(flag); - } - public SortedSet<String> getFlags() { - return this.flags; - } - - public String getVersion() { - return null; - } - - public long getBandwidth() { - return 0; - } - - public long getMeasured() { - return 0; - } - - public boolean getUnmeasured() { - return false; - } - - public String getDefaultPolicy() { - return null; - } - - public String getPortList() { - return null; - } -} - diff --git a/src/test/java/org/torproject/onionoo/DummyTime.java b/src/test/java/org/torproject/onionoo/DummyTime.java deleted file mode 100644 index ffbd6e3..0000000 --- a/src/test/java/org/torproject/onionoo/DummyTime.java +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import org.torproject.onionoo.util.Time; - -public class DummyTime extends Time { - private long currentTimeMillis; - public DummyTime(long currentTimeMillis) { - this.currentTimeMillis = currentTimeMillis; - } - public long currentTimeMillis() { - return this.currentTimeMillis; - } -} - diff --git a/src/test/java/org/torproject/onionoo/LookupServiceTest.java b/src/test/java/org/torproject/onionoo/LookupServiceTest.java deleted file mode 100644 index 56c928d..0000000 --- a/src/test/java/org/torproject/onionoo/LookupServiceTest.java +++ /dev/null @@ -1,596 +0,0 @@ -/* Copyright 2013 The Tor Project - * See LICENSE for licensing information */ - -package org.torproject.onionoo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.torproject.onionoo.updater.LookupResult; -import org.torproject.onionoo.updater.LookupService; - -public class LookupServiceTest { - - private List<String> geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, geoipASNum2Lines; - - private LookupService lookupService; - - private SortedSet<String> addressStrings = new TreeSet<String>(); - - private SortedMap<String, LookupResult> lookupResults; - - private void populateLines() { - this.geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - this.geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - this.geoLite2CityBlocksIPv4Lines.add("8.8.0.0/21,6252001,6252001,,0," - + "0,,38.0000,-97.0000"); - this.geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,5375480,6252001,,0," - + "0,94035,37.3860,-122.0838"); - this.geoLite2CityBlocksIPv4Lines.add("8.8.9.0/24,6252001,6252001,,0," - + "0,,38.0000,-97.0000"); - this.geoLite2CityLocationsEnLines = new ArrayList<String>(); - this.geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - this.geoLite2CityLocationsEnLines.add("6252001,en,NA," - + ""North America",US,"United States",,,,,,,"); - this.geoLite2CityLocationsEnLines.add("5375480,en,NA," - + ""North America",US,"United States",CA,California,,," - + ""Mountain View",807,America/Los_Angeles"); - this.geoipASNum2Lines = new ArrayList<String>(); - this.geoipASNum2Lines.add("134743296,134744063,"AS3356 Level 3 " - + "Communications""); - this.geoipASNum2Lines.add("134744064,134744319,"AS15169 Google " - + "Inc.""); - this.geoipASNum2Lines.add("134744320,134750463,"AS3356 Level 3 " - + "Communications""); - } - - private void writeCsvFiles() { - try { - this.writeCsvFile(this.geoLite2CityBlocksIPv4Lines, - "GeoLite2-City-Blocks-IPv4.csv"); - this.writeCsvFile(this.geoLite2CityLocationsEnLines, - "GeoLite2-City-Locations-en.csv"); - this.writeCsvFile(this.geoipASNum2Lines, "GeoIPASNum2.csv"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void writeCsvFile(List<String> lines, String fileName) - throws IOException { - if (lines != null && !lines.isEmpty()) { - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(new File(this.tempGeoipDir, fileName)), - "UTF-8")); - for (String line : lines) { - bw.write(line + "\n"); - } - bw.close(); - } - } - - private void performLookups() { - this.lookupService = new LookupService(this.tempGeoipDir); - this.lookupResults = this.lookupService.lookup(this.addressStrings); - } - - private void assertLookupResult(List<String> geoLite2CityBlocksLines, - List<String> geoLite2CityLocationsLines, - List<String> geoipASNum2Lines, String addressString, - String countryCode, String countryName, String regionName, - String cityName, Float latitude, Float longitude, String aSNumber, - String aSName) { - this.addressStrings.add(addressString); - this.populateLines(); - if (geoLite2CityBlocksLines != null) { - this.geoLite2CityBlocksIPv4Lines = geoLite2CityBlocksLines; - } - if (geoLite2CityLocationsLines != null) { - this.geoLite2CityLocationsEnLines = geoLite2CityLocationsLines; - } - if (geoipASNum2Lines != null) { - this.geoipASNum2Lines = geoipASNum2Lines; - } - this.writeCsvFiles(); - /* Disable log messages printed to System.err. */ - System.setErr(new PrintStream(new OutputStream() { - public void write(int b) { - } - })); - this.performLookups(); - if (countryCode == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getCountryCode() == null); - } else { - assertEquals(countryCode, - this.lookupResults.get(addressString).getCountryCode()); - } - if (countryName == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getCountryName() == null); - } else { - assertEquals(countryName, - this.lookupResults.get(addressString).getCountryName()); - } - if (regionName == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getRegionName() == null); - } else { - assertEquals(regionName, - this.lookupResults.get(addressString).getRegionName()); - } - if (cityName == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getCityName() == null); - } else { - assertEquals(cityName, - this.lookupResults.get(addressString).getCityName()); - } - if (latitude == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getLatitude() == null); - } else { - assertEquals(latitude, - this.lookupResults.get(addressString).getLatitude(), 0.01); - } - if (longitude == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getLongitude() == null); - } else { - assertEquals(longitude, - this.lookupResults.get(addressString).getLongitude(), 0.01); - } - if (aSNumber == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getAsNumber() == null); - } else { - assertEquals(aSNumber, - this.lookupResults.get(addressString).getAsNumber()); - } - if (aSName == null) { - assertTrue(!this.lookupResults.containsKey(addressString) || - this.lookupResults.get(addressString).getAsName() == null); - } else { - assertEquals(aSName, - this.lookupResults.get(addressString).getAsName()); - } - } - - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - - private File tempGeoipDir; - - @Before - public void createTempGeoipDir() throws IOException { - this.tempGeoipDir = this.tempFolder.newFolder("geoip"); - } - - @Test() - public void testLookup8888() { - this.assertLookupResult(null, null, null, "8.8.8.8", "us", - "United States", "California", "Mountain View", 37.3860f, - -122.0838f, "AS15169", "Google Inc."); - } - - @Test() - public void testLookup8880() { - this.assertLookupResult(null, null, null, "8.8.8.0", "us", - "United States", "California", "Mountain View", 37.3860f, - -122.0838f, "AS15169", "Google Inc."); - } - - @Test() - public void testLookup888255() { - this.assertLookupResult(null, null, null, "8.8.8.255", "us", - "United States", "California", "Mountain View", 37.3860f, - -122.0838f, "AS15169", "Google Inc."); - } - - @Test() - public void testLookup888256() { - this.assertLookupResult(null, null, null, "8.8.8.256", null, null, - null, null, null, null, null, null); - } - - @Test() - public void testLookup888Minus1() { - this.assertLookupResult(null, null, null, "8.8.8.-1", null, null, - null, null, null, null, null, null); - } - - @Test() - public void testLookup000() { - this.assertLookupResult(null, null, null, "0.0.0.0", null, null, null, - null, null, null, null, null); - } - - @Test() - public void testLookupNoBlocksLines() { - this.assertLookupResult(new ArrayList<String>(), null, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupNoLocationLines() { - this.assertLookupResult(null, new ArrayList<String>(), null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupNoGeoipASNum2Lines() { - this.assertLookupResult(null, null, new ArrayList<String>(), - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupNoCorrespondingLocation() { - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("6252001,en,NA," - + ""North America",US,"United States",,,,,,,"); - this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, - "8.8.8.8", null, null, null, null, 37.3860f, -122.0838f, - "AS15169", "Google Inc."); - } - - @Test() - public void testLookupBlocksStartNotANumber() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("one/24,5375480,6252001,,0," - + "0,94035,37.3860,-122.0838"); - this.assertLookupResult( - geoLite2CityBlocksIPv4Lines, null, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupBlocksLocationX() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,X,X,,0,0,94035,37.3860," - + "-122.0838"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupBlocksLocationEmpty() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,,,,0,0,,,"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, - "8.8.8.8", null, null, null, null, null, null, "AS15169", - "Google Inc."); - } - - @Test() - public void testLookupBlocksTooFewFields() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,5375480,6252001,,0," - + "0,94035,37.3860"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupLocationLocIdNotANumber() { - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("threetwoonenineone,en,NA," - + ""North America",US,"United States",CA,California,,," - + ""Mountain View",807,America/Los_Angeles"); - this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupLocationTooFewFields() { - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("threetwoonenineone,en,NA," - + ""North America",US,"United States",CA,California,,," - + ""Mountain View",807"); - this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, - "8.8.8.8", null, null, null, null, null, null, null, null); - } - - @Test() - public void testLookupGeoipASNum2EndBeforeStart() { - List<String> geoipASNum2Lines = new ArrayList<String>(); - geoipASNum2Lines.add("134743296,134744063,"AS3356 Level 3 " - + "Communications""); - geoipASNum2Lines.add("134744319,134744064,"AS15169 Google Inc.""); - geoipASNum2Lines.add("134744320,134750463,"AS3356 Level 3 " - + "Communications""); - this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", "us", - "United States", "California", "Mountain View", 37.3860f, - -122.0838f, null, null); - } - - @Test() - public void testLookupGeoipASNum2StartNotANumber() { - List<String> geoipASNum2Lines = new ArrayList<String>(); - geoipASNum2Lines.add("one,134744319,"AS15169 Google Inc.""); - this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, - null, null, null, null, null, null, null); - } - - @Test() - public void testLookupGeoipASNum2StartTooLarge() { - List<String> geoipASNum2Lines = new ArrayList<String>(); - geoipASNum2Lines.add("1" + String.valueOf(Long.MAX_VALUE) - + ",134744319,"AS15169 Google Inc.""); - this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, - null, null, null, null, null, null, null); - } - - @Test() - public void testLookupGeoipASNum2TooFewFields() { - List<String> geoipASNum2Lines = new ArrayList<String>(); - geoipASNum2Lines.add("134744064,134744319"); - this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, - null, null, null, null, null, null, null); - } - - @Test() - public void testLookupLocationTurkey() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("46.1.133.0/24,307515,298795,,0,0,," - + "39.1458,34.1639"); - geoLite2CityBlocksIPv4Lines.add("46.196.12.0/24,738927,298795,,0,0,," - + "40.9780,27.5085"); - geoLite2CityBlocksIPv4Lines.add("78.180.14.0/24,745169,298795,,0,0,," - + "40.0781,29.5133"); - geoLite2CityBlocksIPv4Lines.add("81.215.1.0/24,749748,298795,,0,0,," - + "40.6000,33.6153"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("307515,en,AS,Asia,TR,Turkey,40," - + ""K\u0131r\u015Fehir",,,"K\u0131r\u015Fehir",," - + "Europe/Istanbul"); - geoLite2CityLocationsEnLines.add("738927,en,AS,Asia,TR,Turkey,59," - + ""Tekirda\u011F",,,"Tekirda\u011F",,Europe/Istanbul"); - geoLite2CityLocationsEnLines.add("745169,en,AS,Asia,TR,Turkey,16," - + "Bursa,,,\u0130neg\u00F6l,,Europe/Istanbul"); - geoLite2CityLocationsEnLines.add("749748,en,AS,Asia,TR,Turkey,18," - + ""\u00C7ank\u0131r\u0131",,,"\u00C7ank\u0131r\u0131",," - + "Europe/Istanbul"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "46.1.133.0", "tr", "Turkey", - "K\u0131r\u015Fehir", "K\u0131r\u015Fehir", 39.1458f, 34.1639f, - null, null); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "46.196.12.0", "tr", "Turkey", - "Tekirda\u011F", "Tekirda\u011F", 40.9780f, 27.5085f, null, null); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "78.180.14.0", "tr", "Turkey", - "Bursa", "\u0130neg\u00F6l", 40.0781f, 29.5133f, null, null); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "81.215.1.0", "tr", "Turkey", - "\u00C7ank\u0131r\u0131", "\u00C7ank\u0131r\u0131", 40.6000f, - 33.6153f, null, null); - } - - @Test() - public void testLookupLocationLatvia() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("78.28.192.0/24,456202,458258,,0,0,," - + "56.5000,27.3167"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("456202,en,EU,Europe,LV,Latvia,REZ," - + "Rezekne,,,"R\u0113zekne",,Europe/Riga"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "78.28.192.0", "lv", "Latvia", - "Rezekne", "R\u0113zekne", 56.5000f, 27.3167f, null, null); - } - - @Test() - public void testLookupLocationAzerbaijan() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("94.20.148.0/24,585170,587116,,0,0,," - + "41.1919,47.1706"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("585170,en,AS,Asia,AZ,Azerbaijan," - + "SAK,"Shaki City",,,"\u015E\u01DDki",,Asia/Baku"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "94.20.148.0", "az", - "Azerbaijan", "Shaki City", "\u015E\u01DDki", 41.1919f, 47.1706f, - null, null); - } - - @Test() - public void testLookupLocationVietnam() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("115.78.92.0/23,1587976,1562822,,0,0," - + ",10.2333,106.3833"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("1587976,en,AS,Asia,VN,Vietnam,50," - + ""Tinh Ben Tre",,,"B\u1EBFn Tre",,Asia/Ho_Chi_Minh"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "115.78.92.0", "vn", - "Vietnam", "Tinh Ben Tre", "B\u1EBFn Tre", 10.2333f, 106.3833f, - null, null); - } - - @Test() - public void testLookupLocationJapan() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("113.154.131.0/24,1848333,1861060,,0," - + "0,1012236,35.8000,139.1833"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("1848333,en,AS,Asia,JP,Japan,13," - + ""T\u014Dky\u014D",,,Yokoo,,Asia/Tokyo"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "113.154.131.0", "jp", - "Japan", "T\u014Dky\u014D", "Yokoo", 35.8000f, 139.1833f, null, - null); - } - - @Test() - public void testLookupLocationDenmark() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("2.110.246.0/24,2625001,2623032,,0,0," - + "5970,54.8880,10.4112"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("2625001,en,EU,Europe,DK,Denmark,83," - + ""South Denmark",,,"\u00C6r\u00F8sk\u00F8bing",," - + "Europe/Copenhagen"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "2.110.246.0", "dk", - "Denmark", "South Denmark", "\u00C6r\u00F8sk\u00F8bing", 54.8880f, - 10.4112f, null, null); - } - - @Test() - public void testLookupLocationGermany() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("37.209.30.128/25,2947444,2921044,,0," - + "0,,48.6833,9.0167"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("2947444,en,EU,Europe,DE,Germany,BW," - + ""Baden-W\u00FCrttemberg Region",,,B\u00F6blingen,," - + "Europe/Berlin"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "37.209.30.128", "de", - "Germany", "Baden-W\u00FCrttemberg Region", "B\u00F6blingen", - 48.6833f, 9.0167f, null, null); - } - - @Test() - public void testLookupLocationPoland() { - List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); - geoLite2CityBlocksIPv4Lines.add("network,geoname_id," - + "registered_country_geoname_id,represented_country_geoname_id," - + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," - + "longitude"); - geoLite2CityBlocksIPv4Lines.add("5.185.94.0/24,3099434,798544,,0,0,," - + "54.3608,18.6583"); - List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); - geoLite2CityLocationsEnLines.add("geoname_id,locale_code," - + "continent_code,continent_name,country_iso_code,country_name," - + "subdivision_1_iso_code,subdivision_1_name," - + "subdivision_2_iso_code,subdivision_2_name,city_name," - + "metro_code,time_zone"); - geoLite2CityLocationsEnLines.add("3099434,en,EU,Europe,PL,Poland,PM," - + ""Pomeranian Voivodeship",,,"Gda\u0144sk",,Europe/Warsaw"); - this.assertLookupResult(geoLite2CityBlocksIPv4Lines, - geoLite2CityLocationsEnLines, null, "5.185.94.0", "pl", "Poland", - "Pomeranian Voivodeship", "Gda\u0144sk", 54.3608f, 18.6583f, null, - null); - } -} - diff --git a/src/test/java/org/torproject/onionoo/ResourceServletTest.java b/src/test/java/org/torproject/onionoo/ResourceServletTest.java deleted file mode 100644 index cc48295..0000000 --- a/src/test/java/org/torproject/onionoo/ResourceServletTest.java +++ /dev/null @@ -1,1383 +0,0 @@ -/* Copyright 2013 The Tor Project - * See LICENSE for licensing information */ - -package org.torproject.onionoo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.junit.Before; -import org.junit.Test; -import org.torproject.onionoo.docs.DateTimeHelper; -import org.torproject.onionoo.docs.DocumentStoreFactory; -import org.torproject.onionoo.docs.UpdateStatus; -import org.torproject.onionoo.server.HttpServletRequestWrapper; -import org.torproject.onionoo.server.HttpServletResponseWrapper; -import org.torproject.onionoo.server.NodeIndexer; -import org.torproject.onionoo.server.NodeIndexerFactory; -import org.torproject.onionoo.server.ResourceServlet; -import org.torproject.onionoo.util.Time; -import org.torproject.onionoo.util.TimeFactory; - -import com.google.gson.Gson; - -/* TODO This test class could (should?) be split into ResponseBuilderTest - * which tests ResponseBuilder and a much shorter ResourceServletTest - * which tests servlet specifics. */ -public class ResourceServletTest { - - private SortedMap<String, org.torproject.onionoo.docs.SummaryDocument> - relays, bridges; - - private long currentTimeMillis = DateTimeHelper.parse( - "2013-04-24 12:22:22"); - - private class TestingHttpServletRequestWrapper - extends HttpServletRequestWrapper { - private String requestURI; - private String queryString; - private Map<String, String[]> parameterMap; - private TestingHttpServletRequestWrapper(String requestURI, - String queryString, Map<String, String[]> parameterMap) { - super(null); - this.requestURI = requestURI; - this.queryString = queryString; - this.parameterMap = parameterMap == null - ? new HashMap<String, String[]>() : parameterMap; - } - protected String getRequestURI() { - return this.requestURI; - } - @SuppressWarnings("rawtypes") - protected Map getParameterMap() { - return this.parameterMap; - } - protected String[] getParameterValues(String parameterKey) { - return this.parameterMap.get(parameterKey); - } - protected String getQueryString() { - return this.queryString; - } - } - - private class TestingHttpServletResponseWrapper extends - HttpServletResponseWrapper { - private TestingHttpServletResponseWrapper() { - super(null); - } - private int errorStatusCode; - protected void sendError(int errorStatusCode) throws IOException { - this.errorStatusCode = errorStatusCode; - } - private Map<String, String> headers = new HashMap<String, String>(); - protected void setHeader(String headerName, String headerValue) { - this.headers.put(headerName, headerValue); - } - protected void setContentType(String contentType) { - } - protected void setCharacterEncoding(String characterEncoding) { - } - private StringWriter stringWriter; - protected PrintWriter getWriter() throws IOException { - if (this.stringWriter == null) { - this.stringWriter = new StringWriter(); - return new PrintWriter(this.stringWriter); - } else { - throw new IOException("Can only request writer once"); - } - } - private String getWrittenContent() { - return this.stringWriter == null ? null - : this.stringWriter.toString(); - } - } - - private TestingHttpServletRequestWrapper request; - - private TestingHttpServletResponseWrapper response; - - private String responseString; - - private SummaryDocument summaryDocument; - - @Before - public void createSampleRelaysAndBridges() { - org.torproject.onionoo.docs.SummaryDocument relayTorkaZ = - new org.torproject.onionoo.docs.SummaryDocument(true, "TorkaZ", - "000C5F55BD4814B917CC474BD537F1A3B33CCE2A", Arrays.asList( - new String[] { "62.216.201.221", "62.216.201.222", - "62.216.201.223" }), DateTimeHelper.parse("2013-04-19 05:00:00"), - false, new TreeSet<String>(Arrays.asList(new String[] { "Running", - "Valid" })), 20L, "de", - DateTimeHelper.parse("2013-04-18 05:00:00"), "AS8767", - "torkaz <klaus dot zufall at gmx dot de> " - + "fb-token:np5_g_83jmf=", new TreeSet<String>(Arrays.asList( - new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC", - "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B" }))); - org.torproject.onionoo.docs.SummaryDocument relayFerrari458 = - new org.torproject.onionoo.docs.SummaryDocument(true, "Ferrari458", - "001C13B3A55A71B977CA65EC85539D79C653A3FC", Arrays.asList( - new String[] { "68.38.171.200", "[2001:4f8:3:2e::51]" }), - DateTimeHelper.parse("2013-04-24 12:00:00"), true, - new TreeSet<String>(Arrays.asList(new String[] { "Fast", "Named", - "Running", "V2Dir", "Valid" })), 1140L, "us", - DateTimeHelper.parse("2013-02-12 16:00:00"), "AS7922", null, - new TreeSet<String>(Arrays.asList(new String[] { - "000C5F55BD4814B917CC474BD537F1A3B33CCE2A" }))); - org.torproject.onionoo.docs.SummaryDocument relayTimMayTribute = - new org.torproject.onionoo.docs.SummaryDocument(true, "TimMayTribute", - "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", Arrays.asList( - new String[] { "89.69.68.246" }), - DateTimeHelper.parse("2013-04-22 20:00:00"), false, - new TreeSet<String>(Arrays.asList(new String[] { "Fast", - "Running", "Unnamed", "V2Dir", "Valid" })), 63L, "a1", - DateTimeHelper.parse("2013-04-16 18:00:00"), "AS6830", - "1024D/51E2A1C7 steven j. murdoch " - + "tor+steven.murdoch@cl.cam.ac.uk fb-token:5sr_k_zs2wm=", - new TreeSet<String>()); - org.torproject.onionoo.docs.SummaryDocument bridgeec2bridgercc7f31fe = - new org.torproject.onionoo.docs.SummaryDocument(false, - "ec2bridgercc7f31fe", "0000831B236DFF73D409AD17B40E2A728A53994F", - Arrays.asList(new String[] { "10.199.7.176" }), - DateTimeHelper.parse("2013-04-21 18:07:03"), false, - new TreeSet<String>(Arrays.asList(new String[] { "Valid" })), -1L, - null, DateTimeHelper.parse("2013-04-20 15:37:04"), null, null, - null); - org.torproject.onionoo.docs.SummaryDocument bridgeUnnamed = - new org.torproject.onionoo.docs.SummaryDocument(false, "Unnamed", - "0002D9BDBBC230BD9C78FF502A16E0033EF87E0C", Arrays.asList( - new String[] { "10.0.52.84" }), - DateTimeHelper.parse("2013-04-20 17:37:04"), false, - new TreeSet<String>(Arrays.asList(new String[] { "Valid" })), -1L, - null, DateTimeHelper.parse("2013-04-14 07:07:05"), null, null, - null); - org.torproject.onionoo.docs.SummaryDocument bridgegummy = - new org.torproject.onionoo.docs.SummaryDocument(false, "gummy", - "1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", Arrays.asList( - new String[] { "10.63.169.98" }), - DateTimeHelper.parse("2013-04-24 01:07:04"), true, - new TreeSet<String>(Arrays.asList(new String[] { "Running", - "Valid" })), -1L, null, - DateTimeHelper.parse("2013-01-16 21:07:04"), null, null, null); - this.relays = - new TreeMap<String, org.torproject.onionoo.docs.SummaryDocument>(); - this.relays.put("000C5F55BD4814B917CC474BD537F1A3B33CCE2A", - relayTorkaZ); - this.relays.put("001C13B3A55A71B977CA65EC85539D79C653A3FC", - relayFerrari458); - this.relays.put("0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", - relayTimMayTribute); - this.bridges = - new TreeMap<String, org.torproject.onionoo.docs.SummaryDocument>(); - this.bridges.put("0000831B236DFF73D409AD17B40E2A728A53994F", - bridgeec2bridgercc7f31fe); - this.bridges.put("0002D9BDBBC230BD9C78FF502A16E0033EF87E0C", - bridgeUnnamed); - this.bridges.put("1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", - bridgegummy); - } - - private void runTest(String request) { - try { - this.createDummyTime(); - this.createDummyDocumentStore(); - this.createNodeIndexer(); - this.makeRequest(request); - this.parseResponse(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void createDummyTime() { - Time dummyTime = new DummyTime(this.currentTimeMillis); - TimeFactory.setTime(dummyTime); - } - - private void createDummyDocumentStore() { - DummyDocumentStore documentStore = new DummyDocumentStore(); - UpdateStatus updateStatus = new UpdateStatus(); - updateStatus.setUpdatedMillis(this.currentTimeMillis); - documentStore.addDocument(updateStatus, null); - for (Map.Entry<String, org.torproject.onionoo.docs.SummaryDocument> e : - this.relays.entrySet()) { - documentStore.addDocument(e.getValue(), e.getKey()); - } - for (Map.Entry<String, org.torproject.onionoo.docs.SummaryDocument> e : - this.bridges.entrySet()) { - documentStore.addDocument(e.getValue(), e.getKey()); - } - DocumentStoreFactory.setDocumentStore(documentStore); - } - - private void createNodeIndexer() { - NodeIndexer newNodeIndexer = new NodeIndexer(); - newNodeIndexer.startIndexing(); - NodeIndexerFactory.setNodeIndexer(newNodeIndexer); - } - - private void makeRequest(String request) throws IOException { - ResourceServlet rs = new ResourceServlet(); - String requestParts[] = request.split("\?"); - String path = requestParts[0]; - String queryString = requestParts.length > 1 ? requestParts[1] : null; - Map<String, String[]> parameterMap = parseParameters(request); - this.request = new TestingHttpServletRequestWrapper(path, queryString, - parameterMap); - this.response = new TestingHttpServletResponseWrapper(); - rs.doGet(this.request, this.response); - } - - private void parseResponse() { - this.responseString = this.response.getWrittenContent(); - if (this.responseString != null) { - Gson gson = new Gson(); - this.summaryDocument = gson.fromJson(this.responseString, - SummaryDocument.class); - } - } - - private void assertErrorStatusCode(String request, - int errorStatusCode) { - this.runTest(request); - assertEquals(errorStatusCode, this.response.errorStatusCode); - } - - private void assertSummaryDocument(String request, - int expectedRelaysNumber, String[] expectedRelaysNicknames, - int expectedBridgesNumber, String[] expectedBridgesNicknames) { - this.runTest(request); - assertNotNull(this.summaryDocument); - assertEquals(expectedRelaysNumber, - this.summaryDocument.relays.length); - if (expectedRelaysNicknames != null) { - for (int i = 0; i < expectedRelaysNumber; i++) { - assertEquals(expectedRelaysNicknames[i], - this.summaryDocument.relays[i].n); - } - } - assertEquals(expectedBridgesNumber, - this.summaryDocument.bridges.length); - if (expectedBridgesNicknames != null) { - for (int i = 0; i < expectedBridgesNumber; i++) { - assertEquals(expectedBridgesNicknames[i], - this.summaryDocument.bridges[i].n); - } - } - } - - private Map<String, String[]> parseParameters(String request) { - Map<String, String[]> parameters = null; - String[] uriParts = request.split("\?"); - if (uriParts.length == 2) { - Map<String, List<String>> parameterLists = - new HashMap<String, List<String>>(); - for (String parameter : uriParts[1].split("&")) { - String[] parameterParts = parameter.split("="); - if (!parameterLists.containsKey(parameterParts[0])) { - parameterLists.put(parameterParts[0], - new ArrayList<String>()); - } - parameterLists.get(parameterParts[0]).add(parameterParts[1]); - } - parameters = new HashMap<String, String[]>(); - for (Map.Entry<String, List<String>> e : - parameterLists.entrySet()) { - parameters.put(e.getKey(), - e.getValue().toArray(new String[e.getValue().size()])); - } - } - return parameters; - } - - private static class SummaryDocument { - private String relays_published; - private RelaySummary[] relays; - private String bridges_published; - private BridgeSummary[] bridges; - } - - private static class RelaySummary { - private String n; - private String f; - private String[] a; - private boolean r; - } - - private static class BridgeSummary { - private String n; - private String h; - private boolean r; - } - - @Test() - public void testValidSummaryRelay() throws IOException { - this.runTest("/summary"); - assertEquals("2013-04-24 12:00:00", - this.summaryDocument.relays_published); - assertEquals(3, this.summaryDocument.relays.length); - RelaySummary relay = null; - for (RelaySummary r : this.summaryDocument.relays) { - if (r.f.equals("000C5F55BD4814B917CC474BD537F1A3B33CCE2A")) { - relay = r; - break; - } - } - assertNotNull(relay); - assertEquals("TorkaZ", relay.n); - assertEquals(3, relay.a.length); - assertEquals("62.216.201.221", relay.a[0]); - assertFalse(relay.r); - } - - @Test() - public void testValidSummaryBridge() { - this.runTest("/summary"); - assertEquals("2013-04-24 01:07:04", - this.summaryDocument.bridges_published); - assertEquals(3, this.summaryDocument.bridges.length); - BridgeSummary bridge = null; - for (BridgeSummary b : this.summaryDocument.bridges) { - if (b.h.equals("0000831B236DFF73D409AD17B40E2A728A53994F")) { - bridge = b; - break; - } - } - assertNotNull(bridge); - assertEquals("ec2bridgercc7f31fe", bridge.n); - assertFalse(bridge.r); - } - - @Test() - public void testNonExistantDocumentType() { - this.assertErrorStatusCode( - "/doesnotexist", 400); - } - - @Test() - public void testSUMMARYDocument() { - this.assertErrorStatusCode( - "/SUMMARY", 400); - } - - @Test() - public void testTypeRelay() { - this.assertSummaryDocument( - "/summary?type=relay", 3, null, 0, null); - } - - @Test() - public void testTypeBridge() { - this.assertSummaryDocument( - "/summary?type=bridge", 0, null, 3, null); - } - - @Test() - public void testTypeBridgerelay() { - this.assertErrorStatusCode( - "/summary?type=bridgerelay", 400); - } - - @Test() - public void testTypeRelayBridge() { - this.assertSummaryDocument( - "/summary?type=relay&type=bridge", 3, null, 0, null); - } - - @Test() - public void testTypeBridgeRelay() { - this.assertSummaryDocument( - "/summary?type=bridge&type=relay", 0, null, 3, null); - } - - @Test() - public void testTypeRelayRelay() { - this.assertSummaryDocument( - "/summary?type=relay&type=relay", 3, null, 0, null); - } - - @Test() - public void testTYPERelay() { - this.assertErrorStatusCode( - "/summary?TYPE=relay", 400); - } - - @Test() - public void testTypeRELAY() { - this.assertSummaryDocument( - "/summary?type=RELAY", 3, null, 0, null); - } - - @Test() - public void testRunningTrue() { - this.assertSummaryDocument( - "/summary?running=true", 1, new String[] { "Ferrari458" }, 1, - new String[] { "gummy" }); - } - - @Test() - public void testRunningFalse() { - this.assertSummaryDocument( - "/summary?running=false", 2, null, 2, null); - } - - @Test() - public void testRunningTruefalse() { - this.assertErrorStatusCode( - "/summary?running=truefalse", 400); - } - - @Test() - public void testRunningTrueFalse() { - this.assertSummaryDocument( - "/summary?running=true&running=false", 1, - new String[] { "Ferrari458" }, 1, new String[] { "gummy" }); - } - - @Test() - public void testRunningFalseTrue() { - this.assertSummaryDocument( - "/summary?running=false&running=true", 2, null, 2, null); - } - - @Test() - public void testRunningTrueTrue() { - this.assertSummaryDocument( - "/summary?running=true&running=true", 1, - new String[] { "Ferrari458" }, 1, new String[] { "gummy" }); - } - - @Test() - public void testRUNNINGTrue() { - this.assertErrorStatusCode( - "/summary?RUNNING=true", 400); - } - - @Test() - public void testRunningTRUE() { - this.assertSummaryDocument( - "/summary?running=TRUE", 1, null, 1, null); - } - - @Test() - public void testSearchTorkaZ() { - this.assertSummaryDocument( - "/summary?search=TorkaZ", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchTorkaX() { - this.assertSummaryDocument( - "/summary?search=TorkaX", 0, null, 0, null); - } - - @Test() - public void testSearchOrkaZ() { - this.assertSummaryDocument( - "/summary?search=orkaZ", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchTorka() { - this.assertSummaryDocument( - "/summary?search=Torka", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchTORKAZ() { - this.assertSummaryDocument( - "/summary?search=TORKAZ", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarFingerprint() { - this.assertSummaryDocument( - "/summary?search=$000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchFingerprint() { - this.assertSummaryDocument( - "/summary?search=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarFingerprint39() { - this.assertSummaryDocument( - "/summary?search=$000C5F55BD4814B917CC474BD537F1A3B33CCE2", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarFingerprintLowerCase39() { - this.assertSummaryDocument( - "/summary?search=$000c5f55bd4814b917cc474bd537f1a3b33cce2", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchFingerprintLowerCase39() { - this.assertSummaryDocument( - "/summary?search=000c5f55bd4814b917cc474bd537f1a3b33cce2", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarHashedFingerprint() { - this.assertSummaryDocument( - "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94cee", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarHashedFingerprint39() { - this.assertSummaryDocument( - "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94ce", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchDollarHashedFingerprint41() { - this.assertErrorStatusCode( - "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94ceee", - 400); - } - - @Test() - public void testSearchBase64FingerprintAlphaNum() { - this.assertSummaryDocument( - "/summary?search=AAxfVb1IFLkXzEdL1Tfxo7M8zio", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchBase64FingerprintSlash() { - this.assertSummaryDocument( - "/summary?search=ABwTs6Vacbl3ymXshVOdecZTo/w", 1, - new String[] { "Ferrari458" }, 0, null); - } - - @Test() - public void testSearchBase64FingerprintPlus() { - this.assertSummaryDocument( - "/summary?search=ACXBNsHzqe7+KuP5GPA7+iG1Bws", 1, - new String[] { "TimMayTribute" }, 0, null); - } - - @Test() - public void testSearchBase64FingerprintBridge() { - this.assertSummaryDocument( - "/summary?search=AACDGyNt/3PUCa0XtA4qcopTmU8", 0, null, 0, null); - } - - @Test() - public void testSearchBase64FingerprintPartial() { - this.assertSummaryDocument( - "/summary?search=AAx", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchBase64HashedFingerprintTorkaZ() { - this.assertSummaryDocument( - "/summary?search=WqFMCNYpE+AFeprVhjtFjAzpTO4", 0, null, 0, null); - } - - @Test() - public void testSearchBase64Fingerprint28() { - this.assertErrorStatusCode( - "/summary?search=AAAAAAAAAAAA//AAAAAAAAAAAAAA", 400); - } - - @Test() - public void testSearchIp() { - this.assertSummaryDocument( - "/summary?search=62.216.201.221", 1, new String[] { "TorkaZ" }, 0, - null); - } - - @Test() - public void testSearchIp24Network() { - this.assertSummaryDocument( - "/summary?search=62.216.201", 1, new String[] { "TorkaZ" }, 0, - null); - } - - @Test() - public void testSearchIpExit() { - this.assertSummaryDocument( - "/summary?search=62.216.201.222", 1, new String[] { "TorkaZ" }, 0, - null); - } - - @Test() - public void testSearchIpv6() { - this.assertSummaryDocument( - "/summary?search=[2001:4f8:3:2e::51]", 1, - new String[] { "Ferrari458" }, 0, null); - } - - @Test() - public void testSearchIpv6Slash64NoTrailingBracket() { - this.assertSummaryDocument( - "/summary?search=[2001:4f8:3:2e::", 1, - new String[] { "Ferrari458" }, 0, null); - } - - @Test() - public void testSearchIpv6Slash64TrailingBracket() { - this.assertSummaryDocument( - "/summary?search=[2001:4f8:3:2e::]", 0, null, 0, null); - } - - @Test() - public void testSearchIpv6Uncompressed() { - this.assertSummaryDocument( - "/summary?search=[2001:04f8:0003:002e:0000:0000:0000:0051]", 0, - null, 0, null); - } - - @Test() - public void testSearchIpv6UpperCase() { - this.assertSummaryDocument( - "/summary?search=[2001:4F8:3:2E::51]", 1, - new String[] { "Ferrari458" }, 0, null); - } - - @Test() - public void testSearchIpv6ThreeColons() { - this.assertSummaryDocument( - "/summary?search=[2001:4f8:3:2e:::51]", 0, null, 0, null); - } - - @Test() - public void testSearchIpv6FiveHex() { - this.assertSummaryDocument( - "/summary?search=[20014:f80:3:2e::51]", 0, null, 0, null); - } - - @Test() - public void testSearchIpv6NineGroups() { - this.assertSummaryDocument( - "/summary?search=[1:2:3:4:5:6:7:8:9]", 0, null, 0, null); - } - - @Test() - public void testSearchIpv6TcpPort() { - this.assertErrorStatusCode( - "/summary?search=[2001:4f8:3:2e::51]:9001", 400); - } - - @Test() - public void testSearchGummy() { - this.assertSummaryDocument( - "/summary?search=gummy", 0, null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchGummi() { - this.assertSummaryDocument( - "/summary?search=gummi", 0, null, 0, null); - } - - @Test() - public void testSearchUmmy() { - this.assertSummaryDocument( - "/summary?search=ummy", 0, null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchGumm() { - this.assertSummaryDocument( - "/summary?search=gumm", 0, null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchGUMMY() { - this.assertSummaryDocument( - "/summary?search=GUMMY", 0, null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarHashedFingerprint() { - this.assertSummaryDocument( - "/summary?search=$1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeHashedFingerprint() { - this.assertSummaryDocument( - "/summary?search=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarHashedFingerprint39() { - this.assertSummaryDocument( - "/summary?search=$1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB75", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarHashedFingerprintLowerCase39() { - this.assertSummaryDocument( - "/summary?search=$1fede50ed8dba1dd9f9165f78c8131e4a44ab75", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeHashedFingerprintLowerCase39() { - this.assertSummaryDocument( - "/summary?search=1fede50ed8dba1dd9f9165f78c8131e4a44ab75", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarHashedHashedFingerprint() { - this.assertSummaryDocument( - "/summary?search=$CE52F898DB3678BCE33FAC28C92774DE90D618B5", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarHashedHashedFingerprint39() { - this.assertSummaryDocument( - "/summary?search=$CE52F898DB3678BCE33FAC28C92774DE90D618B", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testSearchBridgeDollarOriginalFingerprint() { - this.assertSummaryDocument( - "/summary?search=$0010D49C6DA1E46A316563099F41BFE40B6C7183", 0, - null, 0, null); - } - - @Test() - public void testSearchUnderscore() { - this.assertErrorStatusCode( - "/summary?search=_", 400); - } - - @Test() - public void testSearchTypeRelay() { - this.assertSummaryDocument("/summary?search=type:relay", 3, null, 0, - null); - } - - @Test() - public void testSearchTypeRelayTorkaZ() { - this.assertSummaryDocument("/summary?search=type:relay TorkaZ", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchTorkaZTypeRelay() { - this.assertSummaryDocument("/summary?search=TorkaZ type:relay", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testSearchTypeRelayTypeDirectory() { - this.assertSummaryDocument( - "/summary?search=type:relay type:directory", 3, null, 0, null); - } - - @Test() - public void testSearchTypeDirectoryTypeRelay() { - this.assertErrorStatusCode( - "/summary?search=type:directory type:relay", 400); - } - - @Test() - public void testSearchFooBar() { - this.assertErrorStatusCode("/summary?search=foo:bar", 400); - } - - @Test() - public void testSearchSearchTorkaZ() { - this.assertErrorStatusCode("/summary?search=search:TorkaZ", 400); - } - - @Test() - public void testSearchLimitOne() { - this.assertErrorStatusCode("/summary?search=limit:1", 400); - } - - @Test() - public void testLookupFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testLookupDollarFingerprint() { - this.assertErrorStatusCode( - "/summary?lookup=$000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 400); - } - - @Test() - public void testLookupDollarFingerprint39() { - this.assertErrorStatusCode( - "/summary?lookup=$000C5F55BD4814B917CC474BD537F1A3B33CCE2", 400); - } - - @Test() - public void testLookupFingerprintLowerCase39() { - this.assertErrorStatusCode( - "/summary?lookup=000c5f55bd4814b917cc474bd537f1a3b33cce2", 400); - } - - @Test() - public void testLookupHashedFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=5aa14c08d62913e0057a9ad5863b458c0ce94cee", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testLookupBridgeHashedFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testLookupBridgeHashedHashedFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=CE52F898DB3678BCE33FAC28C92774DE90D618B5", 0, - null, 1, new String[] { "gummy" }); - } - - @Test() - public void testLookupBridgeOriginalFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=0010D49C6DA1E46A316563099F41BFE40B6C7183", 0, - null, 0, null); - } - - @Test() - public void testLookupNonExistantFingerprint() { - this.assertSummaryDocument( - "/summary?lookup=0000000000000000000000000000000000000000", 0, - null, 0, null); - } - - @Test() - public void testFingerprintRelayFingerprint() { - this.assertSummaryDocument( - "/summary?fingerprint=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", - 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testFingerprintRelayHashedFingerprint() { - this.assertSummaryDocument( - "/summary?fingerprint=5aa14c08d62913e0057a9ad5863b458c0ce94cee", - 0, null, 0, null); - } - - @Test() - public void testFingerprintBridgeHashedFingerprint() { - this.assertSummaryDocument( - "/summary?fingerprint=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", - 0, null, 1, new String[] { "gummy" }); - } - - @Test() - public void testFingerprintBridgeHashedHashedFingerprint() { - this.assertSummaryDocument( - "/summary?fingerprint=CE52F898DB3678BCE33FAC28C92774DE90D618B5", - 0, null, 0, null); - } - - @Test() - public void testFingerprintBridgeOriginalFingerprint() { - this.assertSummaryDocument( - "/summary?fingerprint=0010D49C6DA1E46A316563099F41BFE40B6C7183", - 0, null, 0, null); - } - - @Test() - public void testCountryDe() { - this.assertSummaryDocument( - "/summary?country=de", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testCountryFr() { - this.assertSummaryDocument( - "/summary?country=fr", 0, null, 0, null); - } - - @Test() - public void testCountryZz() { - this.assertSummaryDocument( - "/summary?country=zz", 0, null, 0, null); - } - - @Test() - public void testCountryDE() { - this.assertSummaryDocument( - "/summary?country=DE", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testCountryDeu() { - this.assertErrorStatusCode( - "/summary?country=deu", 400); - } - - @Test() - public void testCountryD() { - this.assertErrorStatusCode( - "/summary?country=d", 400); - } - - @Test() - public void testCountryA1() { - this.assertSummaryDocument( - "/summary?country=a1", 1, new String[] { "TimMayTribute" }, 0, - null); - } - - @Test() - public void testCountryDeDe() { - this.assertSummaryDocument( - "/summary?country=de&country=de", 1, new String[] { "TorkaZ" }, 0, - null); - } - - @Test() - public void testAsAS8767() { - this.assertSummaryDocument( - "/summary?as=AS8767", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testAs8767() { - this.assertSummaryDocument( - "/summary?as=8767", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testAsAS() { - this.assertErrorStatusCode( - "/summary?as=AS", 400); - } - - @Test() - public void testAsas8767() { - this.assertSummaryDocument( - "/summary?as=as8767", 1, new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testAsASSpace8767() { - this.assertErrorStatusCode( - "/summary?as=AS 8767", 400); - } - - @Test() - public void testFlagRunning() { - this.assertSummaryDocument( - "/summary?flag=Running", 3, null, 1, null); - } - - @Test() - public void testFlagValid() { - this.assertSummaryDocument( - "/summary?flag=Valid", 3, null, 3, null); - } - - @Test() - public void testFlagFast() { - this.assertSummaryDocument( - "/summary?flag=Fast", 2, null, 0, null); - } - - @Test() - public void testFlagNamed() { - this.assertSummaryDocument( - "/summary?flag=Named", 1, null, 0, null); - } - - @Test() - public void testFlagUnnamed() { - this.assertSummaryDocument( - "/summary?flag=Unnamed", 1, null, 0, null); - } - - @Test() - public void testFlagV2Dir() { - this.assertSummaryDocument( - "/summary?flag=V2Dir", 2, null, 0, null); - } - - @Test() - public void testFlagGuard() { - this.assertSummaryDocument( - "/summary?flag=Guard", 0, null, 0, null); - } - - @Test() - public void testFlagCool() { - this.assertSummaryDocument( - "/summary?flag=Cool", 0, null, 0, null); - } - - @Test() - public void testFirstSeenDaysZeroToTwo() { - this.assertSummaryDocument( - "/summary?first_seen_days=0-2", 0, null, 0, null); - } - - @Test() - public void testFirstSeenDaysUpToThree() { - this.assertSummaryDocument( - "/summary?first_seen_days=-3", 0, null, 1, null); - } - - @Test() - public void testFirstSeenDaysThree() { - this.assertSummaryDocument( - "/summary?first_seen_days=3", 0, null, 1, null); - } - - @Test() - public void testFirstSeenDaysTwoToFive() { - this.assertSummaryDocument( - "/summary?first_seen_days=2-5", 0, null, 1, null); - } - - @Test() - public void testFirstSeenDaysSixToSixteen() { - this.assertSummaryDocument( - "/summary?first_seen_days=6-16", 2, null, 1, null); - } - - @Test() - public void testFirstSeenDaysNinetysevenOrMore() { - this.assertSummaryDocument( - "/summary?first_seen_days=97-", 0, null, 1, null); - } - - @Test() - public void testFirstSeenDaysNinetyeightOrMore() { - this.assertSummaryDocument( - "/summary?first_seen_days=98-", 0, null, 0, null); - } - - @Test() - public void testFirstSeenDaysDashDash() { - this.assertErrorStatusCode( - "/summary?first_seen_days=--", 400); - } - - @Test() - public void testFirstSeenDaysDashOneDash() { - this.assertErrorStatusCode( - "/summary?first_seen_days=-1-", 400); - } - - @Test() - public void testFirstSeenDaysZeroDotDotOne() { - this.assertErrorStatusCode( - "/summary?first_seen_days=0..1", 400); - } - - @Test() - public void testFirstSeenDaysElevenDigits() { - this.assertErrorStatusCode( - "/summary?first_seen_days=12345678901", 400); - } - - @Test() - public void testFirstSeenDaysLargeTenDigitNumber() { - this.assertErrorStatusCode( - "/summary?first_seen_days=9999999999", 400); - } - - @Test() - public void testFirstSeenDaysMaxInt() { - this.assertSummaryDocument( - "/summary?last_seen_days=" + String.valueOf(Integer.MAX_VALUE), 0, - null, 0, null); - } - - @Test() - public void testFirstSeenDaysMaxIntPlusOne() { - this.assertErrorStatusCode( - "/summary?first_seen_days=" - + String.valueOf(Integer.MAX_VALUE + 1), 400); - } - - @Test() - public void testLastSeenDaysZero() { - this.assertSummaryDocument( - "/summary?last_seen_days=0", 1, null, 1, null); - } - - @Test() - public void testLastSeenDaysUpToZero() { - this.assertSummaryDocument( - "/summary?last_seen_days=-0", 1, null, 1, null); - } - - @Test() - public void testLastSeenDaysOneToThree() { - this.assertSummaryDocument( - "/summary?last_seen_days=1-3", 1, null, 2, null); - } - - @Test() - public void testLastSeenDaysSixOrMore() { - this.assertSummaryDocument( - "/summary?last_seen_days=6-", 0, null, 0, null); - } - - @Test() - public void testContactSteven() { - this.assertSummaryDocument( - "/summary?contact=Steven", 1, null, 0, null); - } - - @Test() - public void testContactStevenMurdoch() { - this.assertSummaryDocument( - "/summary?contact=Steven Murdoch", 1, null, 0, null); - } - - @Test() - public void testContactMurdochSteven() { - this.assertSummaryDocument( - "/summary?contact=Murdoch Steven", 1, null, 0, null); - } - - @Test() - public void testContactStevenDotMurdoch() { - this.assertSummaryDocument( - "/summary?contact=Steven.Murdoch", 1, null, 0, null); - } - - @Test() - public void testContactFbTokenFive() { - this.assertSummaryDocument( - "/summary?contact=fb-token:5sR_K_zs2wM=", 1, null, 0, null); - } - - @Test() - public void testContactFbToken() { - this.assertSummaryDocument( - "/summary?contact=<fb-token:", 2, null, 0, null); - } - - @Test() - public void testContactDash() { - this.assertSummaryDocument( - "/summary?contact=-", 2, null, 0, null); - } - - @Test() - public void testOrderConsensusWeightAscending() { - this.assertSummaryDocument( - "/summary?order=consensus_weight", 3, - new String[] { "TorkaZ", "TimMayTribute", "Ferrari458" }, 3, - null); - } - - @Test() - public void testOrderConsensusWeightDescending() { - this.assertSummaryDocument( - "/summary?order=-consensus_weight", 3, - new String[] { "Ferrari458", "TimMayTribute", "TorkaZ" }, 3, - null); - } - - @Test() - public void testOrderConsensusWeightAscendingTwice() { - this.assertErrorStatusCode( - "/summary?order=consensus_weight,consensus_weight", 400); - } - - @Test() - public void testOrderConsensusWeightAscendingThenDescending() { - this.assertErrorStatusCode( - "/summary?order=consensus_weight,-consensus_weight", 400); - } - - @Test() - public void testOrderConsensusWeightThenNickname() { - this.assertErrorStatusCode( - "/summary?order=consensus_weight,nickname", 400); - } - - @Test() - public void testOrderCONSENSUS_WEIGHT() { - this.assertSummaryDocument( - "/summary?order=CONSENSUS_WEIGHT", 3, - new String[] { "TorkaZ", "TimMayTribute", "Ferrari458" }, 3, - null); - } - - @Test() - public void testOrderConsensusWeightAscendingLimit1() { - this.assertSummaryDocument( - "/summary?order=consensus_weight&limit=1", 1, - new String[] { "TorkaZ" }, 0, null); - } - - @Test() - public void testOrderConsensusWeightDecendingLimit1() { - this.assertSummaryDocument( - "/summary?order=-consensus_weight&limit=1", 1, - new String[] { "Ferrari458" }, 0, null); - } - - @Test() - public void testOffsetOne() { - this.assertSummaryDocument( - "/summary?offset=1", 2, null, 3, null); - } - - @Test() - public void testOffsetAllRelays() { - this.assertSummaryDocument( - "/summary?offset=3", 0, null, 3, null); - } - - @Test() - public void testOffsetAllRelaysAndOneBridge() { - this.assertSummaryDocument( - "/summary?offset=4", 0, null, 2, null); - } - - @Test() - public void testOffsetAllRelaysAndAllBridges() { - this.assertSummaryDocument( - "/summary?offset=6", 0, null, 0, null); - } - - @Test() - public void testOffsetMoreThanAllRelaysAndAllBridges() { - this.assertSummaryDocument( - "/summary?offset=7", 0, null, 0, null); - } - - @Test() - public void testOffsetZero() { - this.assertSummaryDocument( - "/summary?offset=0", 3, null, 3, null); - } - - @Test() - public void testOffsetMinusOne() { - this.assertSummaryDocument( - "/summary?offset=-1", 3, null, 3, null); - } - - @Test() - public void testOffsetOneWord() { - this.assertErrorStatusCode( - "/summary?offset=one", 400); - } - - @Test() - public void testLimitOne() { - this.assertSummaryDocument( - "/summary?limit=1", 1, null, 0, null); - } - - @Test() - public void testLimitAllRelays() { - this.assertSummaryDocument( - "/summary?limit=3", 3, null, 0, null); - } - - @Test() - public void testLimitAllRelaysAndOneBridge() { - this.assertSummaryDocument( - "/summary?limit=4", 3, null, 1, null); - } - - @Test() - public void testLimitAllRelaysAndAllBridges() { - this.assertSummaryDocument( - "/summary?limit=6", 3, null, 3, null); - } - - @Test() - public void testLimitMoreThanAllRelaysAndAllBridges() { - this.assertSummaryDocument( - "/summary?limit=7", 3, null, 3, null); - } - - @Test() - public void testLimitZero() { - this.assertSummaryDocument( - "/summary?limit=0", 0, null, 0, null); - } - - @Test() - public void testLimitMinusOne() { - this.assertSummaryDocument( - "/summary?limit=-1", 0, null, 0, null); - } - - @Test() - public void testLimitOneWord() { - this.assertErrorStatusCode( - "/summary?limit=one", 400); - } - - @Test() - public void testFamilyTorkaZ() { - this.assertSummaryDocument( - "/summary?family=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 2, - null, 0, null); - } - - @Test() - public void testFamilyFerrari458() { - this.assertSummaryDocument( - "/summary?family=001C13B3A55A71B977CA65EC85539D79C653A3FC", 2, - null, 0, null); - } - - @Test() - public void testFamilyTimMayTribute() { - this.assertSummaryDocument( - "/summary?family=0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", 1, - null, 0, null); - } - - @Test() - public void testFamilyBridgegummy() { - this.assertSummaryDocument( - "/summary?family=0000831B236DFF73D409AD17B40E2A728A53994F", 0, - null, 0, null); - } - - @Test() - public void testFamily39Characters() { - this.assertErrorStatusCode( - "/summary?family=00000000000000000000000000000000000000", 400); - } -} - diff --git a/src/test/java/org/torproject/onionoo/UptimeDocumentWriterTest.java b/src/test/java/org/torproject/onionoo/UptimeDocumentWriterTest.java deleted file mode 100644 index 8f7fff0..0000000 --- a/src/test/java/org/torproject/onionoo/UptimeDocumentWriterTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.torproject.onionoo.docs.DateTimeHelper; -import org.torproject.onionoo.docs.DocumentStoreFactory; -import org.torproject.onionoo.docs.GraphHistory; -import org.torproject.onionoo.docs.UptimeDocument; -import org.torproject.onionoo.docs.UptimeStatus; -import org.torproject.onionoo.updater.DescriptorSourceFactory; -import org.torproject.onionoo.util.TimeFactory; -import org.torproject.onionoo.writer.UptimeDocumentWriter; - -public class UptimeDocumentWriterTest { - - private static final long TEST_TIME = DateTimeHelper.parse( - "2014-03-23 12:00:00"); - - private DummyTime dummyTime; - - @Before - public void createDummyTime() { - this.dummyTime = new DummyTime(TEST_TIME); - TimeFactory.setTime(this.dummyTime); - } - - private DummyDescriptorSource descriptorSource; - - @Before - public void createDummyDescriptorSource() { - this.descriptorSource = new DummyDescriptorSource(); - DescriptorSourceFactory.setDescriptorSource(this.descriptorSource); - } - - private DummyDocumentStore documentStore; - - @Before - public void createDummyDocumentStore() { - this.documentStore = new DummyDocumentStore(); - DocumentStoreFactory.setDocumentStore(this.documentStore); - } - - @Test - public void testNoStatuses() { - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - writer.writeDocuments(); - assertEquals("Without providing any data, nothing should be written " - + "to disk.", 0, - this.documentStore.getPerformedStoreOperations()); - } - - private static final String ALL_RELAYS_FINGERPRINT = null; - - private static final String GABELMOO_FINGERPRINT = - "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281"; - - private void addStatusOneWeekSample(String allRelaysUptime, - String gabelmooUptime) { - UptimeStatus status = new UptimeStatus(); - status.setFromDocumentString(allRelaysUptime); - this.documentStore.addDocument(status, ALL_RELAYS_FINGERPRINT); - status = new UptimeStatus(); - status.setFromDocumentString(gabelmooUptime); - this.documentStore.addDocument(status, GABELMOO_FINGERPRINT); - } - - private static final long ONE_SECOND = 1000L, - ONE_HOUR = 60L * 60L * ONE_SECOND, FOUR_HOURS = 4L * ONE_HOUR; - - private void assertOneWeekGraph(UptimeDocument document, int graphs, - String first, String last, int count, List<Integer> values) { - this.assertGraph(document, graphs, "1_week", first, last, - (int) (ONE_HOUR / ONE_SECOND), count, values); - } - - private void assertOneMonthGraph(UptimeDocument document, int graphs, - String first, String last, int count, List<Integer> values) { - this.assertGraph(document, graphs, "1_month", first, last, - (int) (FOUR_HOURS / ONE_SECOND), count, values); - } - - private void assertGraph(UptimeDocument document, int graphs, - String graphName, String first, String last, int interval, - int count, List<Integer> values) { - assertEquals("Should contain exactly " + graphs + " graphs.", graphs, - document.getUptime().size()); - assertTrue("Should contain a graph for " + graphName + ".", - document.getUptime().containsKey(graphName)); - GraphHistory history = document.getUptime().get(graphName); - assertEquals("First data point should be " + first + ".", - DateTimeHelper.parse(first), history.getFirst()); - assertEquals("Last data point should be " + last + ".", - DateTimeHelper.parse(last), history.getLast()); - assertEquals("Interval should be " + interval + " seconds.", interval, - (int) history.getInterval()); - assertEquals("Factor should be 1.0 / 999.0.", 1.0 / 999.0, - (double) history.getFactor(), 0.01); - assertEquals("There should be one data point per hour.", count, - (int) history.getCount()); - assertEquals("Count should be the same as the number of values.", - count, history.getValues().size()); - if (values == null) { - for (int value : history.getValues()) { - assertEquals("All values should be 999.", 999, value); - } - } else { - assertEquals("Values are not as expected.", values, - history.getValues()); - } - } - - @Test - public void testOneHourUptime() { - this.addStatusOneWeekSample("r 2014-03-23-11 1\n", - "r 2014-03-23-11 1\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - assertEquals("Should not contain any graph.", 0, - document.getUptime().size()); - } - - @Test - public void testTwoHoursUptime() { - this.addStatusOneWeekSample("r 2014-03-23-10 2\n", - "r 2014-03-23-10 2\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneWeekGraph(document, 1, "2014-03-23 10:30:00", - "2014-03-23 11:30:00", 2, null); - } - - @Test - public void testTwoHoursUptimeSeparatedByNull() { - this.addStatusOneWeekSample("r 2014-03-23-09 1\nr 2014-03-23-11 1\n", - "r 2014-03-23-09 1\nr 2014-03-23-11 1\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - assertEquals("Should not contain any graph.", 0, - document.getUptime().size()); - } - - @Test - public void testTwoHoursUptimeSeparatedByZero() { - this.addStatusOneWeekSample("r 2014-03-23-09 3\n", - "r 2014-03-23-09 1\nr 2014-03-23-11 1\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneWeekGraph(document, 1, "2014-03-23 09:30:00", - "2014-03-23 11:30:00", 3, - Arrays.asList(new Integer[] { 999, 0, 999 })); - } - - @Test - public void testTwoHoursUptimeThenDowntime() { - this.addStatusOneWeekSample("r 2014-03-23-09 3\n", - "r 2014-03-23-09 2\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneWeekGraph(document, 1, "2014-03-23 09:30:00", - "2014-03-23 11:30:00", 3, - Arrays.asList(new Integer[] { 999, 999, 0 })); - } - - @Test - public void testOneWeekUptime() { - this.addStatusOneWeekSample("r 2014-03-16-12 168\n", - "r 2014-03-16-12 168\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneWeekGraph(document, 1, "2014-03-16 12:30:00", - "2014-03-23 11:30:00", 168, null); - } - - @Test - public void testOneWeekOneHourUptime() { - this.addStatusOneWeekSample("r 2014-03-16-11 169\n", - "r 2014-03-16-11 169\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneWeekGraph(document, 2, "2014-03-16 12:30:00", - "2014-03-23 11:30:00", 168, null); - this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", - "2014-03-23 10:00:00", 43, null); - } - - @Test - public void testOneMonthPartialIntervalOnline() { - this.addStatusOneWeekSample("r 2014-03-16-08 8\n", - "r 2014-03-16-11 5\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", - "2014-03-16 14:00:00", 2, null); - } - - @Test - public void testOneMonthPartialIntervalOnOff() { - this.addStatusOneWeekSample("r 2014-03-16-08 8\n", - "r 2014-03-16-10 1\nr 2014-03-16-12 1\n"); - UptimeDocumentWriter writer = new UptimeDocumentWriter(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - writer.writeDocuments(); - assertEquals("Should write exactly one document.", 1, - this.documentStore.getPerformedStoreOperations()); - UptimeDocument document = this.documentStore.getDocument( - UptimeDocument.class, GABELMOO_FINGERPRINT); - this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", - "2014-03-16 14:00:00", 2, - Arrays.asList(new Integer[] { 499, 249 })); - } -} - diff --git a/src/test/java/org/torproject/onionoo/UptimeStatusUpdaterTest.java b/src/test/java/org/torproject/onionoo/UptimeStatusUpdaterTest.java deleted file mode 100644 index b418879..0000000 --- a/src/test/java/org/torproject/onionoo/UptimeStatusUpdaterTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright 2014 The Tor Project - * See LICENSE for licensing information */ -package org.torproject.onionoo; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; -import org.torproject.onionoo.docs.DateTimeHelper; -import org.torproject.onionoo.docs.DocumentStoreFactory; -import org.torproject.onionoo.docs.UptimeHistory; -import org.torproject.onionoo.docs.UptimeStatus; -import org.torproject.onionoo.updater.DescriptorSourceFactory; -import org.torproject.onionoo.updater.DescriptorType; -import org.torproject.onionoo.updater.UptimeStatusUpdater; - -public class UptimeStatusUpdaterTest { - - private DummyDescriptorSource descriptorSource; - - @Before - public void createDummyDescriptorSource() { - this.descriptorSource = new DummyDescriptorSource(); - DescriptorSourceFactory.setDescriptorSource(this.descriptorSource); - } - - private DummyDocumentStore documentStore; - - @Before - public void createDummyDocumentStore() { - this.documentStore = new DummyDocumentStore(); - DocumentStoreFactory.setDocumentStore(this.documentStore); - } - - @Test - public void testNoDescriptorsNoStatusFiles() { - UptimeStatusUpdater updater = new UptimeStatusUpdater(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - updater.updateStatuses(); - assertEquals("Without providing any data, nothing should be written " - + "to disk.", 0, - this.documentStore.getPerformedStoreOperations()); - } - - private static final long VALID_AFTER_SAMPLE = - DateTimeHelper.parse("2014-03-21 20:00:00"); - - private static final String GABELMOO_FINGERPRINT = - "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281"; - - private void addConsensusSample() { - DummyStatusEntry statusEntry = new DummyStatusEntry( - GABELMOO_FINGERPRINT); - statusEntry.addFlag("Running"); - DummyConsensus consensus = new DummyConsensus(); - consensus.setValidAfterMillis(VALID_AFTER_SAMPLE); - consensus.addStatusEntry(statusEntry); - this.descriptorSource.addDescriptor(DescriptorType.RELAY_CONSENSUSES, - consensus); - } - - @Test - public void testOneConsensusNoStatusFiles() { - this.addConsensusSample(); - UptimeStatusUpdater updater = new UptimeStatusUpdater(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - updater.updateStatuses(); - assertEquals("Two status files should have been written to disk.", - 2, this.documentStore.getPerformedStoreOperations()); - for (String fingerprint : new String[] { GABELMOO_FINGERPRINT, - null }) { - UptimeStatus status = this.documentStore.getDocument( - UptimeStatus.class, fingerprint); - UptimeHistory history = status.getRelayHistory().first(); - assertEquals("History must contain one entry.", 1, - status.getRelayHistory().size()); - assertEquals("History not for relay.", true, history.isRelay()); - assertEquals("History start millis not as expected.", - VALID_AFTER_SAMPLE, history.getStartMillis()); - assertEquals("History uptime hours must be 1.", 1, - history.getUptimeHours()); - } - } - - private static final String ALL_RELAYS_AND_BRIDGES_FINGERPRINT = null; - - private static final String ALL_RELAYS_AND_BRIDGES_UPTIME_SAMPLE = - "r 2013-07-22-17 5811\n" /* ends 2014-03-21 20:00:00 */ - + "b 2013-07-22-17 5811\n"; /* ends 2014-03-21 20:00:00 */ - - private void addAllRelaysAndBridgesUptimeSample() { - UptimeStatus uptimeStatus = new UptimeStatus(); - uptimeStatus.setFromDocumentString( - ALL_RELAYS_AND_BRIDGES_UPTIME_SAMPLE); - this.documentStore.addDocument(uptimeStatus, - ALL_RELAYS_AND_BRIDGES_FINGERPRINT); - } - - @Test - public void testOneConsensusOneStatusFiles() { - this.addAllRelaysAndBridgesUptimeSample(); - this.addConsensusSample(); - UptimeStatusUpdater updater = new UptimeStatusUpdater(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - updater.updateStatuses(); - assertEquals("Two status files should have been written to disk.", - 2, this.documentStore.getPerformedStoreOperations()); - UptimeStatus status = this.documentStore.getDocument( - UptimeStatus.class, ALL_RELAYS_AND_BRIDGES_FINGERPRINT); - assertEquals("Relay history must contain one entry", 1, - status.getRelayHistory().size()); - UptimeHistory history = status.getRelayHistory().first(); - assertEquals("History not for relay.", true, history.isRelay()); - assertEquals("History start millis not as expected.", - DateTimeHelper.parse("2013-07-22 17:00:00"), - history.getStartMillis()); - assertEquals("History uptime hours must be 5812.", 5812, - history.getUptimeHours()); - } - - private static final long PUBLISHED_SAMPLE = - DateTimeHelper.parse("2014-03-21 20:37:03"); - - private static final String NDNOP2_FINGERPRINT = - "DE6397A047ABE5F78B4C87AF725047831B221AAB"; - - private void addBridgeStatusSample() { - DummyStatusEntry statusEntry = new DummyStatusEntry( - NDNOP2_FINGERPRINT); - statusEntry.addFlag("Running"); - DummyBridgeStatus bridgeStatus = new DummyBridgeStatus(); - bridgeStatus.setPublishedMillis(PUBLISHED_SAMPLE); - bridgeStatus.addStatusEntry(statusEntry); - this.descriptorSource.addDescriptor(DescriptorType.BRIDGE_STATUSES, - bridgeStatus); - } - - @Test - public void testOneBridgeStatusNoStatusFiles() { - this.addBridgeStatusSample(); - UptimeStatusUpdater updater = new UptimeStatusUpdater(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - updater.updateStatuses(); - assertEquals("Two status files should have been written to disk.", - 2, this.documentStore.getPerformedStoreOperations()); - for (String fingerprint : new String[] { NDNOP2_FINGERPRINT, - null }) { - UptimeStatus status = this.documentStore.getDocument( - UptimeStatus.class, fingerprint); - UptimeHistory history = status.getBridgeHistory().first(); - assertEquals("Bridge history must contain one entry.", 1, - status.getBridgeHistory().size()); - assertEquals("History not for bridge.", false, history.isRelay()); - assertEquals("History start millis not as expected.", - DateTimeHelper.parse("2014-03-21 20:00:00"), - history.getStartMillis()); - assertEquals("History uptime hours must be 1.", 1, - history.getUptimeHours()); - } - } - - @Test - public void testOneBridgeStatusOneStatusFiles() { - this.addAllRelaysAndBridgesUptimeSample(); - this.addBridgeStatusSample(); - UptimeStatusUpdater updater = new UptimeStatusUpdater(); - DescriptorSourceFactory.getDescriptorSource().readDescriptors(); - updater.updateStatuses(); - assertEquals("Two status files should have been written to disk.", - 2, this.documentStore.getPerformedStoreOperations()); - UptimeStatus status = this.documentStore.getDocument( - UptimeStatus.class, ALL_RELAYS_AND_BRIDGES_FINGERPRINT); - assertEquals("Bridge history must contain one entry.", 1, - status.getBridgeHistory().size()); - UptimeHistory history = status.getBridgeHistory().last(); - assertEquals("History not for bridge.", false, history.isRelay()); - assertEquals("History start millis not as expected.", - DateTimeHelper.parse("2013-07-22 17:00:00"), - history.getStartMillis()); - assertEquals("History uptime hours must be 5812.", 5812, - history.getUptimeHours()); - } -} - diff --git a/src/test/java/org/torproject/onionoo/docs/BandwidthStatusTest.java b/src/test/java/org/torproject/onionoo/docs/BandwidthStatusTest.java index b943d34..96988d1 100644 --- a/src/test/java/org/torproject/onionoo/docs/BandwidthStatusTest.java +++ b/src/test/java/org/torproject/onionoo/docs/BandwidthStatusTest.java @@ -12,7 +12,7 @@ import java.util.TreeMap; import org.junit.Before; import org.junit.Test; import org.torproject.descriptor.BandwidthHistory; -import org.torproject.onionoo.DummyTime; +import org.torproject.onionoo.util.DummyTime; import org.torproject.onionoo.util.TimeFactory;
public class BandwidthStatusTest { diff --git a/src/test/java/org/torproject/onionoo/docs/DummyDocumentStore.java b/src/test/java/org/torproject/onionoo/docs/DummyDocumentStore.java new file mode 100644 index 0000000..aa987a1 --- /dev/null +++ b/src/test/java/org/torproject/onionoo/docs/DummyDocumentStore.java @@ -0,0 +1,120 @@ +package org.torproject.onionoo.docs; + +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.torproject.onionoo.docs.Document; +import org.torproject.onionoo.docs.DocumentStore; + +public class DummyDocumentStore extends DocumentStore { + + private Map<Class<? extends Document>, SortedMap<String, Document>> + storedDocuments = new HashMap<Class<? extends Document>, + SortedMap<String, Document>>(); + + private static final String FINGERPRINT_NULL = ""; + + private <T extends Document> SortedMap<String, Document> + getStoredDocumentsByClass(Class<T> documentType) { + if (!this.storedDocuments.containsKey(documentType)) { + this.storedDocuments.put(documentType, + new TreeMap<String, Document>()); + } + return this.storedDocuments.get(documentType); + } + + public <T extends Document> void addDocument(T document, + String fingerprint) { + this.getStoredDocumentsByClass(document.getClass()).put( + fingerprint == null ? FINGERPRINT_NULL : fingerprint, document); + } + + public <T extends Document> T getDocument(Class<T> documentType, + String fingerprint) { + return documentType.cast(this.getStoredDocumentsByClass(documentType). + get(fingerprint == null ? FINGERPRINT_NULL : fingerprint)); + } + + public void flushDocumentCache() { + /* Nothing to do. */ + } + + public String getStatsString() { + /* No statistics to return. */ + return null; + } + + private int performedListOperations = 0; + public int getPerformedListOperations() { + return this.performedListOperations; + } + + public <T extends Document> SortedSet<String> list( + Class<T> documentType, long modifiedAfter) { + return this.list(documentType); + } + + public <T extends Document> SortedSet<String> list( + Class<T> documentType) { + this.performedListOperations++; + SortedSet<String> fingerprints = new TreeSet<String>( + this.getStoredDocumentsByClass(documentType).keySet()); + fingerprints.remove(FINGERPRINT_NULL); + return fingerprints; + } + + private int performedRemoveOperations = 0; + public int getPerformedRemoveOperations() { + return this.performedRemoveOperations; + } + + public <T extends Document> boolean remove(Class<T> documentType) { + return this.remove(documentType, null); + } + + public <T extends Document> boolean remove(Class<T> documentType, + String fingerprint) { + this.performedRemoveOperations++; + return this.getStoredDocumentsByClass(documentType).remove( + fingerprint) != null; + } + + private int performedRetrieveOperations = 0; + public int getPerformedRetrieveOperations() { + return this.performedRetrieveOperations; + } + + public <T extends Document> T retrieve(Class<T> documentType, + boolean parse) { + return this.retrieve(documentType, parse, null); + } + + public <T extends Document> T retrieve(Class<T> documentType, + boolean parse, String fingerprint) { + this.performedRetrieveOperations++; + return documentType.cast(this.getStoredDocumentsByClass(documentType). + get(fingerprint == null ? FINGERPRINT_NULL : fingerprint)); + } + + private int performedStoreOperations = 0; + public int getPerformedStoreOperations() { + return this.performedStoreOperations; + } + + public <T extends Document> boolean store(T document) { + return this.store(document, null); + } + + public <T extends Document> boolean store(T document, + String fingerprint) { + this.performedStoreOperations++; + this.getStoredDocumentsByClass(document.getClass()).put( + fingerprint == null ? FINGERPRINT_NULL : fingerprint, document); + return true; + } +} + diff --git a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java new file mode 100644 index 0000000..83ffa5f --- /dev/null +++ b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java @@ -0,0 +1,1385 @@ +/* Copyright 2013 The Tor Project + * See LICENSE for licensing information */ + +package org.torproject.onionoo.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.junit.Before; +import org.junit.Test; +import org.torproject.onionoo.docs.DateTimeHelper; +import org.torproject.onionoo.docs.DocumentStoreFactory; +import org.torproject.onionoo.docs.DummyDocumentStore; +import org.torproject.onionoo.docs.UpdateStatus; +import org.torproject.onionoo.server.HttpServletRequestWrapper; +import org.torproject.onionoo.server.HttpServletResponseWrapper; +import org.torproject.onionoo.server.NodeIndexer; +import org.torproject.onionoo.server.NodeIndexerFactory; +import org.torproject.onionoo.server.ResourceServlet; +import org.torproject.onionoo.util.DummyTime; +import org.torproject.onionoo.util.Time; +import org.torproject.onionoo.util.TimeFactory; + +import com.google.gson.Gson; + +/* TODO This test class could (should?) be split into ResponseBuilderTest + * which tests ResponseBuilder and a much shorter ResourceServletTest + * which tests servlet specifics. */ +public class ResourceServletTest { + + private SortedMap<String, org.torproject.onionoo.docs.SummaryDocument> + relays, bridges; + + private long currentTimeMillis = DateTimeHelper.parse( + "2013-04-24 12:22:22"); + + private class TestingHttpServletRequestWrapper + extends HttpServletRequestWrapper { + private String requestURI; + private String queryString; + private Map<String, String[]> parameterMap; + private TestingHttpServletRequestWrapper(String requestURI, + String queryString, Map<String, String[]> parameterMap) { + super(null); + this.requestURI = requestURI; + this.queryString = queryString; + this.parameterMap = parameterMap == null + ? new HashMap<String, String[]>() : parameterMap; + } + protected String getRequestURI() { + return this.requestURI; + } + @SuppressWarnings("rawtypes") + protected Map getParameterMap() { + return this.parameterMap; + } + protected String[] getParameterValues(String parameterKey) { + return this.parameterMap.get(parameterKey); + } + protected String getQueryString() { + return this.queryString; + } + } + + private class TestingHttpServletResponseWrapper extends + HttpServletResponseWrapper { + private TestingHttpServletResponseWrapper() { + super(null); + } + private int errorStatusCode; + protected void sendError(int errorStatusCode) throws IOException { + this.errorStatusCode = errorStatusCode; + } + private Map<String, String> headers = new HashMap<String, String>(); + protected void setHeader(String headerName, String headerValue) { + this.headers.put(headerName, headerValue); + } + protected void setContentType(String contentType) { + } + protected void setCharacterEncoding(String characterEncoding) { + } + private StringWriter stringWriter; + protected PrintWriter getWriter() throws IOException { + if (this.stringWriter == null) { + this.stringWriter = new StringWriter(); + return new PrintWriter(this.stringWriter); + } else { + throw new IOException("Can only request writer once"); + } + } + private String getWrittenContent() { + return this.stringWriter == null ? null + : this.stringWriter.toString(); + } + } + + private TestingHttpServletRequestWrapper request; + + private TestingHttpServletResponseWrapper response; + + private String responseString; + + private SummaryDocument summaryDocument; + + @Before + public void createSampleRelaysAndBridges() { + org.torproject.onionoo.docs.SummaryDocument relayTorkaZ = + new org.torproject.onionoo.docs.SummaryDocument(true, "TorkaZ", + "000C5F55BD4814B917CC474BD537F1A3B33CCE2A", Arrays.asList( + new String[] { "62.216.201.221", "62.216.201.222", + "62.216.201.223" }), DateTimeHelper.parse("2013-04-19 05:00:00"), + false, new TreeSet<String>(Arrays.asList(new String[] { "Running", + "Valid" })), 20L, "de", + DateTimeHelper.parse("2013-04-18 05:00:00"), "AS8767", + "torkaz <klaus dot zufall at gmx dot de> " + + "fb-token:np5_g_83jmf=", new TreeSet<String>(Arrays.asList( + new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC", + "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B" }))); + org.torproject.onionoo.docs.SummaryDocument relayFerrari458 = + new org.torproject.onionoo.docs.SummaryDocument(true, "Ferrari458", + "001C13B3A55A71B977CA65EC85539D79C653A3FC", Arrays.asList( + new String[] { "68.38.171.200", "[2001:4f8:3:2e::51]" }), + DateTimeHelper.parse("2013-04-24 12:00:00"), true, + new TreeSet<String>(Arrays.asList(new String[] { "Fast", "Named", + "Running", "V2Dir", "Valid" })), 1140L, "us", + DateTimeHelper.parse("2013-02-12 16:00:00"), "AS7922", null, + new TreeSet<String>(Arrays.asList(new String[] { + "000C5F55BD4814B917CC474BD537F1A3B33CCE2A" }))); + org.torproject.onionoo.docs.SummaryDocument relayTimMayTribute = + new org.torproject.onionoo.docs.SummaryDocument(true, "TimMayTribute", + "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", Arrays.asList( + new String[] { "89.69.68.246" }), + DateTimeHelper.parse("2013-04-22 20:00:00"), false, + new TreeSet<String>(Arrays.asList(new String[] { "Fast", + "Running", "Unnamed", "V2Dir", "Valid" })), 63L, "a1", + DateTimeHelper.parse("2013-04-16 18:00:00"), "AS6830", + "1024D/51E2A1C7 steven j. murdoch " + + "tor+steven.murdoch@cl.cam.ac.uk fb-token:5sr_k_zs2wm=", + new TreeSet<String>()); + org.torproject.onionoo.docs.SummaryDocument bridgeec2bridgercc7f31fe = + new org.torproject.onionoo.docs.SummaryDocument(false, + "ec2bridgercc7f31fe", "0000831B236DFF73D409AD17B40E2A728A53994F", + Arrays.asList(new String[] { "10.199.7.176" }), + DateTimeHelper.parse("2013-04-21 18:07:03"), false, + new TreeSet<String>(Arrays.asList(new String[] { "Valid" })), -1L, + null, DateTimeHelper.parse("2013-04-20 15:37:04"), null, null, + null); + org.torproject.onionoo.docs.SummaryDocument bridgeUnnamed = + new org.torproject.onionoo.docs.SummaryDocument(false, "Unnamed", + "0002D9BDBBC230BD9C78FF502A16E0033EF87E0C", Arrays.asList( + new String[] { "10.0.52.84" }), + DateTimeHelper.parse("2013-04-20 17:37:04"), false, + new TreeSet<String>(Arrays.asList(new String[] { "Valid" })), -1L, + null, DateTimeHelper.parse("2013-04-14 07:07:05"), null, null, + null); + org.torproject.onionoo.docs.SummaryDocument bridgegummy = + new org.torproject.onionoo.docs.SummaryDocument(false, "gummy", + "1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", Arrays.asList( + new String[] { "10.63.169.98" }), + DateTimeHelper.parse("2013-04-24 01:07:04"), true, + new TreeSet<String>(Arrays.asList(new String[] { "Running", + "Valid" })), -1L, null, + DateTimeHelper.parse("2013-01-16 21:07:04"), null, null, null); + this.relays = + new TreeMap<String, org.torproject.onionoo.docs.SummaryDocument>(); + this.relays.put("000C5F55BD4814B917CC474BD537F1A3B33CCE2A", + relayTorkaZ); + this.relays.put("001C13B3A55A71B977CA65EC85539D79C653A3FC", + relayFerrari458); + this.relays.put("0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", + relayTimMayTribute); + this.bridges = + new TreeMap<String, org.torproject.onionoo.docs.SummaryDocument>(); + this.bridges.put("0000831B236DFF73D409AD17B40E2A728A53994F", + bridgeec2bridgercc7f31fe); + this.bridges.put("0002D9BDBBC230BD9C78FF502A16E0033EF87E0C", + bridgeUnnamed); + this.bridges.put("1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", + bridgegummy); + } + + private void runTest(String request) { + try { + this.createDummyTime(); + this.createDummyDocumentStore(); + this.createNodeIndexer(); + this.makeRequest(request); + this.parseResponse(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void createDummyTime() { + Time dummyTime = new DummyTime(this.currentTimeMillis); + TimeFactory.setTime(dummyTime); + } + + private void createDummyDocumentStore() { + DummyDocumentStore documentStore = new DummyDocumentStore(); + UpdateStatus updateStatus = new UpdateStatus(); + updateStatus.setUpdatedMillis(this.currentTimeMillis); + documentStore.addDocument(updateStatus, null); + for (Map.Entry<String, org.torproject.onionoo.docs.SummaryDocument> e : + this.relays.entrySet()) { + documentStore.addDocument(e.getValue(), e.getKey()); + } + for (Map.Entry<String, org.torproject.onionoo.docs.SummaryDocument> e : + this.bridges.entrySet()) { + documentStore.addDocument(e.getValue(), e.getKey()); + } + DocumentStoreFactory.setDocumentStore(documentStore); + } + + private void createNodeIndexer() { + NodeIndexer newNodeIndexer = new NodeIndexer(); + newNodeIndexer.startIndexing(); + NodeIndexerFactory.setNodeIndexer(newNodeIndexer); + } + + private void makeRequest(String request) throws IOException { + ResourceServlet rs = new ResourceServlet(); + String requestParts[] = request.split("\?"); + String path = requestParts[0]; + String queryString = requestParts.length > 1 ? requestParts[1] : null; + Map<String, String[]> parameterMap = parseParameters(request); + this.request = new TestingHttpServletRequestWrapper(path, queryString, + parameterMap); + this.response = new TestingHttpServletResponseWrapper(); + rs.doGet(this.request, this.response); + } + + private void parseResponse() { + this.responseString = this.response.getWrittenContent(); + if (this.responseString != null) { + Gson gson = new Gson(); + this.summaryDocument = gson.fromJson(this.responseString, + SummaryDocument.class); + } + } + + private void assertErrorStatusCode(String request, + int errorStatusCode) { + this.runTest(request); + assertEquals(errorStatusCode, this.response.errorStatusCode); + } + + private void assertSummaryDocument(String request, + int expectedRelaysNumber, String[] expectedRelaysNicknames, + int expectedBridgesNumber, String[] expectedBridgesNicknames) { + this.runTest(request); + assertNotNull(this.summaryDocument); + assertEquals(expectedRelaysNumber, + this.summaryDocument.relays.length); + if (expectedRelaysNicknames != null) { + for (int i = 0; i < expectedRelaysNumber; i++) { + assertEquals(expectedRelaysNicknames[i], + this.summaryDocument.relays[i].n); + } + } + assertEquals(expectedBridgesNumber, + this.summaryDocument.bridges.length); + if (expectedBridgesNicknames != null) { + for (int i = 0; i < expectedBridgesNumber; i++) { + assertEquals(expectedBridgesNicknames[i], + this.summaryDocument.bridges[i].n); + } + } + } + + private Map<String, String[]> parseParameters(String request) { + Map<String, String[]> parameters = null; + String[] uriParts = request.split("\?"); + if (uriParts.length == 2) { + Map<String, List<String>> parameterLists = + new HashMap<String, List<String>>(); + for (String parameter : uriParts[1].split("&")) { + String[] parameterParts = parameter.split("="); + if (!parameterLists.containsKey(parameterParts[0])) { + parameterLists.put(parameterParts[0], + new ArrayList<String>()); + } + parameterLists.get(parameterParts[0]).add(parameterParts[1]); + } + parameters = new HashMap<String, String[]>(); + for (Map.Entry<String, List<String>> e : + parameterLists.entrySet()) { + parameters.put(e.getKey(), + e.getValue().toArray(new String[e.getValue().size()])); + } + } + return parameters; + } + + private static class SummaryDocument { + private String relays_published; + private RelaySummary[] relays; + private String bridges_published; + private BridgeSummary[] bridges; + } + + private static class RelaySummary { + private String n; + private String f; + private String[] a; + private boolean r; + } + + private static class BridgeSummary { + private String n; + private String h; + private boolean r; + } + + @Test() + public void testValidSummaryRelay() throws IOException { + this.runTest("/summary"); + assertEquals("2013-04-24 12:00:00", + this.summaryDocument.relays_published); + assertEquals(3, this.summaryDocument.relays.length); + RelaySummary relay = null; + for (RelaySummary r : this.summaryDocument.relays) { + if (r.f.equals("000C5F55BD4814B917CC474BD537F1A3B33CCE2A")) { + relay = r; + break; + } + } + assertNotNull(relay); + assertEquals("TorkaZ", relay.n); + assertEquals(3, relay.a.length); + assertEquals("62.216.201.221", relay.a[0]); + assertFalse(relay.r); + } + + @Test() + public void testValidSummaryBridge() { + this.runTest("/summary"); + assertEquals("2013-04-24 01:07:04", + this.summaryDocument.bridges_published); + assertEquals(3, this.summaryDocument.bridges.length); + BridgeSummary bridge = null; + for (BridgeSummary b : this.summaryDocument.bridges) { + if (b.h.equals("0000831B236DFF73D409AD17B40E2A728A53994F")) { + bridge = b; + break; + } + } + assertNotNull(bridge); + assertEquals("ec2bridgercc7f31fe", bridge.n); + assertFalse(bridge.r); + } + + @Test() + public void testNonExistantDocumentType() { + this.assertErrorStatusCode( + "/doesnotexist", 400); + } + + @Test() + public void testSUMMARYDocument() { + this.assertErrorStatusCode( + "/SUMMARY", 400); + } + + @Test() + public void testTypeRelay() { + this.assertSummaryDocument( + "/summary?type=relay", 3, null, 0, null); + } + + @Test() + public void testTypeBridge() { + this.assertSummaryDocument( + "/summary?type=bridge", 0, null, 3, null); + } + + @Test() + public void testTypeBridgerelay() { + this.assertErrorStatusCode( + "/summary?type=bridgerelay", 400); + } + + @Test() + public void testTypeRelayBridge() { + this.assertSummaryDocument( + "/summary?type=relay&type=bridge", 3, null, 0, null); + } + + @Test() + public void testTypeBridgeRelay() { + this.assertSummaryDocument( + "/summary?type=bridge&type=relay", 0, null, 3, null); + } + + @Test() + public void testTypeRelayRelay() { + this.assertSummaryDocument( + "/summary?type=relay&type=relay", 3, null, 0, null); + } + + @Test() + public void testTYPERelay() { + this.assertErrorStatusCode( + "/summary?TYPE=relay", 400); + } + + @Test() + public void testTypeRELAY() { + this.assertSummaryDocument( + "/summary?type=RELAY", 3, null, 0, null); + } + + @Test() + public void testRunningTrue() { + this.assertSummaryDocument( + "/summary?running=true", 1, new String[] { "Ferrari458" }, 1, + new String[] { "gummy" }); + } + + @Test() + public void testRunningFalse() { + this.assertSummaryDocument( + "/summary?running=false", 2, null, 2, null); + } + + @Test() + public void testRunningTruefalse() { + this.assertErrorStatusCode( + "/summary?running=truefalse", 400); + } + + @Test() + public void testRunningTrueFalse() { + this.assertSummaryDocument( + "/summary?running=true&running=false", 1, + new String[] { "Ferrari458" }, 1, new String[] { "gummy" }); + } + + @Test() + public void testRunningFalseTrue() { + this.assertSummaryDocument( + "/summary?running=false&running=true", 2, null, 2, null); + } + + @Test() + public void testRunningTrueTrue() { + this.assertSummaryDocument( + "/summary?running=true&running=true", 1, + new String[] { "Ferrari458" }, 1, new String[] { "gummy" }); + } + + @Test() + public void testRUNNINGTrue() { + this.assertErrorStatusCode( + "/summary?RUNNING=true", 400); + } + + @Test() + public void testRunningTRUE() { + this.assertSummaryDocument( + "/summary?running=TRUE", 1, null, 1, null); + } + + @Test() + public void testSearchTorkaZ() { + this.assertSummaryDocument( + "/summary?search=TorkaZ", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchTorkaX() { + this.assertSummaryDocument( + "/summary?search=TorkaX", 0, null, 0, null); + } + + @Test() + public void testSearchOrkaZ() { + this.assertSummaryDocument( + "/summary?search=orkaZ", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchTorka() { + this.assertSummaryDocument( + "/summary?search=Torka", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchTORKAZ() { + this.assertSummaryDocument( + "/summary?search=TORKAZ", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarFingerprint() { + this.assertSummaryDocument( + "/summary?search=$000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchFingerprint() { + this.assertSummaryDocument( + "/summary?search=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarFingerprint39() { + this.assertSummaryDocument( + "/summary?search=$000C5F55BD4814B917CC474BD537F1A3B33CCE2", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarFingerprintLowerCase39() { + this.assertSummaryDocument( + "/summary?search=$000c5f55bd4814b917cc474bd537f1a3b33cce2", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchFingerprintLowerCase39() { + this.assertSummaryDocument( + "/summary?search=000c5f55bd4814b917cc474bd537f1a3b33cce2", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarHashedFingerprint() { + this.assertSummaryDocument( + "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94cee", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarHashedFingerprint39() { + this.assertSummaryDocument( + "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94ce", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchDollarHashedFingerprint41() { + this.assertErrorStatusCode( + "/summary?search=$5aa14c08d62913e0057a9ad5863b458c0ce94ceee", + 400); + } + + @Test() + public void testSearchBase64FingerprintAlphaNum() { + this.assertSummaryDocument( + "/summary?search=AAxfVb1IFLkXzEdL1Tfxo7M8zio", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchBase64FingerprintSlash() { + this.assertSummaryDocument( + "/summary?search=ABwTs6Vacbl3ymXshVOdecZTo/w", 1, + new String[] { "Ferrari458" }, 0, null); + } + + @Test() + public void testSearchBase64FingerprintPlus() { + this.assertSummaryDocument( + "/summary?search=ACXBNsHzqe7+KuP5GPA7+iG1Bws", 1, + new String[] { "TimMayTribute" }, 0, null); + } + + @Test() + public void testSearchBase64FingerprintBridge() { + this.assertSummaryDocument( + "/summary?search=AACDGyNt/3PUCa0XtA4qcopTmU8", 0, null, 0, null); + } + + @Test() + public void testSearchBase64FingerprintPartial() { + this.assertSummaryDocument( + "/summary?search=AAx", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchBase64HashedFingerprintTorkaZ() { + this.assertSummaryDocument( + "/summary?search=WqFMCNYpE+AFeprVhjtFjAzpTO4", 0, null, 0, null); + } + + @Test() + public void testSearchBase64Fingerprint28() { + this.assertErrorStatusCode( + "/summary?search=AAAAAAAAAAAA//AAAAAAAAAAAAAA", 400); + } + + @Test() + public void testSearchIp() { + this.assertSummaryDocument( + "/summary?search=62.216.201.221", 1, new String[] { "TorkaZ" }, 0, + null); + } + + @Test() + public void testSearchIp24Network() { + this.assertSummaryDocument( + "/summary?search=62.216.201", 1, new String[] { "TorkaZ" }, 0, + null); + } + + @Test() + public void testSearchIpExit() { + this.assertSummaryDocument( + "/summary?search=62.216.201.222", 1, new String[] { "TorkaZ" }, 0, + null); + } + + @Test() + public void testSearchIpv6() { + this.assertSummaryDocument( + "/summary?search=[2001:4f8:3:2e::51]", 1, + new String[] { "Ferrari458" }, 0, null); + } + + @Test() + public void testSearchIpv6Slash64NoTrailingBracket() { + this.assertSummaryDocument( + "/summary?search=[2001:4f8:3:2e::", 1, + new String[] { "Ferrari458" }, 0, null); + } + + @Test() + public void testSearchIpv6Slash64TrailingBracket() { + this.assertSummaryDocument( + "/summary?search=[2001:4f8:3:2e::]", 0, null, 0, null); + } + + @Test() + public void testSearchIpv6Uncompressed() { + this.assertSummaryDocument( + "/summary?search=[2001:04f8:0003:002e:0000:0000:0000:0051]", 0, + null, 0, null); + } + + @Test() + public void testSearchIpv6UpperCase() { + this.assertSummaryDocument( + "/summary?search=[2001:4F8:3:2E::51]", 1, + new String[] { "Ferrari458" }, 0, null); + } + + @Test() + public void testSearchIpv6ThreeColons() { + this.assertSummaryDocument( + "/summary?search=[2001:4f8:3:2e:::51]", 0, null, 0, null); + } + + @Test() + public void testSearchIpv6FiveHex() { + this.assertSummaryDocument( + "/summary?search=[20014:f80:3:2e::51]", 0, null, 0, null); + } + + @Test() + public void testSearchIpv6NineGroups() { + this.assertSummaryDocument( + "/summary?search=[1:2:3:4:5:6:7:8:9]", 0, null, 0, null); + } + + @Test() + public void testSearchIpv6TcpPort() { + this.assertErrorStatusCode( + "/summary?search=[2001:4f8:3:2e::51]:9001", 400); + } + + @Test() + public void testSearchGummy() { + this.assertSummaryDocument( + "/summary?search=gummy", 0, null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchGummi() { + this.assertSummaryDocument( + "/summary?search=gummi", 0, null, 0, null); + } + + @Test() + public void testSearchUmmy() { + this.assertSummaryDocument( + "/summary?search=ummy", 0, null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchGumm() { + this.assertSummaryDocument( + "/summary?search=gumm", 0, null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchGUMMY() { + this.assertSummaryDocument( + "/summary?search=GUMMY", 0, null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarHashedFingerprint() { + this.assertSummaryDocument( + "/summary?search=$1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeHashedFingerprint() { + this.assertSummaryDocument( + "/summary?search=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarHashedFingerprint39() { + this.assertSummaryDocument( + "/summary?search=$1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB75", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarHashedFingerprintLowerCase39() { + this.assertSummaryDocument( + "/summary?search=$1fede50ed8dba1dd9f9165f78c8131e4a44ab75", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeHashedFingerprintLowerCase39() { + this.assertSummaryDocument( + "/summary?search=1fede50ed8dba1dd9f9165f78c8131e4a44ab75", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarHashedHashedFingerprint() { + this.assertSummaryDocument( + "/summary?search=$CE52F898DB3678BCE33FAC28C92774DE90D618B5", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarHashedHashedFingerprint39() { + this.assertSummaryDocument( + "/summary?search=$CE52F898DB3678BCE33FAC28C92774DE90D618B", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testSearchBridgeDollarOriginalFingerprint() { + this.assertSummaryDocument( + "/summary?search=$0010D49C6DA1E46A316563099F41BFE40B6C7183", 0, + null, 0, null); + } + + @Test() + public void testSearchUnderscore() { + this.assertErrorStatusCode( + "/summary?search=_", 400); + } + + @Test() + public void testSearchTypeRelay() { + this.assertSummaryDocument("/summary?search=type:relay", 3, null, 0, + null); + } + + @Test() + public void testSearchTypeRelayTorkaZ() { + this.assertSummaryDocument("/summary?search=type:relay TorkaZ", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchTorkaZTypeRelay() { + this.assertSummaryDocument("/summary?search=TorkaZ type:relay", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testSearchTypeRelayTypeDirectory() { + this.assertSummaryDocument( + "/summary?search=type:relay type:directory", 3, null, 0, null); + } + + @Test() + public void testSearchTypeDirectoryTypeRelay() { + this.assertErrorStatusCode( + "/summary?search=type:directory type:relay", 400); + } + + @Test() + public void testSearchFooBar() { + this.assertErrorStatusCode("/summary?search=foo:bar", 400); + } + + @Test() + public void testSearchSearchTorkaZ() { + this.assertErrorStatusCode("/summary?search=search:TorkaZ", 400); + } + + @Test() + public void testSearchLimitOne() { + this.assertErrorStatusCode("/summary?search=limit:1", 400); + } + + @Test() + public void testLookupFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testLookupDollarFingerprint() { + this.assertErrorStatusCode( + "/summary?lookup=$000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 400); + } + + @Test() + public void testLookupDollarFingerprint39() { + this.assertErrorStatusCode( + "/summary?lookup=$000C5F55BD4814B917CC474BD537F1A3B33CCE2", 400); + } + + @Test() + public void testLookupFingerprintLowerCase39() { + this.assertErrorStatusCode( + "/summary?lookup=000c5f55bd4814b917cc474bd537f1a3b33cce2", 400); + } + + @Test() + public void testLookupHashedFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=5aa14c08d62913e0057a9ad5863b458c0ce94cee", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testLookupBridgeHashedFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testLookupBridgeHashedHashedFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=CE52F898DB3678BCE33FAC28C92774DE90D618B5", 0, + null, 1, new String[] { "gummy" }); + } + + @Test() + public void testLookupBridgeOriginalFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=0010D49C6DA1E46A316563099F41BFE40B6C7183", 0, + null, 0, null); + } + + @Test() + public void testLookupNonExistantFingerprint() { + this.assertSummaryDocument( + "/summary?lookup=0000000000000000000000000000000000000000", 0, + null, 0, null); + } + + @Test() + public void testFingerprintRelayFingerprint() { + this.assertSummaryDocument( + "/summary?fingerprint=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", + 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testFingerprintRelayHashedFingerprint() { + this.assertSummaryDocument( + "/summary?fingerprint=5aa14c08d62913e0057a9ad5863b458c0ce94cee", + 0, null, 0, null); + } + + @Test() + public void testFingerprintBridgeHashedFingerprint() { + this.assertSummaryDocument( + "/summary?fingerprint=1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", + 0, null, 1, new String[] { "gummy" }); + } + + @Test() + public void testFingerprintBridgeHashedHashedFingerprint() { + this.assertSummaryDocument( + "/summary?fingerprint=CE52F898DB3678BCE33FAC28C92774DE90D618B5", + 0, null, 0, null); + } + + @Test() + public void testFingerprintBridgeOriginalFingerprint() { + this.assertSummaryDocument( + "/summary?fingerprint=0010D49C6DA1E46A316563099F41BFE40B6C7183", + 0, null, 0, null); + } + + @Test() + public void testCountryDe() { + this.assertSummaryDocument( + "/summary?country=de", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testCountryFr() { + this.assertSummaryDocument( + "/summary?country=fr", 0, null, 0, null); + } + + @Test() + public void testCountryZz() { + this.assertSummaryDocument( + "/summary?country=zz", 0, null, 0, null); + } + + @Test() + public void testCountryDE() { + this.assertSummaryDocument( + "/summary?country=DE", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testCountryDeu() { + this.assertErrorStatusCode( + "/summary?country=deu", 400); + } + + @Test() + public void testCountryD() { + this.assertErrorStatusCode( + "/summary?country=d", 400); + } + + @Test() + public void testCountryA1() { + this.assertSummaryDocument( + "/summary?country=a1", 1, new String[] { "TimMayTribute" }, 0, + null); + } + + @Test() + public void testCountryDeDe() { + this.assertSummaryDocument( + "/summary?country=de&country=de", 1, new String[] { "TorkaZ" }, 0, + null); + } + + @Test() + public void testAsAS8767() { + this.assertSummaryDocument( + "/summary?as=AS8767", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testAs8767() { + this.assertSummaryDocument( + "/summary?as=8767", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testAsAS() { + this.assertErrorStatusCode( + "/summary?as=AS", 400); + } + + @Test() + public void testAsas8767() { + this.assertSummaryDocument( + "/summary?as=as8767", 1, new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testAsASSpace8767() { + this.assertErrorStatusCode( + "/summary?as=AS 8767", 400); + } + + @Test() + public void testFlagRunning() { + this.assertSummaryDocument( + "/summary?flag=Running", 3, null, 1, null); + } + + @Test() + public void testFlagValid() { + this.assertSummaryDocument( + "/summary?flag=Valid", 3, null, 3, null); + } + + @Test() + public void testFlagFast() { + this.assertSummaryDocument( + "/summary?flag=Fast", 2, null, 0, null); + } + + @Test() + public void testFlagNamed() { + this.assertSummaryDocument( + "/summary?flag=Named", 1, null, 0, null); + } + + @Test() + public void testFlagUnnamed() { + this.assertSummaryDocument( + "/summary?flag=Unnamed", 1, null, 0, null); + } + + @Test() + public void testFlagV2Dir() { + this.assertSummaryDocument( + "/summary?flag=V2Dir", 2, null, 0, null); + } + + @Test() + public void testFlagGuard() { + this.assertSummaryDocument( + "/summary?flag=Guard", 0, null, 0, null); + } + + @Test() + public void testFlagCool() { + this.assertSummaryDocument( + "/summary?flag=Cool", 0, null, 0, null); + } + + @Test() + public void testFirstSeenDaysZeroToTwo() { + this.assertSummaryDocument( + "/summary?first_seen_days=0-2", 0, null, 0, null); + } + + @Test() + public void testFirstSeenDaysUpToThree() { + this.assertSummaryDocument( + "/summary?first_seen_days=-3", 0, null, 1, null); + } + + @Test() + public void testFirstSeenDaysThree() { + this.assertSummaryDocument( + "/summary?first_seen_days=3", 0, null, 1, null); + } + + @Test() + public void testFirstSeenDaysTwoToFive() { + this.assertSummaryDocument( + "/summary?first_seen_days=2-5", 0, null, 1, null); + } + + @Test() + public void testFirstSeenDaysSixToSixteen() { + this.assertSummaryDocument( + "/summary?first_seen_days=6-16", 2, null, 1, null); + } + + @Test() + public void testFirstSeenDaysNinetysevenOrMore() { + this.assertSummaryDocument( + "/summary?first_seen_days=97-", 0, null, 1, null); + } + + @Test() + public void testFirstSeenDaysNinetyeightOrMore() { + this.assertSummaryDocument( + "/summary?first_seen_days=98-", 0, null, 0, null); + } + + @Test() + public void testFirstSeenDaysDashDash() { + this.assertErrorStatusCode( + "/summary?first_seen_days=--", 400); + } + + @Test() + public void testFirstSeenDaysDashOneDash() { + this.assertErrorStatusCode( + "/summary?first_seen_days=-1-", 400); + } + + @Test() + public void testFirstSeenDaysZeroDotDotOne() { + this.assertErrorStatusCode( + "/summary?first_seen_days=0..1", 400); + } + + @Test() + public void testFirstSeenDaysElevenDigits() { + this.assertErrorStatusCode( + "/summary?first_seen_days=12345678901", 400); + } + + @Test() + public void testFirstSeenDaysLargeTenDigitNumber() { + this.assertErrorStatusCode( + "/summary?first_seen_days=9999999999", 400); + } + + @Test() + public void testFirstSeenDaysMaxInt() { + this.assertSummaryDocument( + "/summary?last_seen_days=" + String.valueOf(Integer.MAX_VALUE), 0, + null, 0, null); + } + + @Test() + public void testFirstSeenDaysMaxIntPlusOne() { + this.assertErrorStatusCode( + "/summary?first_seen_days=" + + String.valueOf(Integer.MAX_VALUE + 1), 400); + } + + @Test() + public void testLastSeenDaysZero() { + this.assertSummaryDocument( + "/summary?last_seen_days=0", 1, null, 1, null); + } + + @Test() + public void testLastSeenDaysUpToZero() { + this.assertSummaryDocument( + "/summary?last_seen_days=-0", 1, null, 1, null); + } + + @Test() + public void testLastSeenDaysOneToThree() { + this.assertSummaryDocument( + "/summary?last_seen_days=1-3", 1, null, 2, null); + } + + @Test() + public void testLastSeenDaysSixOrMore() { + this.assertSummaryDocument( + "/summary?last_seen_days=6-", 0, null, 0, null); + } + + @Test() + public void testContactSteven() { + this.assertSummaryDocument( + "/summary?contact=Steven", 1, null, 0, null); + } + + @Test() + public void testContactStevenMurdoch() { + this.assertSummaryDocument( + "/summary?contact=Steven Murdoch", 1, null, 0, null); + } + + @Test() + public void testContactMurdochSteven() { + this.assertSummaryDocument( + "/summary?contact=Murdoch Steven", 1, null, 0, null); + } + + @Test() + public void testContactStevenDotMurdoch() { + this.assertSummaryDocument( + "/summary?contact=Steven.Murdoch", 1, null, 0, null); + } + + @Test() + public void testContactFbTokenFive() { + this.assertSummaryDocument( + "/summary?contact=fb-token:5sR_K_zs2wM=", 1, null, 0, null); + } + + @Test() + public void testContactFbToken() { + this.assertSummaryDocument( + "/summary?contact=<fb-token:", 2, null, 0, null); + } + + @Test() + public void testContactDash() { + this.assertSummaryDocument( + "/summary?contact=-", 2, null, 0, null); + } + + @Test() + public void testOrderConsensusWeightAscending() { + this.assertSummaryDocument( + "/summary?order=consensus_weight", 3, + new String[] { "TorkaZ", "TimMayTribute", "Ferrari458" }, 3, + null); + } + + @Test() + public void testOrderConsensusWeightDescending() { + this.assertSummaryDocument( + "/summary?order=-consensus_weight", 3, + new String[] { "Ferrari458", "TimMayTribute", "TorkaZ" }, 3, + null); + } + + @Test() + public void testOrderConsensusWeightAscendingTwice() { + this.assertErrorStatusCode( + "/summary?order=consensus_weight,consensus_weight", 400); + } + + @Test() + public void testOrderConsensusWeightAscendingThenDescending() { + this.assertErrorStatusCode( + "/summary?order=consensus_weight,-consensus_weight", 400); + } + + @Test() + public void testOrderConsensusWeightThenNickname() { + this.assertErrorStatusCode( + "/summary?order=consensus_weight,nickname", 400); + } + + @Test() + public void testOrderCONSENSUS_WEIGHT() { + this.assertSummaryDocument( + "/summary?order=CONSENSUS_WEIGHT", 3, + new String[] { "TorkaZ", "TimMayTribute", "Ferrari458" }, 3, + null); + } + + @Test() + public void testOrderConsensusWeightAscendingLimit1() { + this.assertSummaryDocument( + "/summary?order=consensus_weight&limit=1", 1, + new String[] { "TorkaZ" }, 0, null); + } + + @Test() + public void testOrderConsensusWeightDecendingLimit1() { + this.assertSummaryDocument( + "/summary?order=-consensus_weight&limit=1", 1, + new String[] { "Ferrari458" }, 0, null); + } + + @Test() + public void testOffsetOne() { + this.assertSummaryDocument( + "/summary?offset=1", 2, null, 3, null); + } + + @Test() + public void testOffsetAllRelays() { + this.assertSummaryDocument( + "/summary?offset=3", 0, null, 3, null); + } + + @Test() + public void testOffsetAllRelaysAndOneBridge() { + this.assertSummaryDocument( + "/summary?offset=4", 0, null, 2, null); + } + + @Test() + public void testOffsetAllRelaysAndAllBridges() { + this.assertSummaryDocument( + "/summary?offset=6", 0, null, 0, null); + } + + @Test() + public void testOffsetMoreThanAllRelaysAndAllBridges() { + this.assertSummaryDocument( + "/summary?offset=7", 0, null, 0, null); + } + + @Test() + public void testOffsetZero() { + this.assertSummaryDocument( + "/summary?offset=0", 3, null, 3, null); + } + + @Test() + public void testOffsetMinusOne() { + this.assertSummaryDocument( + "/summary?offset=-1", 3, null, 3, null); + } + + @Test() + public void testOffsetOneWord() { + this.assertErrorStatusCode( + "/summary?offset=one", 400); + } + + @Test() + public void testLimitOne() { + this.assertSummaryDocument( + "/summary?limit=1", 1, null, 0, null); + } + + @Test() + public void testLimitAllRelays() { + this.assertSummaryDocument( + "/summary?limit=3", 3, null, 0, null); + } + + @Test() + public void testLimitAllRelaysAndOneBridge() { + this.assertSummaryDocument( + "/summary?limit=4", 3, null, 1, null); + } + + @Test() + public void testLimitAllRelaysAndAllBridges() { + this.assertSummaryDocument( + "/summary?limit=6", 3, null, 3, null); + } + + @Test() + public void testLimitMoreThanAllRelaysAndAllBridges() { + this.assertSummaryDocument( + "/summary?limit=7", 3, null, 3, null); + } + + @Test() + public void testLimitZero() { + this.assertSummaryDocument( + "/summary?limit=0", 0, null, 0, null); + } + + @Test() + public void testLimitMinusOne() { + this.assertSummaryDocument( + "/summary?limit=-1", 0, null, 0, null); + } + + @Test() + public void testLimitOneWord() { + this.assertErrorStatusCode( + "/summary?limit=one", 400); + } + + @Test() + public void testFamilyTorkaZ() { + this.assertSummaryDocument( + "/summary?family=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 2, + null, 0, null); + } + + @Test() + public void testFamilyFerrari458() { + this.assertSummaryDocument( + "/summary?family=001C13B3A55A71B977CA65EC85539D79C653A3FC", 2, + null, 0, null); + } + + @Test() + public void testFamilyTimMayTribute() { + this.assertSummaryDocument( + "/summary?family=0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", 1, + null, 0, null); + } + + @Test() + public void testFamilyBridgegummy() { + this.assertSummaryDocument( + "/summary?family=0000831B236DFF73D409AD17B40E2A728A53994F", 0, + null, 0, null); + } + + @Test() + public void testFamily39Characters() { + this.assertErrorStatusCode( + "/summary?family=00000000000000000000000000000000000000", 400); + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/DummyBridgeStatus.java b/src/test/java/org/torproject/onionoo/updater/DummyBridgeStatus.java new file mode 100644 index 0000000..f6a396c --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/DummyBridgeStatus.java @@ -0,0 +1,43 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.updater; + +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.torproject.descriptor.BridgeNetworkStatus; +import org.torproject.descriptor.NetworkStatusEntry; + +public class DummyBridgeStatus implements BridgeNetworkStatus { + + public byte[] getRawDescriptorBytes() { + return null; + } + + public List<String> getAnnotations() { + return null; + } + + public List<String> getUnrecognizedLines() { + return null; + } + + private long publishedMillis; + public void setPublishedMillis(long publishedMillis) { + this.publishedMillis = publishedMillis; + } + public long getPublishedMillis() { + return this.publishedMillis; + } + + private SortedMap<String, NetworkStatusEntry> statusEntries = + new TreeMap<String, NetworkStatusEntry>(); + public void addStatusEntry(NetworkStatusEntry statusEntry) { + this.statusEntries.put(statusEntry.getFingerprint(), statusEntry); + } + public SortedMap<String, NetworkStatusEntry> getStatusEntries() { + return this.statusEntries; + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/DummyConsensus.java b/src/test/java/org/torproject/onionoo/updater/DummyConsensus.java new file mode 100644 index 0000000..8f164a0 --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/DummyConsensus.java @@ -0,0 +1,114 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.updater; + +import java.util.List; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; + +import org.torproject.descriptor.DirSourceEntry; +import org.torproject.descriptor.DirectorySignature; +import org.torproject.descriptor.NetworkStatusEntry; +import org.torproject.descriptor.RelayNetworkStatusConsensus; + +public class DummyConsensus implements RelayNetworkStatusConsensus { + + public byte[] getRawDescriptorBytes() { + return null; + } + + public List<String> getAnnotations() { + return null; + } + + public List<String> getUnrecognizedLines() { + return null; + } + + public int getNetworkStatusVersion() { + return 0; + } + + public String getConsensusFlavor() { + return null; + } + + public int getConsensusMethod() { + return 0; + } + + private long validAfterMillis; + public void setValidAfterMillis(long validAfterMillis) { + this.validAfterMillis = validAfterMillis; + } + public long getValidAfterMillis() { + return this.validAfterMillis; + } + + public long getFreshUntilMillis() { + return 0; + } + + public long getValidUntilMillis() { + return 0; + } + + public long getVoteSeconds() { + return 0; + } + + public long getDistSeconds() { + return 0; + } + + public List<String> getRecommendedServerVersions() { + return null; + } + + public List<String> getRecommendedClientVersions() { + return null; + } + + public SortedSet<String> getKnownFlags() { + return null; + } + + public SortedMap<String, Integer> getConsensusParams() { + return null; + } + + public SortedMap<String, DirSourceEntry> getDirSourceEntries() { + return null; + } + + private SortedMap<String, NetworkStatusEntry> statusEntries = + new TreeMap<String, NetworkStatusEntry>(); + public void addStatusEntry(NetworkStatusEntry statusEntry) { + this.statusEntries.put(statusEntry.getFingerprint(), statusEntry); + } + public SortedMap<String, NetworkStatusEntry> getStatusEntries() { + return this.statusEntries; + } + + public boolean containsStatusEntry(String fingerprint) { + return false; + } + + public NetworkStatusEntry getStatusEntry(String fingerprint) { + return null; + } + + public SortedMap<String, DirectorySignature> getDirectorySignatures() { + return null; + } + + public SortedMap<String, Integer> getBandwidthWeights() { + return null; + } + + public String getConsensusDigest() { + return null; + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/DummyDescriptorSource.java b/src/test/java/org/torproject/onionoo/updater/DummyDescriptorSource.java new file mode 100644 index 0000000..3664e25 --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/DummyDescriptorSource.java @@ -0,0 +1,90 @@ +package org.torproject.onionoo.updater; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.torproject.descriptor.Descriptor; +import org.torproject.onionoo.updater.DescriptorListener; +import org.torproject.onionoo.updater.DescriptorSource; +import org.torproject.onionoo.updater.DescriptorType; + +public class DummyDescriptorSource extends DescriptorSource { + + private Map<DescriptorType, Set<Descriptor>> descriptors = + new HashMap<DescriptorType, Set<Descriptor>>(); + + public void provideDescriptors(DescriptorType descriptorType, + Collection<Descriptor> descriptors) { + for (Descriptor descriptor : descriptors) { + this.addDescriptor(descriptorType, descriptor); + } + } + + public void addDescriptor(DescriptorType descriptorType, + Descriptor descriptor) { + this.getDescriptorsByType(descriptorType).add(descriptor); + } + + private Set<Descriptor> getDescriptorsByType( + DescriptorType descriptorType) { + if (!this.descriptors.containsKey(descriptorType)) { + this.descriptors.put(descriptorType, new HashSet<Descriptor>()); + } + return this.descriptors.get(descriptorType); + } + + private Map<DescriptorType, Set<DescriptorListener>> + descriptorListeners = new HashMap<DescriptorType, + Set<DescriptorListener>>(); + + public void registerDescriptorListener(DescriptorListener listener, + DescriptorType descriptorType) { + if (!this.descriptorListeners.containsKey(descriptorType)) { + this.descriptorListeners.put(descriptorType, + new HashSet<DescriptorListener>()); + } + this.descriptorListeners.get(descriptorType).add(listener); + } + + public void readDescriptors() { + Set<DescriptorType> descriptorTypes = new HashSet<DescriptorType>(); + descriptorTypes.addAll(this.descriptorListeners.keySet()); + for (DescriptorType descriptorType : descriptorTypes) { + boolean relay; + switch (descriptorType) { + case RELAY_CONSENSUSES: + case RELAY_SERVER_DESCRIPTORS: + case RELAY_EXTRA_INFOS: + case EXIT_LISTS: + relay = true; + break; + case BRIDGE_STATUSES: + case BRIDGE_SERVER_DESCRIPTORS: + case BRIDGE_EXTRA_INFOS: + case BRIDGE_POOL_ASSIGNMENTS: + default: + relay = false; + break; + } + if (this.descriptors.containsKey(descriptorType) && + this.descriptorListeners.containsKey(descriptorType)) { + Set<DescriptorListener> listeners = + this.descriptorListeners.get(descriptorType); + for (Descriptor descriptor : + this.getDescriptorsByType(descriptorType)) { + for (DescriptorListener listener : listeners) { + listener.processDescriptor(descriptor, relay); + } + } + } + } + } + + public void writeHistoryFiles() { + /* Nothing to do here. */ + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/DummyStatusEntry.java b/src/test/java/org/torproject/onionoo/updater/DummyStatusEntry.java new file mode 100644 index 0000000..64ef73f --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/DummyStatusEntry.java @@ -0,0 +1,92 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.updater; + +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.torproject.descriptor.NetworkStatusEntry; + +public class DummyStatusEntry implements NetworkStatusEntry { + + public DummyStatusEntry(String fingerprint) { + this.fingerprint = fingerprint; + } + + public byte[] getStatusEntryBytes() { + return null; + } + + @Override + public String getNickname() { + return null; + } + + private String fingerprint; + public String getFingerprint() { + return this.fingerprint; + } + + public String getDescriptor() { + return null; + } + + public long getPublishedMillis() { + return 0; + } + + public String getAddress() { + return null; + } + + public int getOrPort() { + return 0; + } + + public int getDirPort() { + return 0; + } + + public Set<String> getMicrodescriptorDigests() { + return null; + } + + public List<String> getOrAddresses() { + return null; + } + + private SortedSet<String> flags = new TreeSet<String>(); + public void addFlag(String flag) { + this.flags.add(flag); + } + public SortedSet<String> getFlags() { + return this.flags; + } + + public String getVersion() { + return null; + } + + public long getBandwidth() { + return 0; + } + + public long getMeasured() { + return 0; + } + + public boolean getUnmeasured() { + return false; + } + + public String getDefaultPolicy() { + return null; + } + + public String getPortList() { + return null; + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/LookupServiceTest.java b/src/test/java/org/torproject/onionoo/updater/LookupServiceTest.java new file mode 100644 index 0000000..9275fbf --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/LookupServiceTest.java @@ -0,0 +1,596 @@ +/* Copyright 2013 The Tor Project + * See LICENSE for licensing information */ + +package org.torproject.onionoo.updater; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.torproject.onionoo.updater.LookupResult; +import org.torproject.onionoo.updater.LookupService; + +public class LookupServiceTest { + + private List<String> geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, geoipASNum2Lines; + + private LookupService lookupService; + + private SortedSet<String> addressStrings = new TreeSet<String>(); + + private SortedMap<String, LookupResult> lookupResults; + + private void populateLines() { + this.geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + this.geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + this.geoLite2CityBlocksIPv4Lines.add("8.8.0.0/21,6252001,6252001,,0," + + "0,,38.0000,-97.0000"); + this.geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,5375480,6252001,,0," + + "0,94035,37.3860,-122.0838"); + this.geoLite2CityBlocksIPv4Lines.add("8.8.9.0/24,6252001,6252001,,0," + + "0,,38.0000,-97.0000"); + this.geoLite2CityLocationsEnLines = new ArrayList<String>(); + this.geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + this.geoLite2CityLocationsEnLines.add("6252001,en,NA," + + ""North America",US,"United States",,,,,,,"); + this.geoLite2CityLocationsEnLines.add("5375480,en,NA," + + ""North America",US,"United States",CA,California,,," + + ""Mountain View",807,America/Los_Angeles"); + this.geoipASNum2Lines = new ArrayList<String>(); + this.geoipASNum2Lines.add("134743296,134744063,"AS3356 Level 3 " + + "Communications""); + this.geoipASNum2Lines.add("134744064,134744319,"AS15169 Google " + + "Inc.""); + this.geoipASNum2Lines.add("134744320,134750463,"AS3356 Level 3 " + + "Communications""); + } + + private void writeCsvFiles() { + try { + this.writeCsvFile(this.geoLite2CityBlocksIPv4Lines, + "GeoLite2-City-Blocks-IPv4.csv"); + this.writeCsvFile(this.geoLite2CityLocationsEnLines, + "GeoLite2-City-Locations-en.csv"); + this.writeCsvFile(this.geoipASNum2Lines, "GeoIPASNum2.csv"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void writeCsvFile(List<String> lines, String fileName) + throws IOException { + if (lines != null && !lines.isEmpty()) { + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(new File(this.tempGeoipDir, fileName)), + "UTF-8")); + for (String line : lines) { + bw.write(line + "\n"); + } + bw.close(); + } + } + + private void performLookups() { + this.lookupService = new LookupService(this.tempGeoipDir); + this.lookupResults = this.lookupService.lookup(this.addressStrings); + } + + private void assertLookupResult(List<String> geoLite2CityBlocksLines, + List<String> geoLite2CityLocationsLines, + List<String> geoipASNum2Lines, String addressString, + String countryCode, String countryName, String regionName, + String cityName, Float latitude, Float longitude, String aSNumber, + String aSName) { + this.addressStrings.add(addressString); + this.populateLines(); + if (geoLite2CityBlocksLines != null) { + this.geoLite2CityBlocksIPv4Lines = geoLite2CityBlocksLines; + } + if (geoLite2CityLocationsLines != null) { + this.geoLite2CityLocationsEnLines = geoLite2CityLocationsLines; + } + if (geoipASNum2Lines != null) { + this.geoipASNum2Lines = geoipASNum2Lines; + } + this.writeCsvFiles(); + /* Disable log messages printed to System.err. */ + System.setErr(new PrintStream(new OutputStream() { + public void write(int b) { + } + })); + this.performLookups(); + if (countryCode == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getCountryCode() == null); + } else { + assertEquals(countryCode, + this.lookupResults.get(addressString).getCountryCode()); + } + if (countryName == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getCountryName() == null); + } else { + assertEquals(countryName, + this.lookupResults.get(addressString).getCountryName()); + } + if (regionName == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getRegionName() == null); + } else { + assertEquals(regionName, + this.lookupResults.get(addressString).getRegionName()); + } + if (cityName == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getCityName() == null); + } else { + assertEquals(cityName, + this.lookupResults.get(addressString).getCityName()); + } + if (latitude == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getLatitude() == null); + } else { + assertEquals(latitude, + this.lookupResults.get(addressString).getLatitude(), 0.01); + } + if (longitude == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getLongitude() == null); + } else { + assertEquals(longitude, + this.lookupResults.get(addressString).getLongitude(), 0.01); + } + if (aSNumber == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getAsNumber() == null); + } else { + assertEquals(aSNumber, + this.lookupResults.get(addressString).getAsNumber()); + } + if (aSName == null) { + assertTrue(!this.lookupResults.containsKey(addressString) || + this.lookupResults.get(addressString).getAsName() == null); + } else { + assertEquals(aSName, + this.lookupResults.get(addressString).getAsName()); + } + } + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + private File tempGeoipDir; + + @Before + public void createTempGeoipDir() throws IOException { + this.tempGeoipDir = this.tempFolder.newFolder("geoip"); + } + + @Test() + public void testLookup8888() { + this.assertLookupResult(null, null, null, "8.8.8.8", "us", + "United States", "California", "Mountain View", 37.3860f, + -122.0838f, "AS15169", "Google Inc."); + } + + @Test() + public void testLookup8880() { + this.assertLookupResult(null, null, null, "8.8.8.0", "us", + "United States", "California", "Mountain View", 37.3860f, + -122.0838f, "AS15169", "Google Inc."); + } + + @Test() + public void testLookup888255() { + this.assertLookupResult(null, null, null, "8.8.8.255", "us", + "United States", "California", "Mountain View", 37.3860f, + -122.0838f, "AS15169", "Google Inc."); + } + + @Test() + public void testLookup888256() { + this.assertLookupResult(null, null, null, "8.8.8.256", null, null, + null, null, null, null, null, null); + } + + @Test() + public void testLookup888Minus1() { + this.assertLookupResult(null, null, null, "8.8.8.-1", null, null, + null, null, null, null, null, null); + } + + @Test() + public void testLookup000() { + this.assertLookupResult(null, null, null, "0.0.0.0", null, null, null, + null, null, null, null, null); + } + + @Test() + public void testLookupNoBlocksLines() { + this.assertLookupResult(new ArrayList<String>(), null, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupNoLocationLines() { + this.assertLookupResult(null, new ArrayList<String>(), null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupNoGeoipASNum2Lines() { + this.assertLookupResult(null, null, new ArrayList<String>(), + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupNoCorrespondingLocation() { + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("6252001,en,NA," + + ""North America",US,"United States",,,,,,,"); + this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, + "8.8.8.8", null, null, null, null, 37.3860f, -122.0838f, + "AS15169", "Google Inc."); + } + + @Test() + public void testLookupBlocksStartNotANumber() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("one/24,5375480,6252001,,0," + + "0,94035,37.3860,-122.0838"); + this.assertLookupResult( + geoLite2CityBlocksIPv4Lines, null, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupBlocksLocationX() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,X,X,,0,0,94035,37.3860," + + "-122.0838"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupBlocksLocationEmpty() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,,,,0,0,,,"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, + "8.8.8.8", null, null, null, null, null, null, "AS15169", + "Google Inc."); + } + + @Test() + public void testLookupBlocksTooFewFields() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("8.8.8.0/24,5375480,6252001,,0," + + "0,94035,37.3860"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, null, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupLocationLocIdNotANumber() { + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("threetwoonenineone,en,NA," + + ""North America",US,"United States",CA,California,,," + + ""Mountain View",807,America/Los_Angeles"); + this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupLocationTooFewFields() { + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("threetwoonenineone,en,NA," + + ""North America",US,"United States",CA,California,,," + + ""Mountain View",807"); + this.assertLookupResult(null, geoLite2CityLocationsEnLines, null, + "8.8.8.8", null, null, null, null, null, null, null, null); + } + + @Test() + public void testLookupGeoipASNum2EndBeforeStart() { + List<String> geoipASNum2Lines = new ArrayList<String>(); + geoipASNum2Lines.add("134743296,134744063,"AS3356 Level 3 " + + "Communications""); + geoipASNum2Lines.add("134744319,134744064,"AS15169 Google Inc.""); + geoipASNum2Lines.add("134744320,134750463,"AS3356 Level 3 " + + "Communications""); + this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", "us", + "United States", "California", "Mountain View", 37.3860f, + -122.0838f, null, null); + } + + @Test() + public void testLookupGeoipASNum2StartNotANumber() { + List<String> geoipASNum2Lines = new ArrayList<String>(); + geoipASNum2Lines.add("one,134744319,"AS15169 Google Inc.""); + this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, + null, null, null, null, null, null, null); + } + + @Test() + public void testLookupGeoipASNum2StartTooLarge() { + List<String> geoipASNum2Lines = new ArrayList<String>(); + geoipASNum2Lines.add("1" + String.valueOf(Long.MAX_VALUE) + + ",134744319,"AS15169 Google Inc.""); + this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, + null, null, null, null, null, null, null); + } + + @Test() + public void testLookupGeoipASNum2TooFewFields() { + List<String> geoipASNum2Lines = new ArrayList<String>(); + geoipASNum2Lines.add("134744064,134744319"); + this.assertLookupResult(null, null, geoipASNum2Lines, "8.8.8.8", null, + null, null, null, null, null, null, null); + } + + @Test() + public void testLookupLocationTurkey() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("46.1.133.0/24,307515,298795,,0,0,," + + "39.1458,34.1639"); + geoLite2CityBlocksIPv4Lines.add("46.196.12.0/24,738927,298795,,0,0,," + + "40.9780,27.5085"); + geoLite2CityBlocksIPv4Lines.add("78.180.14.0/24,745169,298795,,0,0,," + + "40.0781,29.5133"); + geoLite2CityBlocksIPv4Lines.add("81.215.1.0/24,749748,298795,,0,0,," + + "40.6000,33.6153"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("307515,en,AS,Asia,TR,Turkey,40," + + ""K\u0131r\u015Fehir",,,"K\u0131r\u015Fehir",," + + "Europe/Istanbul"); + geoLite2CityLocationsEnLines.add("738927,en,AS,Asia,TR,Turkey,59," + + ""Tekirda\u011F",,,"Tekirda\u011F",,Europe/Istanbul"); + geoLite2CityLocationsEnLines.add("745169,en,AS,Asia,TR,Turkey,16," + + "Bursa,,,\u0130neg\u00F6l,,Europe/Istanbul"); + geoLite2CityLocationsEnLines.add("749748,en,AS,Asia,TR,Turkey,18," + + ""\u00C7ank\u0131r\u0131",,,"\u00C7ank\u0131r\u0131",," + + "Europe/Istanbul"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "46.1.133.0", "tr", "Turkey", + "K\u0131r\u015Fehir", "K\u0131r\u015Fehir", 39.1458f, 34.1639f, + null, null); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "46.196.12.0", "tr", "Turkey", + "Tekirda\u011F", "Tekirda\u011F", 40.9780f, 27.5085f, null, null); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "78.180.14.0", "tr", "Turkey", + "Bursa", "\u0130neg\u00F6l", 40.0781f, 29.5133f, null, null); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "81.215.1.0", "tr", "Turkey", + "\u00C7ank\u0131r\u0131", "\u00C7ank\u0131r\u0131", 40.6000f, + 33.6153f, null, null); + } + + @Test() + public void testLookupLocationLatvia() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("78.28.192.0/24,456202,458258,,0,0,," + + "56.5000,27.3167"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("456202,en,EU,Europe,LV,Latvia,REZ," + + "Rezekne,,,"R\u0113zekne",,Europe/Riga"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "78.28.192.0", "lv", "Latvia", + "Rezekne", "R\u0113zekne", 56.5000f, 27.3167f, null, null); + } + + @Test() + public void testLookupLocationAzerbaijan() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("94.20.148.0/24,585170,587116,,0,0,," + + "41.1919,47.1706"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("585170,en,AS,Asia,AZ,Azerbaijan," + + "SAK,"Shaki City",,,"\u015E\u01DDki",,Asia/Baku"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "94.20.148.0", "az", + "Azerbaijan", "Shaki City", "\u015E\u01DDki", 41.1919f, 47.1706f, + null, null); + } + + @Test() + public void testLookupLocationVietnam() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("115.78.92.0/23,1587976,1562822,,0,0," + + ",10.2333,106.3833"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("1587976,en,AS,Asia,VN,Vietnam,50," + + ""Tinh Ben Tre",,,"B\u1EBFn Tre",,Asia/Ho_Chi_Minh"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "115.78.92.0", "vn", + "Vietnam", "Tinh Ben Tre", "B\u1EBFn Tre", 10.2333f, 106.3833f, + null, null); + } + + @Test() + public void testLookupLocationJapan() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("113.154.131.0/24,1848333,1861060,,0," + + "0,1012236,35.8000,139.1833"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("1848333,en,AS,Asia,JP,Japan,13," + + ""T\u014Dky\u014D",,,Yokoo,,Asia/Tokyo"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "113.154.131.0", "jp", + "Japan", "T\u014Dky\u014D", "Yokoo", 35.8000f, 139.1833f, null, + null); + } + + @Test() + public void testLookupLocationDenmark() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("2.110.246.0/24,2625001,2623032,,0,0," + + "5970,54.8880,10.4112"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("2625001,en,EU,Europe,DK,Denmark,83," + + ""South Denmark",,,"\u00C6r\u00F8sk\u00F8bing",," + + "Europe/Copenhagen"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "2.110.246.0", "dk", + "Denmark", "South Denmark", "\u00C6r\u00F8sk\u00F8bing", 54.8880f, + 10.4112f, null, null); + } + + @Test() + public void testLookupLocationGermany() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("37.209.30.128/25,2947444,2921044,,0," + + "0,,48.6833,9.0167"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("2947444,en,EU,Europe,DE,Germany,BW," + + ""Baden-W\u00FCrttemberg Region",,,B\u00F6blingen,," + + "Europe/Berlin"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "37.209.30.128", "de", + "Germany", "Baden-W\u00FCrttemberg Region", "B\u00F6blingen", + 48.6833f, 9.0167f, null, null); + } + + @Test() + public void testLookupLocationPoland() { + List<String> geoLite2CityBlocksIPv4Lines = new ArrayList<String>(); + geoLite2CityBlocksIPv4Lines.add("network,geoname_id," + + "registered_country_geoname_id,represented_country_geoname_id," + + "is_anonymous_proxy,is_satellite_provider,postal_code,latitude," + + "longitude"); + geoLite2CityBlocksIPv4Lines.add("5.185.94.0/24,3099434,798544,,0,0,," + + "54.3608,18.6583"); + List<String> geoLite2CityLocationsEnLines = new ArrayList<String>(); + geoLite2CityLocationsEnLines.add("geoname_id,locale_code," + + "continent_code,continent_name,country_iso_code,country_name," + + "subdivision_1_iso_code,subdivision_1_name," + + "subdivision_2_iso_code,subdivision_2_name,city_name," + + "metro_code,time_zone"); + geoLite2CityLocationsEnLines.add("3099434,en,EU,Europe,PL,Poland,PM," + + ""Pomeranian Voivodeship",,,"Gda\u0144sk",,Europe/Warsaw"); + this.assertLookupResult(geoLite2CityBlocksIPv4Lines, + geoLite2CityLocationsEnLines, null, "5.185.94.0", "pl", "Poland", + "Pomeranian Voivodeship", "Gda\u0144sk", 54.3608f, 18.6583f, null, + null); + } +} + diff --git a/src/test/java/org/torproject/onionoo/updater/UptimeStatusUpdaterTest.java b/src/test/java/org/torproject/onionoo/updater/UptimeStatusUpdaterTest.java new file mode 100644 index 0000000..e74dc5c --- /dev/null +++ b/src/test/java/org/torproject/onionoo/updater/UptimeStatusUpdaterTest.java @@ -0,0 +1,182 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.updater; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; +import org.torproject.onionoo.docs.DateTimeHelper; +import org.torproject.onionoo.docs.DocumentStoreFactory; +import org.torproject.onionoo.docs.DummyDocumentStore; +import org.torproject.onionoo.docs.UptimeHistory; +import org.torproject.onionoo.docs.UptimeStatus; + +public class UptimeStatusUpdaterTest { + + private DummyDescriptorSource descriptorSource; + + @Before + public void createDummyDescriptorSource() { + this.descriptorSource = new DummyDescriptorSource(); + DescriptorSourceFactory.setDescriptorSource(this.descriptorSource); + } + + private DummyDocumentStore documentStore; + + @Before + public void createDummyDocumentStore() { + this.documentStore = new DummyDocumentStore(); + DocumentStoreFactory.setDocumentStore(this.documentStore); + } + + @Test + public void testNoDescriptorsNoStatusFiles() { + UptimeStatusUpdater updater = new UptimeStatusUpdater(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + updater.updateStatuses(); + assertEquals("Without providing any data, nothing should be written " + + "to disk.", 0, + this.documentStore.getPerformedStoreOperations()); + } + + private static final long VALID_AFTER_SAMPLE = + DateTimeHelper.parse("2014-03-21 20:00:00"); + + private static final String GABELMOO_FINGERPRINT = + "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281"; + + private void addConsensusSample() { + DummyStatusEntry statusEntry = new DummyStatusEntry( + GABELMOO_FINGERPRINT); + statusEntry.addFlag("Running"); + DummyConsensus consensus = new DummyConsensus(); + consensus.setValidAfterMillis(VALID_AFTER_SAMPLE); + consensus.addStatusEntry(statusEntry); + this.descriptorSource.addDescriptor(DescriptorType.RELAY_CONSENSUSES, + consensus); + } + + @Test + public void testOneConsensusNoStatusFiles() { + this.addConsensusSample(); + UptimeStatusUpdater updater = new UptimeStatusUpdater(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + updater.updateStatuses(); + assertEquals("Two status files should have been written to disk.", + 2, this.documentStore.getPerformedStoreOperations()); + for (String fingerprint : new String[] { GABELMOO_FINGERPRINT, + null }) { + UptimeStatus status = this.documentStore.getDocument( + UptimeStatus.class, fingerprint); + UptimeHistory history = status.getRelayHistory().first(); + assertEquals("History must contain one entry.", 1, + status.getRelayHistory().size()); + assertEquals("History not for relay.", true, history.isRelay()); + assertEquals("History start millis not as expected.", + VALID_AFTER_SAMPLE, history.getStartMillis()); + assertEquals("History uptime hours must be 1.", 1, + history.getUptimeHours()); + } + } + + private static final String ALL_RELAYS_AND_BRIDGES_FINGERPRINT = null; + + private static final String ALL_RELAYS_AND_BRIDGES_UPTIME_SAMPLE = + "r 2013-07-22-17 5811\n" /* ends 2014-03-21 20:00:00 */ + + "b 2013-07-22-17 5811\n"; /* ends 2014-03-21 20:00:00 */ + + private void addAllRelaysAndBridgesUptimeSample() { + UptimeStatus uptimeStatus = new UptimeStatus(); + uptimeStatus.setFromDocumentString( + ALL_RELAYS_AND_BRIDGES_UPTIME_SAMPLE); + this.documentStore.addDocument(uptimeStatus, + ALL_RELAYS_AND_BRIDGES_FINGERPRINT); + } + + @Test + public void testOneConsensusOneStatusFiles() { + this.addAllRelaysAndBridgesUptimeSample(); + this.addConsensusSample(); + UptimeStatusUpdater updater = new UptimeStatusUpdater(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + updater.updateStatuses(); + assertEquals("Two status files should have been written to disk.", + 2, this.documentStore.getPerformedStoreOperations()); + UptimeStatus status = this.documentStore.getDocument( + UptimeStatus.class, ALL_RELAYS_AND_BRIDGES_FINGERPRINT); + assertEquals("Relay history must contain one entry", 1, + status.getRelayHistory().size()); + UptimeHistory history = status.getRelayHistory().first(); + assertEquals("History not for relay.", true, history.isRelay()); + assertEquals("History start millis not as expected.", + DateTimeHelper.parse("2013-07-22 17:00:00"), + history.getStartMillis()); + assertEquals("History uptime hours must be 5812.", 5812, + history.getUptimeHours()); + } + + private static final long PUBLISHED_SAMPLE = + DateTimeHelper.parse("2014-03-21 20:37:03"); + + private static final String NDNOP2_FINGERPRINT = + "DE6397A047ABE5F78B4C87AF725047831B221AAB"; + + private void addBridgeStatusSample() { + DummyStatusEntry statusEntry = new DummyStatusEntry( + NDNOP2_FINGERPRINT); + statusEntry.addFlag("Running"); + DummyBridgeStatus bridgeStatus = new DummyBridgeStatus(); + bridgeStatus.setPublishedMillis(PUBLISHED_SAMPLE); + bridgeStatus.addStatusEntry(statusEntry); + this.descriptorSource.addDescriptor(DescriptorType.BRIDGE_STATUSES, + bridgeStatus); + } + + @Test + public void testOneBridgeStatusNoStatusFiles() { + this.addBridgeStatusSample(); + UptimeStatusUpdater updater = new UptimeStatusUpdater(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + updater.updateStatuses(); + assertEquals("Two status files should have been written to disk.", + 2, this.documentStore.getPerformedStoreOperations()); + for (String fingerprint : new String[] { NDNOP2_FINGERPRINT, + null }) { + UptimeStatus status = this.documentStore.getDocument( + UptimeStatus.class, fingerprint); + UptimeHistory history = status.getBridgeHistory().first(); + assertEquals("Bridge history must contain one entry.", 1, + status.getBridgeHistory().size()); + assertEquals("History not for bridge.", false, history.isRelay()); + assertEquals("History start millis not as expected.", + DateTimeHelper.parse("2014-03-21 20:00:00"), + history.getStartMillis()); + assertEquals("History uptime hours must be 1.", 1, + history.getUptimeHours()); + } + } + + @Test + public void testOneBridgeStatusOneStatusFiles() { + this.addAllRelaysAndBridgesUptimeSample(); + this.addBridgeStatusSample(); + UptimeStatusUpdater updater = new UptimeStatusUpdater(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + updater.updateStatuses(); + assertEquals("Two status files should have been written to disk.", + 2, this.documentStore.getPerformedStoreOperations()); + UptimeStatus status = this.documentStore.getDocument( + UptimeStatus.class, ALL_RELAYS_AND_BRIDGES_FINGERPRINT); + assertEquals("Bridge history must contain one entry.", 1, + status.getBridgeHistory().size()); + UptimeHistory history = status.getBridgeHistory().last(); + assertEquals("History not for bridge.", false, history.isRelay()); + assertEquals("History start millis not as expected.", + DateTimeHelper.parse("2013-07-22 17:00:00"), + history.getStartMillis()); + assertEquals("History uptime hours must be 5812.", 5812, + history.getUptimeHours()); + } +} + diff --git a/src/test/java/org/torproject/onionoo/util/DummyTime.java b/src/test/java/org/torproject/onionoo/util/DummyTime.java new file mode 100644 index 0000000..ec7a50f --- /dev/null +++ b/src/test/java/org/torproject/onionoo/util/DummyTime.java @@ -0,0 +1,16 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.util; + +import org.torproject.onionoo.util.Time; + +public class DummyTime extends Time { + private long currentTimeMillis; + public DummyTime(long currentTimeMillis) { + this.currentTimeMillis = currentTimeMillis; + } + public long currentTimeMillis() { + return this.currentTimeMillis; + } +} + diff --git a/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java new file mode 100644 index 0000000..517efc0 --- /dev/null +++ b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java @@ -0,0 +1,262 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.onionoo.writer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.torproject.onionoo.docs.DateTimeHelper; +import org.torproject.onionoo.docs.DocumentStoreFactory; +import org.torproject.onionoo.docs.DummyDocumentStore; +import org.torproject.onionoo.docs.GraphHistory; +import org.torproject.onionoo.docs.UptimeDocument; +import org.torproject.onionoo.docs.UptimeStatus; +import org.torproject.onionoo.updater.DescriptorSourceFactory; +import org.torproject.onionoo.updater.DummyDescriptorSource; +import org.torproject.onionoo.util.DummyTime; +import org.torproject.onionoo.util.TimeFactory; + +public class UptimeDocumentWriterTest { + + private static final long TEST_TIME = DateTimeHelper.parse( + "2014-03-23 12:00:00"); + + private DummyTime dummyTime; + + @Before + public void createDummyTime() { + this.dummyTime = new DummyTime(TEST_TIME); + TimeFactory.setTime(this.dummyTime); + } + + private DummyDescriptorSource descriptorSource; + + @Before + public void createDummyDescriptorSource() { + this.descriptorSource = new DummyDescriptorSource(); + DescriptorSourceFactory.setDescriptorSource(this.descriptorSource); + } + + private DummyDocumentStore documentStore; + + @Before + public void createDummyDocumentStore() { + this.documentStore = new DummyDocumentStore(); + DocumentStoreFactory.setDocumentStore(this.documentStore); + } + + @Test + public void testNoStatuses() { + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + writer.writeDocuments(); + assertEquals("Without providing any data, nothing should be written " + + "to disk.", 0, + this.documentStore.getPerformedStoreOperations()); + } + + private static final String ALL_RELAYS_FINGERPRINT = null; + + private static final String GABELMOO_FINGERPRINT = + "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281"; + + private void addStatusOneWeekSample(String allRelaysUptime, + String gabelmooUptime) { + UptimeStatus status = new UptimeStatus(); + status.setFromDocumentString(allRelaysUptime); + this.documentStore.addDocument(status, ALL_RELAYS_FINGERPRINT); + status = new UptimeStatus(); + status.setFromDocumentString(gabelmooUptime); + this.documentStore.addDocument(status, GABELMOO_FINGERPRINT); + } + + private static final long ONE_SECOND = 1000L, + ONE_HOUR = 60L * 60L * ONE_SECOND, FOUR_HOURS = 4L * ONE_HOUR; + + private void assertOneWeekGraph(UptimeDocument document, int graphs, + String first, String last, int count, List<Integer> values) { + this.assertGraph(document, graphs, "1_week", first, last, + (int) (ONE_HOUR / ONE_SECOND), count, values); + } + + private void assertOneMonthGraph(UptimeDocument document, int graphs, + String first, String last, int count, List<Integer> values) { + this.assertGraph(document, graphs, "1_month", first, last, + (int) (FOUR_HOURS / ONE_SECOND), count, values); + } + + private void assertGraph(UptimeDocument document, int graphs, + String graphName, String first, String last, int interval, + int count, List<Integer> values) { + assertEquals("Should contain exactly " + graphs + " graphs.", graphs, + document.getUptime().size()); + assertTrue("Should contain a graph for " + graphName + ".", + document.getUptime().containsKey(graphName)); + GraphHistory history = document.getUptime().get(graphName); + assertEquals("First data point should be " + first + ".", + DateTimeHelper.parse(first), history.getFirst()); + assertEquals("Last data point should be " + last + ".", + DateTimeHelper.parse(last), history.getLast()); + assertEquals("Interval should be " + interval + " seconds.", interval, + (int) history.getInterval()); + assertEquals("Factor should be 1.0 / 999.0.", 1.0 / 999.0, + (double) history.getFactor(), 0.01); + assertEquals("There should be one data point per hour.", count, + (int) history.getCount()); + assertEquals("Count should be the same as the number of values.", + count, history.getValues().size()); + if (values == null) { + for (int value : history.getValues()) { + assertEquals("All values should be 999.", 999, value); + } + } else { + assertEquals("Values are not as expected.", values, + history.getValues()); + } + } + + @Test + public void testOneHourUptime() { + this.addStatusOneWeekSample("r 2014-03-23-11 1\n", + "r 2014-03-23-11 1\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + assertEquals("Should not contain any graph.", 0, + document.getUptime().size()); + } + + @Test + public void testTwoHoursUptime() { + this.addStatusOneWeekSample("r 2014-03-23-10 2\n", + "r 2014-03-23-10 2\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneWeekGraph(document, 1, "2014-03-23 10:30:00", + "2014-03-23 11:30:00", 2, null); + } + + @Test + public void testTwoHoursUptimeSeparatedByNull() { + this.addStatusOneWeekSample("r 2014-03-23-09 1\nr 2014-03-23-11 1\n", + "r 2014-03-23-09 1\nr 2014-03-23-11 1\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + assertEquals("Should not contain any graph.", 0, + document.getUptime().size()); + } + + @Test + public void testTwoHoursUptimeSeparatedByZero() { + this.addStatusOneWeekSample("r 2014-03-23-09 3\n", + "r 2014-03-23-09 1\nr 2014-03-23-11 1\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneWeekGraph(document, 1, "2014-03-23 09:30:00", + "2014-03-23 11:30:00", 3, + Arrays.asList(new Integer[] { 999, 0, 999 })); + } + + @Test + public void testTwoHoursUptimeThenDowntime() { + this.addStatusOneWeekSample("r 2014-03-23-09 3\n", + "r 2014-03-23-09 2\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneWeekGraph(document, 1, "2014-03-23 09:30:00", + "2014-03-23 11:30:00", 3, + Arrays.asList(new Integer[] { 999, 999, 0 })); + } + + @Test + public void testOneWeekUptime() { + this.addStatusOneWeekSample("r 2014-03-16-12 168\n", + "r 2014-03-16-12 168\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneWeekGraph(document, 1, "2014-03-16 12:30:00", + "2014-03-23 11:30:00", 168, null); + } + + @Test + public void testOneWeekOneHourUptime() { + this.addStatusOneWeekSample("r 2014-03-16-11 169\n", + "r 2014-03-16-11 169\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneWeekGraph(document, 2, "2014-03-16 12:30:00", + "2014-03-23 11:30:00", 168, null); + this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", + "2014-03-23 10:00:00", 43, null); + } + + @Test + public void testOneMonthPartialIntervalOnline() { + this.addStatusOneWeekSample("r 2014-03-16-08 8\n", + "r 2014-03-16-11 5\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", + "2014-03-16 14:00:00", 2, null); + } + + @Test + public void testOneMonthPartialIntervalOnOff() { + this.addStatusOneWeekSample("r 2014-03-16-08 8\n", + "r 2014-03-16-10 1\nr 2014-03-16-12 1\n"); + UptimeDocumentWriter writer = new UptimeDocumentWriter(); + DescriptorSourceFactory.getDescriptorSource().readDescriptors(); + writer.writeDocuments(); + assertEquals("Should write exactly one document.", 1, + this.documentStore.getPerformedStoreOperations()); + UptimeDocument document = this.documentStore.getDocument( + UptimeDocument.class, GABELMOO_FINGERPRINT); + this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00", + "2014-03-16 14:00:00", 2, + Arrays.asList(new Integer[] { 499, 249 })); + } +} +
tor-commits@lists.torproject.org