[tor-commits] [stem/master] Parsing consensus-methods attribute
atagar at torproject.org
atagar at torproject.org
Sat Oct 13 18:35:45 UTC 2012
commit 65e92e80711999591441abbdf23a21321e4d9271
Author: Damian Johnson <atagar at torproject.org>
Date: Sat Sep 8 18:18:38 2012 -0700
Parsing consensus-methods attribute
Only noteworthy bit is that the spec says 'Method "1" MUST be included.' so
checking for that.
---
stem/descriptor/networkstatus.py | 19 +++++++++++------
test/unit/descriptor/networkstatus/document.py | 25 ++++++++++++++++++++++-
2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index f4c3b40..7e7907f 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -328,6 +328,17 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
self.is_consensus, self.is_vote = False, True
elif validate:
raise ValueError("A network status document's vote-status line can only be 'consensus' or 'vote', got '%s' instead" % value)
+ elif keyword == 'consensus-methods':
+ # "consensus-methods" IntegerList
+
+ for entry in value.split(" "):
+ if entry.isdigit():
+ self.consensus_methods.append(int(entry))
+ elif validate:
+ raise ValueError("A network status document's consensus-methods must be a list of integer values, but was '%s'" % value)
+
+ if validate and not (1 in self.consensus_methods):
+ raise ValueError("Network status votes must include consensus-method version 1")
# doing this validation afterward so we know our 'is_consensus' and
# 'is_vote' attributes
@@ -344,17 +355,11 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
# ignore things the parse() method handles
_read_keyword_line("network-status-version", content, False, True)
_read_keyword_line("vote-status", content, False, True)
+ _read_keyword_line("consensus-methods", content, False, True)
vote = self.is_vote
if vote:
- read_keyword_line("consensus-methods", True)
-
- if self.consensus_methods:
- self.consensus_methods = [int(method) for method in self.consensus_methods.split(" ")]
- else:
- self.consensus_methods = []
-
line = _read_keyword_line("published", content, validate, True)
if line:
diff --git a/test/unit/descriptor/networkstatus/document.py b/test/unit/descriptor/networkstatus/document.py
index 9b24a00..9301cce 100644
--- a/test/unit/descriptor/networkstatus/document.py
+++ b/test/unit/descriptor/networkstatus/document.py
@@ -10,7 +10,7 @@ from stem.descriptor.networkstatus import HEADER_STATUS_DOCUMENT_FIELDS, FOOTER_
NETWORK_STATUS_DOCUMENT_ATTR = {
"network-status-version": "3",
"vote-status": "consensus",
- "consensus-methods": "9",
+ "consensus-methods": "1 9",
"consensus-method": "9",
"published": "2012-09-02 22:00:00",
"valid-after": "2012-09-02 22:00:00",
@@ -138,7 +138,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertEqual(False, document.is_consensus)
self.assertEqual(True, document.is_vote)
self.assertEqual(None, document.consensus_method)
- self.assertEqual([9], document.consensus_methods)
+ self.assertEqual([1, 9], document.consensus_methods)
self.assertEqual(datetime.datetime(2012, 9, 2, 22, 0, 0), document.published)
self.assertEqual(datetime.datetime(2012, 9, 2, 22, 0, 0), document.valid_after)
self.assertEqual(datetime.datetime(2012, 9, 2, 22, 0, 0), document.fresh_until)
@@ -245,4 +245,25 @@ class TestNetworkStatusDocument(unittest.TestCase):
document = NetworkStatusDocument(content, False)
self.assertEquals(True, document.is_consensus)
self.assertEquals(False, document.is_vote)
+
+ def test_invalid_consensus_methods(self):
+ """
+ Parses an invalid consensus-methods field.
+ """
+
+ test_values = (
+ ("", []),
+ (" ", []),
+ ("1 2 3 a 5", [1, 2, 3, 5]),
+ ("1 2 3 4.0 5", [1, 2, 3, 5]),
+ ("2 3 4", [2, 3, 4]), # spec says version one must be included
+ )
+
+ for test_value, expected_consensus_methods in test_values:
+ content = get_network_status_document({"vote-status": "vote", "consensus-methods": test_value})
+ self.assertRaises(ValueError, NetworkStatusDocument, content)
+
+ document = NetworkStatusDocument(content, False)
+ self.assertEquals(expected_consensus_methods, document.consensus_methods)
+
More information about the tor-commits
mailing list