commit 73ba530be8d7df7600e1b9a29df904de29a94831 Author: Damian Johnson atagar@torproject.org Date: Sat Mar 23 19:03:46 2013 -0700
Switching network status document routers to a dict
Changing the 'routers' attribute of NetworkStatusDocuments to a dict mapping fingerprints to the router status entry. This is generally far more convenient to work with - thanks to gsathya for the idea! --- stem/descriptor/networkstatus.py | 21 +++++--- test/integ/descriptor/networkstatus.py | 10 ++-- .../descriptor/networkstatus/bridge_document.py | 5 +- test/unit/descriptor/networkstatus/document_v2.py | 2 +- test/unit/descriptor/networkstatus/document_v3.py | 57 +++++++++++--------- 5 files changed, 52 insertions(+), 43 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py index c32a7ce..bad31d4 100644 --- a/stem/descriptor/networkstatus.py +++ b/stem/descriptor/networkstatus.py @@ -240,7 +240,7 @@ class NetworkStatusDocumentV2(NetworkStatusDocument): Version 2 network status document. These have been deprecated and are no longer generated by Tor.
- :var tuple routers: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV2` + :var dict routers: fingerprints to :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV2` contained in the document
:var int version: ***** document version @@ -291,14 +291,16 @@ class NetworkStatusDocumentV2(NetworkStatusDocument): document_file = io.BytesIO(raw_content) document_content = bytes.join(b"", stem.descriptor._read_until_keywords((ROUTERS_START, V2_FOOTER_START), document_file))
- self.routers = tuple(stem.descriptor.router_status_entry._parse_file( + router_iter = stem.descriptor.router_status_entry._parse_file( document_file, validate, entry_class = stem.descriptor.router_status_entry.RouterStatusEntryV2, entry_keyword = ROUTERS_START, section_end_keywords = (V2_FOOTER_START,), extra_args = (self,), - )) + ) + + self.routers = dict((desc.fingerprint, desc) for desc in router_iter)
document_content += b"\n" + document_file.read() document_content = stem.util.str_tools._to_unicode(document_content) @@ -490,14 +492,16 @@ class NetworkStatusDocumentV3(NetworkStatusDocument): else: router_type = stem.descriptor.router_status_entry.RouterStatusEntryMicroV3
- self.routers = tuple(stem.descriptor.router_status_entry._parse_file( + router_iter = stem.descriptor.router_status_entry._parse_file( document_file, validate, entry_class = router_type, entry_keyword = ROUTERS_START, section_end_keywords = (FOOTER_START, V2_FOOTER_START), extra_args = (self,), - )) + ) + + self.routers = dict((desc.fingerprint, desc) for desc in router_iter)
self._footer = _DocumentFooter(document_file, validate, self._header)
@@ -1414,7 +1418,6 @@ class BridgeNetworkStatusDocument(NetworkStatusDocument): def __init__(self, raw_content, validate = True): super(BridgeNetworkStatusDocument, self).__init__(raw_content)
- self.routers = None self.published = None
document_file = io.BytesIO(raw_content) @@ -1431,9 +1434,11 @@ class BridgeNetworkStatusDocument(NetworkStatusDocument): elif validate: raise ValueError("Bridge network status documents must start with a 'published' line:\n%s" % stem.util.str_tools._to_unicode(raw_content))
- self.routers = tuple(stem.descriptor.router_status_entry._parse_file( + router_iter = stem.descriptor.router_status_entry._parse_file( document_file, validate, entry_class = stem.descriptor.router_status_entry.RouterStatusEntryV2, extra_args = (self,), - )) + ) + + self.routers = dict((desc.fingerprint, desc) for desc in router_iter) diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py index 92a1973..7e07939 100644 --- a/test/integ/descriptor/networkstatus.py +++ b/test/integ/descriptor/networkstatus.py @@ -251,7 +251,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY= self.assertEquals(None, document.published) self.assertEquals([], document.get_unrecognized_lines())
- router = document.routers[0] + router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"] self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("F260ABF1297B445E04354E236F4159140FF7768F", router.digest) @@ -326,7 +326,7 @@ TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E=
self.assertEqual(3, len(document.routers))
- router1 = document.routers[0] + router1 = document.routers["719BE45DE224B607C53707D0E2143E2D423E74CF"] self.assertEquals("moria2", router1.nickname) self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", router1.fingerprint) self.assertEquals("B7F3F0975B87889DD1285FD57A1B1BB617F65432", router1.digest) @@ -336,7 +336,7 @@ TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E= self.assertEquals(80, router1.dir_port) self.assertEquals(set(["Authority", "Fast", "Named", "Running", "Valid", "V2Dir"]), set(router1.flags))
- router2 = document.routers[1] + router2 = document.routers["0928BA467056C4A689FEE4EF5D71482B6289C3D5"] self.assertEquals("stnv", router2.nickname) self.assertEquals("0928BA467056C4A689FEE4EF5D71482B6289C3D5", router2.fingerprint) self.assertEquals("22D1A7ED4199BDA7ED6C416EECD769C18E1F2A5A", router2.digest) @@ -346,7 +346,7 @@ TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E= self.assertEquals(None, router2.dir_port) self.assertEquals(set(["Named", "Valid"]), set(router2.flags))
- router3 = document.routers[2] + router3 = document.routers["09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968"] self.assertEquals("nggrplz", router3.nickname) self.assertEquals("09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968", router3.fingerprint) self.assertEquals("B302C2B01C94F398E3EF38939526B0651F824DD6", router3.digest) @@ -449,7 +449,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= self.assertEquals(datetime.datetime(2012, 7, 11, 23, 50, 1), document.published) self.assertEquals([], document.get_unrecognized_lines())
- router = document.routers[0] + router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"] self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("0799F806200B005F01E40A9A7F1A21C988AE8FB1", router.digest) diff --git a/test/unit/descriptor/networkstatus/bridge_document.py b/test/unit/descriptor/networkstatus/bridge_document.py index 97aeb0c..a40bd84 100644 --- a/test/unit/descriptor/networkstatus/bridge_document.py +++ b/test/unit/descriptor/networkstatus/bridge_document.py @@ -28,7 +28,7 @@ class TestBridgeNetworkStatusDocument(unittest.TestCase):
document = BridgeNetworkStatusDocument(b"published 2012-06-01 04:07:04") self.assertEqual(datetime.datetime(2012, 6, 1, 4, 7, 4), document.published) - self.assertEqual((), document.routers) + self.assertEqual({}, document.routers) self.assertEqual([], document.get_unrecognized_lines())
def test_document(self): @@ -40,6 +40,5 @@ class TestBridgeNetworkStatusDocument(unittest.TestCase): self.assertEqual(datetime.datetime(2012, 6, 1, 4, 7, 4), document.published)
self.assertEqual(2, len(document.routers)) - self.assertEqual("Unnamed", document.routers[0].nickname) - self.assertEqual("TolFuin", document.routers[1].nickname) + self.assertEqual(set(["Unnamed", "TolFuin"]), set([desc.nickname for desc in document.routers.values()])) self.assertEqual([], document.get_unrecognized_lines()) diff --git a/test/unit/descriptor/networkstatus/document_v2.py b/test/unit/descriptor/networkstatus/document_v2.py index 866e750..5c2dd26 100644 --- a/test/unit/descriptor/networkstatus/document_v2.py +++ b/test/unit/descriptor/networkstatus/document_v2.py @@ -16,7 +16,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
document = get_network_status_document_v2()
- self.assertEquals((), document.routers) + self.assertEquals({}, document.routers) self.assertEquals(2, document.version) self.assertEquals("18.244.0.114", document.hostname) self.assertEquals("18.244.0.114", document.address) diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py index f4b13af..4984e67 100644 --- a/test/unit/descriptor/networkstatus/document_v3.py +++ b/test/unit/descriptor/networkstatus/document_v3.py @@ -45,7 +45,7 @@ class TestNetworkStatusDocument(unittest.TestCase): Flag.FAST, Flag.GUARD, Flag.HSDIR, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.UNNAMED, Flag.V2DIR, Flag.VALID]
- self.assertEqual((), document.routers) + self.assertEqual({}, document.routers) self.assertEqual(3, document.version) self.assertEqual(None, document.version_flavor) self.assertEqual(True, document.is_consensus) @@ -81,7 +81,7 @@ class TestNetworkStatusDocument(unittest.TestCase): Flag.FAST, Flag.GUARD, Flag.HSDIR, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.UNNAMED, Flag.V2DIR, Flag.VALID]
- self.assertEqual((), document.routers) + self.assertEqual({}, document.routers) self.assertEqual(3, document.version) self.assertEqual(False, document.is_consensus) self.assertEqual(True, document.is_vote) @@ -120,7 +120,7 @@ class TestNetworkStatusDocument(unittest.TestCase): consensus = NetworkStatusDocumentV3(consensus_file.read()) consensus_file.close()
- for router in consensus.routers: + for router in consensus.routers.values(): self.assertEqual('caerSidi', router.nickname)
# second example: using stem.descriptor.parse_file @@ -139,7 +139,11 @@ class TestNetworkStatusDocument(unittest.TestCase): # document includes or excludes the router status entries as appropriate.
entry1 = get_router_status_entry_v3({'s': "Fast"}) - entry2 = get_router_status_entry_v3({'s': "Valid"}) + entry2 = get_router_status_entry_v3({ + 'r': "Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030", + 's': "Valid", + }) + content = get_network_status_document_v3(routers = (entry1, entry2), content = True)
descriptors = list(stem.descriptor.parse_file(io.BytesIO(content), 'network-status-consensus-3 1.0', document_handler = stem.descriptor.DocumentHandler.DOCUMENT)) @@ -792,10 +796,15 @@ class TestNetworkStatusDocument(unittest.TestCase): """
entry1 = get_router_status_entry_v3({'s': "Fast"}) - entry2 = get_router_status_entry_v3({'s': "Valid"}) + entry2 = get_router_status_entry_v3({ + 'r': "Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030", + 's': "Valid", + }) + document = get_network_status_document_v3(routers = (entry1, entry2))
- self.assertEquals((entry1, entry2), document.routers) + self.assertTrue(entry1 in document.routers.values()) + self.assertTrue(entry2 in document.routers.values())
# try with an invalid RouterStatusEntry
@@ -804,20 +813,15 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertRaises(ValueError, NetworkStatusDocumentV3, content) document = NetworkStatusDocumentV3(content, False) - self.assertEquals((entry3,), document.routers) + self.assertEquals([entry3], document.routers.values())
# try including with a microdescriptor consensus
- content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1, entry2), content = True) + content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1,), content = True) self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
- expected_routers = ( - RouterStatusEntryMicroV3(str(entry1), False), - RouterStatusEntryMicroV3(str(entry2), False), - ) - document = NetworkStatusDocumentV3(content, False) - self.assertEquals(expected_routers, document.routers) + self.assertEqual([RouterStatusEntryMicroV3(str(entry1), False)], document.routers.values())
def test_with_microdescriptor_router_status_entries(self): """ @@ -826,32 +830,33 @@ class TestNetworkStatusDocument(unittest.TestCase): """
entry1 = get_router_status_entry_micro_v3({'s': "Fast"}) - entry2 = get_router_status_entry_micro_v3({'s': "Valid"}) + entry2 = get_router_status_entry_micro_v3({ + 'r': "tornodeviennasil AcWxDFxrHetHYS5m6/MVt8ZN6AM 2013-03-13 22:09:13 78.142.142.246 443 80", + 's': "Valid", + }) + document = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1, entry2))
- self.assertEquals((entry1, entry2), document.routers) + self.assertTrue(entry1 in document.routers.values()) + self.assertTrue(entry2 in document.routers.values())
# try with an invalid RouterStatusEntry
entry3 = RouterStatusEntryMicroV3(get_router_status_entry_micro_v3({'r': "ugabuga"}, content = True), False) - content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry3,), content = True)
+ content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry3,), content = True) self.assertRaises(ValueError, NetworkStatusDocumentV3, content) + document = NetworkStatusDocumentV3(content, False) - self.assertEquals((entry3,), document.routers) + self.assertEquals([entry3], document.routers.values())
- # try including microdescriptor entries in a normal consensus + # try including microdescriptor entry in a normal consensus
- content = get_network_status_document_v3(routers = (entry1, entry2), content = True) + content = get_network_status_document_v3(routers = (entry1,), content = True) self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
- expected_routers = ( - RouterStatusEntryV3(str(entry1), False), - RouterStatusEntryV3(str(entry2), False), - ) - document = NetworkStatusDocumentV3(content, False) - self.assertEquals(expected_routers, document.routers) + self.assertEqual([RouterStatusEntryV3(str(entry1), False)], document.routers.values())
def test_with_directory_authorities(self): """
tor-commits@lists.torproject.org