[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