commit cb96c3e094719b096e5425faeadc01a15dfcb388 Author: Damian Johnson atagar@torproject.org Date: Sat Sep 8 18:42:29 2012 -0700
Parsing consensus-method and datetime attributes
Handling the published, valid-after, fresh-until, and valid-until fields. Doing them as a batch since they're all simply datetime fields without any other constraints. --- stem/descriptor/networkstatus.py | 54 ++++++++++++------------ test/unit/descriptor/networkstatus/document.py | 45 +++++++++++++++++++- 2 files changed, 71 insertions(+), 28 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py index 7e7907f..039222b 100644 --- a/stem/descriptor/networkstatus.py +++ b/stem/descriptor/networkstatus.py @@ -339,6 +339,28 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
if validate and not (1 in self.consensus_methods): raise ValueError("Network status votes must include consensus-method version 1") + elif keyword == 'consensus-method': + # "consensus-method" Integer + + if value.isdigit(): + self.consensus_method = int(value) + elif validate: + raise ValueError("A network status document's consensus-method must be an integer, but was '%s'" % value) + elif keyword in ('published', 'valid-after', 'fresh-until', 'valid-until'): + try: + date_value = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S") + + if keyword == 'published': + self.published = date_value + elif keyword == 'valid-after': + self.valid_after = date_value + elif keyword == 'fresh-until': + self.fresh_until = date_value + elif keyword == 'valid-until': + self.valid_until = date_value + except ValueError: + if validate: + raise ValueError("Network status document's '%s' time wasn't parseable: %s" % (keyword, value))
# doing this validation afterward so we know our 'is_consensus' and # 'is_vote' attributes @@ -356,36 +378,14 @@ class NetworkStatusDocument(stem.descriptor.Descriptor): _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) + _read_keyword_line("consensus-method", content, False, True) + _read_keyword_line("published", content, False, True) + _read_keyword_line("valid-after", content, False, True) + _read_keyword_line("fresh-until", content, False, True) + _read_keyword_line("valid-until", content, False, True)
vote = self.is_vote
- if vote: - line = _read_keyword_line("published", content, validate, True) - - if line: - self.published = _strptime(line, validate, True) - else: - read_keyword_line("consensus-method", True) - if self.consensus_method != None: - self.consensus_method = int(self.consensus_method) - - map(read_keyword_line, ["valid-after", "fresh-until", "valid-until"]) - - if self.valid_after: - self.valid_after = _strptime(self.valid_after, validate) - elif validate: - raise ValueError("Missing the 'valid-after' field") - - if self.fresh_until: - self.fresh_until = _strptime(self.fresh_until, validate) - elif validate: - raise ValueError("Missing the 'fresh-until' field") - - if self.valid_until: - self.valid_until = _strptime(self.valid_until, validate) - elif validate: - raise ValueError("Missing the 'valid-until' field") - voting_delay = _read_keyword_line("voting-delay", content, validate)
if voting_delay: diff --git a/test/unit/descriptor/networkstatus/document.py b/test/unit/descriptor/networkstatus/document.py index 9301cce..91796a3 100644 --- a/test/unit/descriptor/networkstatus/document.py +++ b/test/unit/descriptor/networkstatus/document.py @@ -265,5 +265,48 @@ class TestNetworkStatusDocument(unittest.TestCase):
document = NetworkStatusDocument(content, False) self.assertEquals(expected_consensus_methods, document.consensus_methods) - + + def test_invalid_consensus_method(self): + """ + Parses an invalid consensus-method field. + """ + + test_values = ( + "", + " ", + "a", + "1 2", + "2.0", + ) + + for test_value in test_values: + content = get_network_status_document({"consensus-method": test_value}) + self.assertRaises(ValueError, NetworkStatusDocument, content) + + document = NetworkStatusDocument(content, False) + self.assertEquals(None, document.consensus_method) + + def test_invalid_time_fields(self): + """ + Parses invalid published, valid-after, fresh-until, and valid-until fields. + All are simply datetime values. + """ + + test_values = ( + "", + " ", + "2012-12-12", + "2012-12-12 01:01:", + "2012-12-12 01:a1:01", + ) + + for field in ('published', 'valid-after', 'fresh-until', 'valid-until'): + attr = field.replace('-', '_') + + for test_value in test_values: + content = get_network_status_document({"vote-status": "vote", field: test_value}) + self.assertRaises(ValueError, NetworkStatusDocument, content) + + document = NetworkStatusDocument(content, False) + self.assertEquals(None, getattr(document, attr))
tor-commits@lists.torproject.org