[tor-commits] [stem/master] Support for BUILDTIMEOUT_SET events

atagar at torproject.org atagar at torproject.org
Mon Dec 3 04:21:50 UTC 2012


commit 0687e99789827aa43dd8523006eb49aed837c2ef
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Dec 2 20:20:33 2012 -0800

    Support for BUILDTIMEOUT_SET events
    
    Impementation and testing for BUILDTIMEOUT_SET events. Snagged test data by
    listening for the events while bootstrapping...
    
    650 BUILDTIMEOUT_SET COMPUTED TOTAL_TIMES=124 TIMEOUT_MS=9019 XM=1375 ALPHA=0.855662 CUTOFF_QUANTILE=0.800000 TIMEOUT_RATE=0.137097 CLOSE_MS=21850 CLOSE_RATE=0.072581
    650 BUILDTIMEOUT_SET COMPUTED TOTAL_TIMES=125 TIMEOUT_MS=8915 XM=1375 ALPHA=0.860984 CUTOFF_QUANTILE=0.800000 TIMEOUT_RATE=0.136000 CLOSE_MS=21850 CLOSE_RATE=0.072000
    650 BUILDTIMEOUT_SET COMPUTED TOTAL_TIMES=126 TIMEOUT_MS=8923 XM=1375 ALPHA=0.860563 CUTOFF_QUANTILE=0.800000 TIMEOUT_RATE=0.134921 CLOSE_MS=21850 CLOSE_RATE=0.071429
    650 BUILDTIMEOUT_SET COMPUTED TOTAL_TIMES=127 TIMEOUT_MS=8814 XM=1375 ALPHA=0.866231 CUTOFF_QUANTILE=0.800000 TIMEOUT_RATE=0.133858 CLOSE_MS=21850 CLOSE_RATE=0.070866
---
 stem/__init__.py             |   24 ++++++++++++++++
 stem/control.py              |    1 +
 stem/response/events.py      |   63 ++++++++++++++++++++++++++++++++++++++++--
 test/unit/response/events.py |   27 ++++++++++++++++++
 4 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 815e82c..ea3a5eb 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -291,6 +291,21 @@ Library for working with the tor process.
   **GOOD**      unknown
   **DROPPED**   unknown
   ============= ===========
+
+.. data:: TimeoutSetType (enum)
+  
+  Way in which the timeout value of a circuit is changing. Tor may provide
+  types not in this enum.
+  
+  =============== ===========
+  TimeoutSetType  Description
+  =============== ===========
+  **COMPUTED**    tor has computed a new timeout based on prior circuits
+  **RESET**       timeout reverted to its default
+  **SUSPENDED**   timeout reverted to its default until network connectivity has recovered
+  **DISCARD**     throwing out timeout value from when the network was down
+  **RESUME**      resumed calculations to determine the proper timeout
+  =============== ===========
 """
 
 __version__ = '0.0.1'
@@ -334,6 +349,7 @@ __all__ = [
   "StatusType",
   "GuardType",
   "GuardStatus",
+  "TimeoutSetType",
 ]
 
 import stem.util.enum
@@ -542,3 +558,11 @@ GuardStatus = stem.util.enum.UppercaseEnum(
   "DROPPED",
 )
 
+TimeoutSetType = stem.util.enum.UppercaseEnum(
+  "COMPUTED",
+  "RESET",
+  "SUSPENDED",
+  "DISCARD",
+  "RESUME",
+)
+
diff --git a/stem/control.py b/stem/control.py
index ec727ce..a8f7913 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -80,6 +80,7 @@ providing its own for interacting at a higher level.
   ===================== ===========
   **ADDRMAP**           :class:`stem.response.events.AddrMapEvent`
   **AUTHDIR_NEWDESCS**  :class:`stem.response.events.AuthDirNewDescEvent`
+  **BUILDTIMEOUT_SET**  :class:`stem.response.events.BuildTimeoutSetEvent`
   **BW**                :class:`stem.response.events.BandwidthEvent`
   **CIRC**              :class:`stem.response.events.CircuitEvent`
   **CLIENTS_SEEN**      :class:`stem.response.events.ClientsSeenEvent`
diff --git a/stem/response/events.py b/stem/response/events.py
index 522f9cc..8e437d9 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -232,6 +232,62 @@ class BandwidthEvent(Event):
     self.read = long(self.read)
     self.written = long(self.written)
 
+class BuildTimeoutSetEvent(Event):
+  """
+  Event indicating that the timeout value for a circuit has changed. This was
+  first added in tor version 0.2.2.7.
+  
+  :var stem.TimeoutSetType set_type: way in which the timeout is changing
+  :var int total_times: circuit build times tor used to determine the timeout
+  :var int timeout: circuit timeout value in milliseconds
+  :var int xm: Pareto parameter Xm in milliseconds
+  :var float alpha: Paredo paremter alpha
+  :var float quantile: CDF quantile cutoff point
+  :var float timeout_rate: ratio of circuits that have time out
+  :var int close_timeout: duration to keep measurement circuits in milliseconds
+  :var float close_rate: ratio of measurement circuits that are closed
+  """
+  
+  _POSITIONAL_ARGS = ("set_type",)
+  _KEYWORD_ARGS = {
+    "TOTAL_TIMES": "total_times",
+    "TIMEOUT_MS": "timeout",
+    "XM": "xm",
+    "ALPHA": "alpha",
+    "CUTOFF_QUANTILE": "quantile",
+    "TIMEOUT_RATE": "timeout_rate",
+    "CLOSE_MS": "close_timeout",
+    "CLOSE_RATE": "close_rate",
+  }
+  
+  def _parse(self):
+    # convert our integer and float parameters
+    
+    for param in ('total_times', 'timeout', 'xm', 'close_timeout'):
+      param_value = getattr(self, param)
+      
+      if param_value != None:
+        try:
+          setattr(self, param, int(param_value))
+        except ValueError:
+          raise stem.ProtocolError("The %s of a BUILDTIMEOUT_SET should be an integer: %s" % (param, self))
+    
+    for param in ('alpha', 'quantile', 'timeout_rate', 'close_rate'):
+      param_value = getattr(self, param)
+      
+      if param_value != None:
+        try:
+          setattr(self, param, float(param_value))
+        except ValueError:
+          raise stem.ProtocolError("The %s of a BUILDTIMEOUT_SET should be a float: %s" % (param, self))
+    
+    # log if we have an unrecognized timeout set type
+    unrecognized_msg = UNRECOGNIZED_ATTR_MSG % ("BUILDTIMEOUT_SET", self)
+    
+    if self.set_type and (not self.set_type in stem.TimeoutSetType):
+      log_id = "event.buildtimeout_set.unknown_timeout_set_type.%s" % self.set_type
+      log.log_once(log_id, log.INFO, unrecognized_msg % ('timeout set type', self.set_type))
+
 class CircuitEvent(Event):
   """
   Event that indicates that a circuit has changed.
