[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Support for 'flag-thresholds' lines in network status votes
commit 4e8aaa4daadb02db1686dde57c42c15aef6821e9
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Feb 5 09:48:12 2013 -0800
Support for 'flag-thresholds' lines in network status votes
Parsing the new 'flag-thresholds' in network status votes - thanks to Karsten
for pointing this out.
metrics-lib change:
https://gitweb.torproject.org/metrics-lib.git/commitdiff/c2a0dbf8bf100a19660ad512b88d93f3d7c18a1e
dir-spec addition:
https://trac.torproject.org/8165
---
stem/descriptor/networkstatus.py | 21 ++++++++
test/unit/descriptor/networkstatus/document_v3.py | 52 +++++++++++++++++++++
2 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 9f3730c..3377f5c 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -87,6 +87,7 @@ HEADER_STATUS_DOCUMENT_FIELDS = (
("client-versions", True, True, False),
("server-versions", True, True, False),
("known-flags", True, True, True),
+ ("flag-thresholds", True, False, False),
("params", True, True, False),
)
@@ -442,6 +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
**\*** attribute is either required when we're parsed with validation or has
a default value, others are left as None if undefined
@@ -551,6 +553,7 @@ class _DocumentHeader(object):
self.client_versions = []
self.server_versions = []
self.known_flags = []
+ self.flag_thresholds = {}
self.params = dict(DEFAULT_PARAMS) if default_params else {}
self._unrecognized_lines = []
@@ -681,6 +684,24 @@ class _DocumentHeader(object):
# simply fetches the entries, excluding empty strings
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()
+
+ if value:
+ for entry in value.split(" "):
+ if not '=' in entry:
+ if not validate:
+ continue
+
+ 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
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 74c7fe4..71d56e5 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -65,6 +65,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertEqual([], document.client_versions)
self.assertEqual([], document.server_versions)
self.assertEqual(expected_known_flags, document.known_flags)
+ self.assertEqual({}, document.flag_thresholds)
self.assertEqual(DEFAULT_PARAMS, document.params)
self.assertEqual((), document.directory_authorities)
self.assertEqual({}, document.bandwidth_weights)
@@ -98,6 +99,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertEqual([], document.client_versions)
self.assertEqual([], document.server_versions)
self.assertEqual(expected_known_flags, document.known_flags)
+ self.assertEqual({}, document.flag_thresholds)
self.assertEqual(DEFAULT_PARAMS, document.params)
self.assertEqual((), document.directory_authorities)
self.assertEqual({}, document.bandwidth_weights)
@@ -472,6 +474,56 @@ class TestNetworkStatusDocument(unittest.TestCase):
document = get_network_status_document_v3({"known-flags": test_value})
self.assertEquals(expected_value, document.known_flags)
+ def test_flag_thresholds(self):
+ """
+ Parses the flag-thresholds entry.
+ """
+
+ 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
+ )
+
+ for test_value, expected_value in test_values:
+ document = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": test_value})
+ self.assertEquals(expected_value, document.flag_thresholds)
+
+ # parses a full entry found in an actual vote
+
+ 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",
+ }
+
+ 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
+ )
+
+ for test_value in test_values:
+ content = get_network_status_document_v3({"vote-status": "vote", "flag-thresholds": test_value}, content = True)
+ self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
+
+ document = NetworkStatusDocumentV3(content, False)
+ self.assertEquals({}, document.flag_thresholds)
+
def test_params(self):
"""
General testing for the 'params' line, exercising the happy cases.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits