[tor-commits] [stem/master] Switching network status document routers to a dict

atagar at torproject.org atagar at torproject.org
Sun Mar 24 02:26:58 UTC 2013


commit 73ba530be8d7df7600e1b9a29df904de29a94831
Author: Damian Johnson <atagar at 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):
     """





More information about the tor-commits mailing list