[tor-commits] [stem/master] Unit tests for minimal DirectoryAuthority instances

atagar at torproject.org atagar at torproject.org
Sat Oct 13 18:35:45 UTC 2012


commit 11070d9a91e0c00b4b5854fc935c5fc7a871e97f
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Sep 29 12:41:24 2012 -0700

    Unit tests for minimal DirectoryAuthority instances
    
    Adding unit tests for the minimal vote and consensus directory authority entry.
    Presently this is just exercising the old parsing code (which I broke in a few
    places during some of my earlier refactoring).
---
 run_tests.py                                       |    2 +
 stem/descriptor/networkstatus.py                   |   29 +++++++-----
 test/mocking.py                                    |   38 ++++++++++++++++
 test/unit/descriptor/networkstatus/__init__.py     |    2 +-
 .../networkstatus/directory_authority.py           |   47 ++++++++++++++++++++
 5 files changed, 105 insertions(+), 13 deletions(-)

diff --git a/run_tests.py b/run_tests.py
index 54e74b2..8f76dd3 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -21,6 +21,7 @@ import test.unit.descriptor.reader
 import test.unit.descriptor.server_descriptor
 import test.unit.descriptor.extrainfo_descriptor
 import test.unit.descriptor.networkstatus.entry
+import test.unit.descriptor.networkstatus.directory_authority
 import test.unit.descriptor.networkstatus.key_certificate
 import test.unit.descriptor.networkstatus.document
 import test.unit.response.control_line
