[tor-commits] [stem/master] Using numeric 'flag-thresholds' values

atagar at torproject.org atagar at torproject.org
Fri Feb 8 17:17:25 UTC 2013


commit ea5212863a97efa4f29e47280faf3c9566ec5349
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Feb 8 08:29:22 2013 -0800

    Using numeric 'flag-thresholds' values
    
    Now that the spec has been revised to specify numeric values we can provide
    'flag => int/float' mappings (which are much nicer for our users).
    
    Spec change:
    https://gitweb.torproject.org/torspec.git/commitdiff/52d0eb4858ad3eb191df3afe324f43683467ae22
---
 stem/descriptor/networkstatus.py                  |   21 ++++++++++---
 test/unit/descriptor/networkstatus/document_v3.py |   32 ++++++++++-----------
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 3377f5c..3104cad 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -443,7 +443,7 @@ class NetworkStatusDocumentV3(NetworkStatusDocument):
 
   :var list consensus_methods: list of ints for the supported method versions
   :var datetime published: time when the document was published
-  :var dict flag_thresholds: **\*** mapping of internal performance thresholds used while making the vote
+  :var dict flag_thresholds: **\*** mapping of internal performance thresholds used while making the vote, values are **ints** or **floats**
 
   **\*** attribute is either required when we're parsed with validation or has
   a default value, others are left as None if undefined
@@ -686,9 +686,6 @@ class _DocumentHeader(object):
         self.known_flags = [entry for entry in value.split(" ") if entry]
       elif keyword == "flag-thresholds":
         # "flag-thresholds" SP THRESHOLDS
-        #
-        # TODO: format is being discussed on...
-        #   https://trac.torproject.org/8165
 
         value = value.strip()
 
@@ -701,7 +698,21 @@ class _DocumentHeader(object):
               raise ValueError("Network status document's '%s' line is expected to be space separated key=value mappings, got: %s" % (keyword, line))
 
             entry_key, entry_value = entry.split("=", 1)
-            self.flag_thresholds[entry_key] = entry_value
+
+            try:
+              if entry_value.endswith("%"):
+                # opting for string manipulation rather than just
+                # 'float(entry_value) / 100' because floating point arithmetic
+                # will lose precision
+
+                self.flag_thresholds[entry_key] = float("0." + entry_value[:-1].replace('.', '', 1))
+              elif '.' in entry_value:
+                self.flag_thresholds[entry_key] = float(entry_value)
+              else:
+                self.flag_thresholds[entry_key] = int(entry_value)
+            except ValueError:
+              if validate:
+                raise ValueError("Network status document's '%s' line is expected to have float values, got: %s" % (keyword, line))
       elif keyword == "params":
         # "params" [Parameters]
         # Parameter ::= Keyword '=' Int32
diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py
index 548d467..1a478cf 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -481,9 +481,9 @@ class TestNetworkStatusDocument(unittest.TestCase):
 
     test_values = (
       ("", {}),
-      ("fast-speed=40960", {u"fast-speed": u"40960"}),    # numeric value
-      ("guard-wfu=94.669%", {u"guard-wfu": u"94.669%"}),  # percentage value
-      ("guard-wfu=94.669% guard-tk=691200", {u"guard-wfu": u"94.669%", u"guard-tk": u"691200"}),  # multiple values
+      ("fast-speed=40960", {u"fast-speed": 40960}),    # numeric value
+      ("guard-wfu=94.669%", {u"guard-wfu": 0.94669}),  # percentage value
+      ("guard-wfu=94.669% guard-tk=691200", {u"guard-wfu": 0.94669, u"guard-tk": 691200}),  # multiple values
     )
 
     for test_value, expected_value in test_values:
@@ -495,26 +495,24 @@ class TestNetworkStatusDocument(unittest.TestCase):
     full_line = "stable-uptime=693369 stable-mtbf=153249 fast-speed=40960 guard-wfu=94.669% guard-tk=691200 guard-bw-inc-exits=174080 guard-bw-exc-exits=184320 enough-mtbf=1"
 
     expected_value = {
-      u"stable-uptime": u"693369",
-      u"stable-mtbf": u"153249",
-      u"fast-speed": u"40960",
-      u"guard-wfu": u"94.669%",
-      u"guard-tk": u"691200",
-      u"guard-bw-inc-exits": u"174080",
-      u"guard-bw-exc-exits": u"184320",
-      u"enough-mtbf": u"1",
+      u"stable-uptime": 693369,
+      u"stable-mtbf": 153249,
+      u"fast-speed": 40960,
+      u"guard-wfu": 0.94669,
+      u"guard-tk": 691200,
+      u"guard-bw-inc-exits": 174080,
+      u"guard-bw-exc-exits": 184320,
+      u"enough-mtbf": 1,
     }
 
     document = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": full_line})
     self.assertEquals(expected_value, document.flag_thresholds)
 
-    # TODO: At present our validation is pretty permissive since the field
-    # doesn't yet have a formal specificiation. We should expand this test when
-    # it does.
-
     test_values = (
-      "stable-uptime 693369",  # not a key=value mapping
-      #"stable-uptime=693369\tstable-mtbf=153249", # non-space divider
+      "stable-uptime 693369",   # not a key=value mapping
+      "stable-uptime=a693369",  # non-numeric value
+      "guard-wfu=94.669%%",     # double quote
+      "stable-uptime=693369\tstable-mtbf=153249",  # non-space divider
     )
 
     for test_value in test_values:





More information about the tor-commits mailing list