commit 7af8ed0d62b60ffc9a066ba64980deb2f3036af3 Author: Isis Lovecruft isis@torproject.org Date: Fri Dec 5 09:31:17 2014 +0000
Add unittest for parsing extrainfo files without validation. --- lib/bridgedb/test/test_parse_descriptors.py | 128 +++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 16 deletions(-)
diff --git a/lib/bridgedb/test/test_parse_descriptors.py b/lib/bridgedb/test/test_parse_descriptors.py index 5ed6f2f..67bef6a 100644 --- a/lib/bridgedb/test/test_parse_descriptors.py +++ b/lib/bridgedb/test/test_parse_descriptors.py @@ -11,6 +11,7 @@
from __future__ import print_function
+import datetime import io import os import textwrap @@ -21,7 +22,7 @@ HAS_STEM = False
try: from stem.descriptor.server_descriptor import RelayDescriptor - from stem.descriptor.extrainfo_descriptor import BridgeExtraInfoDescriptor + from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor from stem.descriptor.router_status_entry import RouterStatusEntryV3 from bridgedb.parse import descriptors except (ImportError, NameError), error: @@ -142,6 +143,37 @@ U36EY4UoN5ABPowhNZFeyr5A3vKiDr6j0hCOqYOhxPY= -----END SIGNATURE----- '''
+BRIDGE_EXTRA_INFO_DESCRIPTOR_NEWEST_DUPLICATE = '''\ +extra-info MiserLandfalls E08B324D20AD0A13E114F027AB9AC3F32CA696A0 +published 2014-12-04 03:10:25 +write-history 2014-12-04 03:10:25 (900 s) 3188736,2226176,2866176,2226176 +read-history 2014-12-04 03:10:25 (900 s) 3891200,2483200,2698240,2483200 +dirreq-write-history 2014-12-04 03:10:25 (900 s) 1024,0,2048,3072 +dirreq-read-history 2014-12-04 03:10:25 (900 s) 0,0,0,0 +geoip-db-digest 09A0E093100B279AD9CFF47A67B13A21C6E1483F +geoip6-db-digest E983833985E4BCA34CEF611B2DF51942D188E638 +dirreq-stats-end 2014-12-04 03:10:25 (86400 s) +dirreq-v3-ips +dirreq-v3-reqs +dirreq-v3-resp ok=16,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=0,busy=0 +dirreq-v3-direct-dl complete=0,timeout=0,running=0 +dirreq-v3-tunneled-dl complete=12,timeout=0,running=0 +transport obfs3 2.215.61.223:4057 +transport obfs2 2.215.61.223:4058 +transport scramblesuit 2.215.61.223:4059 password=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 +transport obfs4 2.215.61.223:4060 iat-mode=0,node-id=19a448c01aa2e7d55979473b647e282459995b85,public-key=7a61b53701befdae0eeeffaecc73f14e20b537bb0f8b91ad7c2936dc63562b25 +bridge-stats-end 2014-12-04 03:10:25 (86400 s) +bridge-ips ca=8 +bridge-ip-versions v4=8,v6=0 +bridge-ip-transports <OR>=8 +router-signature +-----BEGIN SIGNATURE----- +KOXNPCoe+Q+thFA/Lz7RTja2tWp4oC6SvyIooEZibHtEDgiXuU4sELWT4bSOk3np +RVmu7QPMmNybx4LHowq3pOeNLtJzpWg8Pfo+N6tR+K4nqPwBRmpsuDhCD/tIXJlP +U36EY4UoN5ABPowhNZFeyr5A3vKiDr6j0hCOqYOhxPY= +-----END SIGNATURE----- +''' +
class ParseDescriptorsTests(unittest.TestCase): """Unittests for :class:`bridgedb.parse.descriptors` module.""" @@ -150,6 +182,11 @@ class ParseDescriptorsTests(unittest.TestCase):
def setUp(self): """Test if we have Stem installed. Skip these tests if it's missing.""" + self.expectedIPBridge0 = '2.215.61.223' + self.expectedIPBridge1 = '80.44.173.87' + + self.expectedFprBridge0 = 'E08B324D20AD0A13E114F027AB9AC3F32CA696A0' + if self.skip: raise unittest.SkipTest("Couldn't import Stem.")
@@ -177,9 +214,8 @@ class ParseDescriptorsTests(unittest.TestCase): self.assertIsInstance(routers, list) bridge = routers[0] self.assertIsInstance(bridge, RelayDescriptor) - self.assertEqual(bridge.address, u'152.78.9.20') - self.assertEqual(bridge.fingerprint, - u'6FA9216CF3A06E89A03121ACC31F70F8DFD7DDCC') + self.assertEqual(bridge.address, self.expectedIPBridge0) + self.assertEqual(bridge.fingerprint, self.expectedFprBridge0)
def test_parse_descriptors_parseBridgeNetworkStatusFile_return_type(self): """``b.p.descriptors.parseNetworkStatusFile`` should return a dict.""" @@ -203,7 +239,7 @@ class ParseDescriptorsTests(unittest.TestCase): bridge = routers[0] self.assertIsInstance(bridge, RouterStatusEntryV3)
- def test_parse_descriptors_parseBridgeNetworkStatusFile_1(self): + def test_parse_descriptors_parseBridgeNetworkStatusFile_one_file(self): """Test ``b.p.descriptors.parseNetworkStatusFile`` with one bridge networkstatus descriptor. """ @@ -213,14 +249,15 @@ class ParseDescriptorsTests(unittest.TestCase): BRIDGE_NETWORKSTATUS_0) routers = descriptors.parseNetworkStatusFile(descFile) bridge = routers[0] - self.assertEqual(bridge.address, u'152.78.9.20') - self.assertEqual(bridge.fingerprint, - u'6FA9216CF3A06E89A03121ACC31F70F8DFD7DDCC') + self.assertEqual(bridge.address, self.expectedIPBridge0) + self.assertEqual(bridge.fingerprint, self.expectedFprBridge0)
- def test_parse_descriptors_parseBridgeNetworkStatusFile_2(self): + def test_parse_descriptors_parseBridgeNetworkStatusFile_two_files(self): """Test ``b.p.descriptors.parseNetworkStatusFile`` with two bridge networkstatus descriptors. """ + expectedIPs = [self.expectedIPBridge0, self.expectedIPBridge1] + # Write the descriptor to a file for testing. This is necessary # because the function opens the networkstatus file to read it. descFile = self.writeTestDescriptorsToFile('networkstatus-bridges', @@ -228,9 +265,9 @@ class ParseDescriptorsTests(unittest.TestCase): BRIDGE_NETWORKSTATUS_1) routers = descriptors.parseNetworkStatusFile(descFile) bridge = routers[0] - self.assertEqual(bridge.address, u'152.78.9.20') - self.assertEqual(bridge.fingerprint, - u'6FA9216CF3A06E89A03121ACC31F70F8DFD7DDCC') + + self.assertIn(bridge.address, expectedIPs) + self.assertEqual(bridge.fingerprint, self.expectedFprBridge0)
def test_parse_descriptors_parseBridgeNetworkStatusFile_with_annotations(self): """Test ``b.p.descriptors.parseNetworkStatusFile`` with some document @@ -285,7 +322,7 @@ class ParseDescriptorsTests(unittest.TestCase): descFile = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR) routers = descriptors.parseBridgeExtraInfoFiles(descFile) bridge = routers.values()[0] - self.assertIsInstance(bridge, BridgeExtraInfoDescriptor) + self.assertIsInstance(bridge, RelayExtraInfoDescriptor)
def test_parse_descriptors_parseBridgeExtraInfoFiles_one_file(self): """Test for ``b.p.descriptors.parseBridgeExtraInfoFiles`` with only one @@ -300,8 +337,7 @@ class ParseDescriptorsTests(unittest.TestCase): self.assertEqual(len(bridge.transport), BRIDGE_EXTRA_INFO_DESCRIPTOR.count('transport '))
- self.assertEqual(bridge.fingerprint, - u'6FA9216CF3A06E89A03121ACC31F70F8DFD7DDCC') + self.assertEqual(bridge.fingerprint, self.expectedFprBridge0)
def test_parse_descriptors_deduplicate_identical_timestamps(self): """Parsing two descriptors for the same bridge with identical @@ -321,5 +357,65 @@ class ParseDescriptorsTests(unittest.TestCase): descFileOne = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR) descFileTwo = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR_NEWER_DUPLICATE) routers = descriptors.parseBridgeExtraInfoFiles(descFileOne, descFileTwo) + + # We shouldn't have duplicates: + self.assertEqual(len(routers), 1, + "We shouldn't have any duplicate descriptors.") + + # We should only have the newest descriptor: + bridge = routers.values()[0] + self.assertEqual( + bridge.published, + datetime.datetime.strptime("2014-11-04 08:10:25", "%Y-%m-%d %H:%M:%S"), + "We should have the newest available descriptor for this router.") + + def test_parse_descriptors_parseBridgeExtraInfoFiles_two_files_reverse(self): + """Test for ``b.p.descriptors.parseBridgeExtraInfoFiles`` with two bridge + extrainfo files. This time, they are processed in reverse to ensure + that we only keep the newer duplicates of descriptors, no matter what + order they appeared in the files. + """ + descFileOne = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR_NEWER_DUPLICATE) + descFileTwo = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR) + routers = descriptors.parseBridgeExtraInfoFiles(descFileOne, descFileTwo) + + self.assertEqual(len(routers), 1, + "We shouldn't have any duplicate descriptors.") + + bridge = routers.values()[0] + self.assertEqual( + bridge.published, + datetime.datetime.strptime("2014-11-04 08:10:25", "%Y-%m-%d %H:%M:%S"), + "We should have the newest available descriptor for this router.") + + def test_parse_descriptors_parseBridgeExtraInfoFiles_three_files(self): + """Test for ``b.p.descriptors.parseBridgeExtraInfoFiles`` with three + bridge extrainfo files, and check that only the newest extrainfo + descriptor is used. + """ + descFileOne = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR_NEWER_DUPLICATE) + descFileTwo = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR) + descFileThree = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR_NEWEST_DUPLICATE) + routers = descriptors.parseBridgeExtraInfoFiles(descFileOne, + descFileTwo, + descFileThree) + # We shouldn't have duplicates: - self.assertEqual(len(routers), 1) + self.assertEqual(len(routers), 1, + "We shouldn't have any duplicate descriptors.") + + # We should only have the newest descriptor: + bridge = routers.values()[0] + self.assertEqual( + bridge.published, + datetime.datetime.strptime("2014-12-04 03:10:25", "%Y-%m-%d %H:%M:%S"), + "We should have the newest available descriptor for this router.") + + def test_parse_descriptors_parseBridgeExtraInfoFiles_no_validate(self): + """Test for ``b.p.descriptors.parseBridgeExtraInfoFiles`` with + descriptor validation disabled. + """ + descFileOne = io.BytesIO(BRIDGE_EXTRA_INFO_DESCRIPTOR) + routers = descriptors.parseBridgeExtraInfoFiles(descFileOne, + validate=False) + self.assertGreaterEqual(len(routers), 1)
tor-commits@lists.torproject.org