[tor-commits] [stem/master] Expanding attributes for read/write-history
atagar at torproject.org
atagar at torproject.org
Sun Apr 15 02:50:21 UTC 2012
commit 62f34c67bcaaa7205b09cc7cf6201d78447c0a39
Author: Damian Johnson <atagar at torproject.org>
Date: Sat Apr 14 15:51:16 2012 -0700
Expanding attributes for read/write-history
Parsing and validating read-history and write-history attributes. These are
depricated fields, but still found on archived and extra-info descriptors. This
includes a unit test to exercise the additions.
---
stem/descriptor/server_descriptor.py | 64 +++++++++++++++++++++++++---
test/unit/descriptor/server_descriptor.py | 27 ++++++++++++
2 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 9b74e2b..6892381 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -202,10 +202,18 @@ class ServerDescriptorV3(stem.descriptor.Descriptor):
average_bandwidth (int) - rate of traffic relay is willing to relay in bytes/s (*)
burst_bandwidth (int) - rate of traffic relay is willing to burst to in bytes/s (*)
observed_bandwidth (int) - estimated capacity of the relay based on usage in bytes/s (*)
- read_history (str) - (deprecated) always unset
- write_history (str) - (deprecated) always unset
eventdns (bool) - (deprecated) always unset (*)
+ read_history (str) - (deprecated) read-history line, always unset
+ read_history_end (datetime.datetime) - (deprecated) end of the sampling interval
+ read_history_interval (int) - (deprecated) seconds per interval
+ read_history_values (list) - (deprecated) bytes read during each interval (*)
+
+ write_history (str) - (deprecated) write-history line, always unset
+ write_history_end (datetime.datetime) - (deprecated) end of the sampling interval
+ write_history_interval (int) - (deprecated) seconds per interval
+ write_history_values (list) - (deprecated) bytes written during each interval (*)
+
(*) required fields, others are left as None if undefined
"""
@@ -254,9 +262,18 @@ class ServerDescriptorV3(stem.descriptor.Descriptor):
self.average_bandwidth = None
self.burst_bandwidth = None
self.observed_bandwidth = None
+ self.eventdns = True
+
self.read_history = None
+ self.read_history_end = None
+ self.read_history_interval = None
+ self.read_history_values = []
+
self.write_history = None
- self.eventdns = True
+ self.write_history_end = None
+ self.write_history_interval = None
+ self.write_history_values = []
+
self._unrecognized_lines = []
self._annotation_lines = annotations if annotations else []
@@ -474,12 +491,45 @@ class ServerDescriptorV3(stem.descriptor.Descriptor):
raise ValueError("Protocols line did not match the expected pattern: %s" % line)
elif keyword == "family":
self.family = value.split(" ")
- elif keyword == "read-history":
- self.read_history = value
- elif keyword == "write-history":
- self.write_history = value
elif keyword == "eventdns":
self.eventdns = value == "1"
+ elif keyword in ("read-history", "write-history"):
+ is_read = keyword == "read-history"
+
+ if is_read: self.read_history = value
+ else: self.write_history = value
+
+ value_match = re.match("^(.*) \(([0-9]+) s\) (.*)$", value)
+
+ if not value_match:
+ if not validate: continue
+ raise ValueError("Malformed %s line: %s" % (keyword, line))
+
+ end_value, interval_value, history_values = value_match.groups()
+
+ try:
+ end_datetime = datetime.datetime.strptime(end_value, "%Y-%m-%d %H:%M:%S")
+
+ if is_read: self.read_history_end = end_datetime
+ else: self.write_history_end = end_datetime
+ except ValueError:
+ if validate:
+ raise ValueError("%s line's time wasn't parseable: %s" % (keyword, line))
+
+ if interval_value.isdigit():
+ if is_read: self.read_history_interval = int(interval_value)
+ else: self.write_history_interval = int(interval_value)
+ elif validate:
+ raise ValueError("%s line's interval wasn't a number: %s" % (keyword, line))
+
+ for sampling in history_values.split(","):
+ if sampling.isdigit():
+ if is_read: self.read_history_values.append(int(sampling))
+ else: self.write_history_values.append(int(sampling))
+ else:
+ if validate:
+ raise ValueError("%s line has non-numeric values: %s" % (keyword, line))
+ else: break
else:
self._unrecognized_lines.append(line)
diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py
index 89a28c6..5c4cfce 100644
--- a/test/unit/descriptor/server_descriptor.py
+++ b/test/unit/descriptor/server_descriptor.py
@@ -222,6 +222,33 @@ class TestServerDescriptor(unittest.TestCase):
desc_text = _make_descriptor({"published": "2012-01-01"})
self._expect_invalid_attr(desc_text, "published")
+ def test_read_and_write_history(self):
+ """
+ Parses a read-history and write-history entry. This is now a depricated
+ field for relay server descriptors but is still found in archives and
+ extra-info descriptors.
+ """
+
+ for field in ("read-history", "write-history"):
+ value = "2005-12-16 18:00:48 (900 s) 81,8848,8927,8927,83,8848"
+ desc_text = _make_descriptor({"opt %s" % field: value})
+ desc = RelayDescriptorV3(desc_text)
+
+ if field == "read-history":
+ attr = (desc.read_history, desc.read_history_end,
+ desc.read_history_interval, desc.read_history_values)
+ else:
+ attr = (desc.write_history, desc.write_history_end,
+ desc.write_history_interval, desc.write_history_values)
+
+ expected_end = datetime.datetime(2005, 12, 16, 18, 0, 48)
+ expected_values = [81, 8848, 8927, 8927, 83, 8848]
+
+ self.assertEquals(value, attr[0])
+ self.assertEquals(expected_end, attr[1])
+ self.assertEquals(900, attr[2])
+ self.assertEquals(expected_values, attr[3])
+
def test_annotations(self):
"""
Checks that content before a descriptor are parsed as annotations.
More information about the tor-commits
mailing list