[tor-commits] [stem/master] Parsing consensus-method and datetime attributes

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


commit cb96c3e094719b096e5425faeadc01a15dfcb388
Author: Damian Johnson <atagar at 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))
 





More information about the tor-commits mailing list