[tor-commits] [stem/master] Unit test for parsing a minimal key certificate
atagar at torproject.org
atagar at torproject.org
Sat Oct 13 18:35:45 UTC 2012
commit 5d1a11fa4f479cac4d4987d9841889ea251b2eba
Author: Damian Johnson <atagar at torproject.org>
Date: Wed Sep 26 09:00:22 2012 -0700
Unit test for parsing a minimal key certificate
Test for minimal key certificate parsing, and related fixes for the
KeyCertificate class. The main gotcha in this is that KeyCertificates don't
need to have a prescribed order (unlike other network status document
fields).
---
run_tests.py | 2 +
stem/descriptor/networkstatus.py | 14 +---
test/unit/descriptor/networkstatus/__init__.py | 2 +-
.../descriptor/networkstatus/key_certificate.py | 79 ++++++++++++++++++++
4 files changed, 85 insertions(+), 12 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index af2d09f..54e74b2 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.key_certificate
import test.unit.descriptor.networkstatus.document
import test.unit.response.control_line
import test.unit.response.control_message
@@ -117,6 +118,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.key_certificate.TestKeyCertificate,
test.unit.descriptor.networkstatus.document.TestNetworkStatusDocument,
test.unit.exit_policy.rule.TestExitPolicyRule,
test.unit.exit_policy.policy.TestExitPolicy,
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 46adbfe..01fb2f3 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -801,7 +801,7 @@ class KeyCertificate(stem.descriptor.Descriptor):
**\*** mandatory attribute
"""
- def __init__(self, raw_content, validate):
+ def __init__(self, raw_content, validate = True):
super(KeyCertificate, self).__init__(raw_content)
self.version = None
@@ -817,7 +817,7 @@ class KeyCertificate(stem.descriptor.Descriptor):
self._unrecognized_lines = []
- self._parse(raw_contents, validate)
+ self._parse(raw_content, validate)
def _parse(self, content, validate):
"""
@@ -847,14 +847,6 @@ class KeyCertificate(stem.descriptor.Descriptor):
entry_count = len(entries.get(keyword, []))
if entry_count > 1:
raise ValueError("Key certificates can only have a single '%s' line, got %i:\n%s" % (keyword, entry_count, content))
-
- # Check that our field's order matches the spec. This isn't explicitely
- # stated in the spec, but the network status document requires a specific
- # order so it stands to reason that the key certificate (which is in it)
- # needs ot match a prescribed order too.
-
- fields = [attr[0] for attr in KEY_CERTIFICATE_PARAMS]
- _check_for_misordered_fields(entries, fields)
for keyword, values in entries.items():
value, block_contents = values[0]
@@ -936,7 +928,7 @@ class KeyCertificate(stem.descriptor.Descriptor):
:returns: a list of unrecognized lines
"""
- return self.unrecognized_lines
+ return self._unrecognized_lines
# TODO: microdescriptors have a slightly different format (including a
# 'method') - should probably be a subclass
diff --git a/test/unit/descriptor/networkstatus/__init__.py b/test/unit/descriptor/networkstatus/__init__.py
index d8483e2..d8c9657 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", "document"]
+__all__ = ["entry", "key_certificate", "document"]
diff --git a/test/unit/descriptor/networkstatus/key_certificate.py b/test/unit/descriptor/networkstatus/key_certificate.py
new file mode 100644
index 0000000..2d779e7
--- /dev/null
+++ b/test/unit/descriptor/networkstatus/key_certificate.py
@@ -0,0 +1,79 @@
+"""
+Unit tests for the KeyCertificate of stem.descriptor.networkstatus.
+"""
+
+import datetime
+import unittest
+
+from stem.descriptor.networkstatus import KeyCertificate
+
+sig_block = """\
+-----BEGIN %s-----
+MIGJAoGBAJ5itcJRYNEM3Qf1OVWLRkwjqf84oXPc2ZusaJ5zOe7TVvBMra9GNyc0
+NM9y6zVkHCAePAjr4KbW/8P1olA6FUE2LV9bozaU1jFf6K8B2OELKs5FUEW+n+ic
+GM0x6MhngyXonWOcKt5Gj+mAu5lrno9tpNbPkz2Utr/Pi0nsDhWlAgMBAAE=
+-----END %s-----\
+"""
+
+RSA_SIG = sig_block % ("RSA PUBLIC KEY", "RSA PUBLIC KEY")
+KEY_SIG = sig_block % ("SIGNATURE", "SIGNATURE")
+
+KEY_CERTIFICATE_ATTR = (
+ ("dir-key-certificate-version", "3"),
+ ("fingerprint", "27B6B5996C426270A5C95488AA5BCEB6BCC86956"),
+ ("dir-key-published", "2011-11-28 21:51:04"),
+ ("dir-key-expires", "2012-11-28 21:51:04"),
+ ("dir-identity-key", "\n" + RSA_SIG),
+ ("dir-signing-key", "\n" + RSA_SIG),
+ ("dir-key-certification", "\n" + KEY_SIG),
+)
+
+def get_key_certificate(attr = None, exclude = None):
+ """
+ Constructs a minimal key certificate with the given attributes.
+
+ :param dict attr: keyword/value mappings to be included in the entry
+ :param list exclude: mandatory keywords to exclude from the entry
+
+ :returns: str with customized key certificate content
+ """
+
+ descriptor_lines = []
+ if attr is None: attr = {}
+ if exclude is None: exclude = []
+ attr = dict(attr) # shallow copy since we're destructive
+
+ for keyword, value in KEY_CERTIFICATE_ATTR:
+ if keyword in exclude: continue
+ elif keyword in attr:
+ value = attr[keyword]
+ del attr[keyword]
+
+ descriptor_lines.append("%s %s" % (keyword, value))
+
+ # dump in any unused attributes
+ for attr_keyword, attr_value in attr.items():
+ descriptor_lines.append("%s %s" % (attr_keyword, attr_value))
+
+ return "\n".join(descriptor_lines)
+
+class TestKeyCertificate(unittest.TestCase):
+ def test_minimal(self):
+ """
+ Parses a minimal key certificate.
+ """
+
+ certificate = KeyCertificate(get_key_certificate())
+
+ self.assertEqual(3, certificate.version)
+ self.assertEqual(None, certificate.address)
+ self.assertEqual(None, certificate.dir_port)
+ self.assertEqual("27B6B5996C426270A5C95488AA5BCEB6BCC86956", certificate.fingerprint)
+ self.assertEqual(RSA_SIG, certificate.identity_key)
+ self.assertEqual(datetime.datetime(2011, 11, 28, 21, 51, 4), certificate.published)
+ self.assertEqual(datetime.datetime(2012, 11, 28, 21, 51, 4), certificate.expires)
+ self.assertEqual(RSA_SIG, certificate.signing_key)
+ self.assertEqual(None, certificate.crosscert)
+ self.assertEqual(KEY_SIG, certificate.certification)
+ self.assertEqual([], certificate.get_unrecognized_lines())
+
More information about the tor-commits
mailing list