@@ -118,6 +119,7 @@ UNIT_TESTS = (
   test.unit.descriptor.server_descriptor.TestServerDescriptor,
   test.unit.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor,
   test.unit.descriptor.networkstatus.entry.TestRouterStatusEntry,
+  test.unit.descriptor.networkstatus.directory_authority.TestDirectoryAuthority,
   test.unit.descriptor.networkstatus.key_certificate.TestKeyCertificate,
   test.unit.descriptor.networkstatus.document.TestNetworkStatusDocument,
   test.unit.exit_policy.rule.TestExitPolicyRule,
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 7c95f96..8147a26 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -699,6 +699,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
     
     self.nickname = None
     self.fingerprint = None
+    self.hostname = None
     self.address = None
     self.dir_port = None
     self.or_port = None
@@ -712,7 +713,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
     self._unrecognized_lines = []
     
     #self._parse(raw_contents, validate, is_vote)
-    self._parse_old(raw_contents, validate, is_vote)
+    self._parse_old(raw_content, validate, is_vote)
   
   def _parse(self, content, validate, is_vote):
     """
@@ -753,26 +754,24 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
       #if validate and len(values) > 1 and keyword in ('r', 's', 'v', 'w', 'p'):
       #  raise ValueError("Router status entries can only have a single '%s' line, got %i:\n%s" % (key, len(values), content))
   
-  def _parse_old(self, content, validate, is_vote):
-    self.nickname, self.fingerprint, self.address, self.ip = None, None, None, None
-    self.dir_port, self.or_port, self.legacy_dir_key = None, None, None
-    self.key_certificate, self.contact, self.vote_digest = None, None, None
-    
+  def _parse_old(self, raw_content, validate, is_vote):
     content = StringIO(raw_content)
     dir_source = _read_keyword_line("dir-source", content, validate)
-    self.nickname, self.fingerprint, self.address, self.ip, self.dir_port, self.or_port = dir_source.split(" ")
+    self.nickname, self.fingerprint, self.hostname, self.address, self.dir_port, self.or_port = dir_source.split(" ")
     self.dir_port = int(self.dir_port)
     self.or_port = int(self.or_port)
     
     self.contact = _read_keyword_line("contact", content, validate)
-    if vote:
+    if is_vote:
       self.legacy_dir_key = _read_keyword_line("legacy-dir-key", content, validate, True)
       self.key_certificate = KeyCertificate(content.read(), validate)
     else:
       self.vote_digest = _read_keyword_line("vote-digest", content, True, validate)
-    self.unrecognized_lines = content.read()
-    if self.unrecognized_lines and validate:
-      raise ValueError("Unrecognized trailing data in directory authority information")
+    
+    remainder = content.read()
+    
+    if remainder:
+      self._unrecognized_lines = remainder.split("\n")
   
   def get_unrecognized_lines(self):
     """
@@ -781,7 +780,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
     :returns: a list of unrecognized lines
     """
     
-    return self.unrecognized_lines
+    return self._unrecognized_lines
 
 class KeyCertificate(stem.descriptor.Descriptor):
   """
@@ -931,6 +930,12 @@ class KeyCertificate(stem.descriptor.Descriptor):
     """
     
     return self._unrecognized_lines
+  
+  def __cmp__(self, other):
+    if not isinstance(other, KeyCertificate):
+      return 1
+    
+    return str(self) > str(other)
 
 # TODO: microdescriptors have a slightly different format (including a
 # 'method') - should probably be a subclass
diff --git a/test/mocking.py b/test/mocking.py
index 7008a2a..89ea2f6 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -28,7 +28,9 @@ calling :func:`test.mocking.revert_mocking`.
     get_relay_extrainfo_descriptor  - stem.descriptor.extrainfo_descriptor.RelayExtraInfoDescriptor
     get_bridge_extrainfo_descriptor - stem.descriptor.extrainfo_descriptor.BridgeExtraInfoDescriptor
     get_router_status_entry         - stem.descriptor.networkstatus.RouterStatusEntry
+    get_directory_authority         - stem.descriptor.networkstatus.DirectoryAuthority
     get_key_certificate             - stem.descriptor.networkstatus.KeyCertificate
+    get_network_status_document     - stem.descriptor.networkstatus.NetworkStatusDocument
 """
 
 import inspect
@@ -109,6 +111,11 @@ ROUTER_STATUS_ENTRY_HEADER = (
   ("s", "Fast Named Running Stable Valid"),
 )
 
+AUTHORITY_HEADER = (
+  ("dir-source", "turtles 27B6B5996C426270A5C95488AA5BCEB6BCC86956 no.place.com 76.73.17.194 9030 9090"),
+  ("contact", "Mike Perry <email>"),
+)
+
 KEY_CERTIFICATE_HEADER = (
   ("dir-key-certificate-version", "3"),
   ("fingerprint", "27B6B5996C426270A5C95488AA5BCEB6BCC86956"),
@@ -534,6 +541,37 @@ def get_router_status_entry(attr = None, exclude = (), content = False):
   else:
     return stem.descriptor.networkstatus.RouterStatusEntry(desc_content, validate = True)
 
+def get_directory_authority(attr = None, exclude = (), is_vote = False, content = False):
+  """
+  Provides the descriptor content for...
+  stem.descriptor.networkstatus.DirectoryAuthority
+  
+  :param dict attr: keyword/value mappings to be included in the descriptor
+  :param list exclude: mandatory keywords to exclude from the descriptor
+  :param bool is_vote: True if this is for a vote, False if it's for a consensus
+  :param bool content: provides the str content of the descriptor rather than the class if True
+  
+  :returns: DirectoryAuthority for the requested descriptor content
+  """
+  
+  if attr is None:
+    attr = {}
+  
+  if not is_vote:
+    # entries from a consensus also have a mandatory 'vote-digest' field
+    if not ('vote-digest' in attr or (exclude and 'vote-digest' in exclude)):
+      attr['vote-digest'] = '0B6D1E9A300B895AA2D0B427F92917B6995C3C1C'
+  
+  desc_content = _get_descriptor_content(attr, exclude, AUTHORITY_HEADER)
+  
+  if is_vote:
+    desc_content += "\n" + str(get_key_certificate())
+  
+  if content:
+    return desc_content
+  else:
+    return stem.descriptor.networkstatus.DirectoryAuthority(desc_content, validate = True, is_vote = is_vote)
+
 def get_key_certificate(attr = None, exclude = (), content = False):
   """
   Provides the descriptor content for...
diff --git a/test/unit/descriptor/networkstatus/__init__.py b/test/unit/descriptor/networkstatus/__init__.py
index d8c9657..b2314cc 100644
--- a/test/unit/descriptor/networkstatus/__init__.py
+++ b/test/unit/descriptor/networkstatus/__init__.py
@@ -2,5 +2,5 @@
 Unit tests for stem.descriptor.networkstatus.
 """
 
-__all__ = ["entry", "key_certificate", "document"]
+__all__ = ["entry", "directory_authority", "key_certificate", "document"]
 
diff --git a/test/unit/descriptor/networkstatus/directory_authority.py b/test/unit/descriptor/networkstatus/directory_authority.py
new file mode 100644
index 0000000..dd4c5fa
--- /dev/null
+++ b/test/unit/descriptor/networkstatus/directory_authority.py
@@ -0,0 +1,47 @@
+"""
+Unit tests for the DirectoryAuthority of stem.descriptor.networkstatus.
+"""
+
+import unittest
+
+from test.mocking import get_directory_authority, get_key_certificate
+
+class TestDirectoryAuthority(unittest.TestCase):
+  def test_minimal_consensus_authority(self):
+    """
+    Parses a minimal directory authority for a consensus.
+    """
+    
+    authority = get_directory_authority()
+    
+    self.assertEqual("turtles", authority.nickname)
+    self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint)
+    self.assertEqual("no.place.com", authority.hostname)
+    self.assertEqual("76.73.17.194", authority.address)
+    self.assertEqual(9030, authority.dir_port)
+    self.assertEqual(9090, authority.or_port)
+    self.assertEqual("Mike Perry <email>", authority.contact)
+    self.assertEqual("0B6D1E9A300B895AA2D0B427F92917B6995C3C1C", authority.vote_digest)
+    self.assertEqual(None, authority.legacy_dir_key)
+    self.assertEqual(None, authority.key_certificate)
+    self.assertEqual([], authority.get_unrecognized_lines())
+  
+  def test_minimal_vote_authority(self):
+    """
+    Parses a minimal directory authority for a vote.
+    """
+    
+    authority = get_directory_authority(is_vote = True)
+    
+    self.assertEqual("turtles", authority.nickname)
+    self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint)
+    self.assertEqual("no.place.com", authority.hostname)
+    self.assertEqual("76.73.17.194", authority.address)
+    self.assertEqual(9030, authority.dir_port)
+    self.assertEqual(9090, authority.or_port)
+    self.assertEqual("Mike Perry <email>", authority.contact)
+    self.assertEqual(None, authority.vote_digest)
+    self.assertEqual(None, authority.legacy_dir_key)
+    self.assertEqual(get_key_certificate(), authority.key_certificate)
+    self.assertEqual([], authority.get_unrecognized_lines())
+





More information about the tor-commits mailing list