@@ -424,7 +480,7 @@ class NetworkStatusEvent(Event):
   Event for when our copy of the consensus has changed. This was introduced in
   tor version 0.1.2.3.
   
-  :param list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors
+  :var list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors
   """
   
   _SKIP_PARSING = True
@@ -447,7 +503,7 @@ class NewConsensusEvent(Event):
   
   This was introduced in tor version 0.2.1.13.
   
-  :param list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors
+  :var list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors
   """
   
   _SKIP_PARSING = True
@@ -469,7 +525,7 @@ class NewDescEvent(Event):
   VERBOSE_NAMES feature isn't enabled. The option was first introduced in tor
   version 0.1.2.2, and on by default after 0.2.2.1.
   
-  :param tuple relays: **(fingerprint, nickname)** tuples for the relays with
+  :var tuple relays: **(fingerprint, nickname)** tuples for the relays with
     new descriptors
   """
   
@@ -659,6 +715,7 @@ class StreamEvent(Event):
 EVENT_TYPE_TO_CLASS = {
   "ADDRMAP": AddrMapEvent,
   "AUTHDIR_NEWDESCS": AuthDirNewDescEvent,
+  "BUILDTIMEOUT_SET": BuildTimeoutSetEvent,
   "BW": BandwidthEvent,
   "CIRC": CircuitEvent,
   "CLIENTS_SEEN": ClientsSeenEvent,
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index 6f18676..b74f4ad 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -12,6 +12,18 @@ import test.mocking as mocking
 
 from stem import * # enums and exceptions
 
+# BUILDTIMEOUT_SET event from tor 0.2.3.16.
+
+BUILD_TIMEOUT_EVENT = "650 BUILDTIMEOUT_SET COMPUTED \
+TOTAL_TIMES=124 \
+TIMEOUT_MS=9019 \
+XM=1375 \
+ALPHA=0.855662 \
+CUTOFF_QUANTILE=0.800000 \
+TIMEOUT_RATE=0.137097 \
+CLOSE_MS=21850 \
+CLOSE_RATE=0.072581"
+
 # CIRC events from tor v0.2.3.16
 
 CIRC_LAUNCHED = "650 CIRC 7 LAUNCHED \
@@ -244,6 +256,21 @@ class TestEvents(unittest.TestCase):
     self.assertEqual([], event.positional_args)
     self.assertEqual({}, event.keyword_args)
   
+  def test_build_timeout_set_event(self):
+    event = _get_event(BUILD_TIMEOUT_EVENT)
+    
+    self.assertTrue(isinstance(event, stem.response.events.BuildTimeoutSetEvent))
+    self.assertEqual(BUILD_TIMEOUT_EVENT.lstrip("650 "), str(event))
+    self.assertEqual(TimeoutSetType.COMPUTED, event.set_type)
+    self.assertEqual(124, event.total_times)
+    self.assertEqual(9019, event.timeout)
+    self.assertEqual(1375, event.xm)
+    self.assertEqual(0.855662, event.alpha)
+    self.assertEqual(0.8, event.quantile)
+    self.assertEqual(0.137097, event.timeout_rate)
+    self.assertEqual(21850, event.close_timeout)
+    self.assertEqual(0.072581, event.close_rate)
+  
   def test_bw_event(self):
     event = _get_event("650 BW 15 25")
     



More information about the tor-commits mailing list