[tor-commits] [stem/master] Adding support for TB_EMPTY events
atagar at torproject.org
atagar at torproject.org
Mon Nov 4 07:29:15 UTC 2013
commit d6a95bf778e6b90d9de9ea46aefcfce2f9103e68
Author: Damian Johnson <atagar at torproject.org>
Date: Sun Nov 3 23:22:32 2013 -0800
Adding support for TB_EMPTY events
Last event type from...
https://gitweb.torproject.org/torspec.git/commitdiff/6f2919a
---
docs/change_log.rst | 1 +
stem/__init__.py | 18 +++++++++++++++++
stem/response/events.py | 44 ++++++++++++++++++++++++++++++++++++++++++
stem/version.py | 2 ++
test/unit/response/events.py | 41 +++++++++++++++++++++++++++++++++++++++
5 files changed, 106 insertions(+)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 5c6fed2..7b71c47 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -45,6 +45,7 @@ The following are only available within stem's `git repository
* Added `support for CONN_BW events <api/response.html#stem.response.events.ConnectionBandwidthEvent>`_ (:spec:`6f2919a`)
* Added `support for CIRC_BW events <api/response.html#stem.response.events.CircuitBandwidthEvent>`_ (:spec:`6f2919a`)
* Added `support for CELL_STATS events <api/response.html#stem.response.events.CellStatsEvent>`_ (:spec:`6f2919a`)
+ * Added `support for TB_EMPTY events <api/response.html#stem.response.events.TokenBucketEmptyEvent>`_ (:spec:`6f2919a`)
.. _version_1.1:
diff --git a/stem/__init__.py b/stem/__init__.py
index 182428f..9710d24 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -380,6 +380,18 @@ Library for working with the tor process.
**DIR** fetching or sending tor descriptor data
**EXIT** carrying traffic between the tor network and an external destination
=============== ===========
+
+.. data:: TokenBucket (enum)
+
+ Bucket categories of TB_EMPTY events.
+
+ =============== ===========
+ TokenBucket Description
+ =============== ===========
+ **GLOBAL** global token bucket
+ **RELAY** relay token bucket
+ **ORCONN** bucket used for OR connections
+ =============== ===========
"""
__version__ = '1.1.0-dev'
@@ -718,3 +730,9 @@ ConnectionType = stem.util.enum.UppercaseEnum(
"DIR",
"EXIT",
)
+
+TokenBucket = stem.util.enum.UppercaseEnum(
+ "GLOBAL",
+ "RELAY",
+ "ORCONN",
+)
diff --git a/stem/response/events.py b/stem/response/events.py
index 616bbfc..19e1680 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -1069,6 +1069,49 @@ class CellStatsEvent(Event):
self.outbound_time = _parse_cell_type_mapping(self.outbound_time)
+class TokenBucketEmptyEvent(Event):
+ """
+ Event emitted when refilling an empty token bucket. **These events are only
+ emitted if TestingTorNetwork is set.**
+
+ The TB_EMPTY event was introduced in tor version 0.2.5.2-alpha.
+
+ .. versionadded:: 1.1.0-dev
+
+ :var stem.TokenBucket bucket: bucket being refilled
+ :var str id: connection identifier
+ :var int read: time in milliseconds since the read bucket was last refilled
+ :var int written: time in milliseconds since the write bucket was last refilled
+ :var int last_refill: time in milliseconds the bucket has been empty since last refilled
+ """
+
+ _POSITIONAL_ARGS = ("bucket",)
+ _KEYWORD_ARGS = {
+ "ID": "id",
+ "READ": "read",
+ "WRITTEN": "written",
+ "LAST": "last_refill",
+ }
+
+ _VERSION_ADDED = stem.version.Requirement.EVENT_TB_EMPTY
+
+ def _parse(self):
+ if self.id and not tor_tools.is_valid_connection_id(self.id):
+ raise stem.ProtocolError("Connection IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self))
+ elif not self.read.isdigit():
+ raise stem.ProtocolError("A TB_EMPTY's READ value should be a positive numeric value, received: %s" % self)
+ elif not self.written.isdigit():
+ raise stem.ProtocolError("A TB_EMPTY's WRITTEN value should be a positive numeric value, received: %s" % self)
+ elif not self.last_refill.isdigit():
+ raise stem.ProtocolError("A TB_EMPTY's LAST value should be a positive numeric value, received: %s" % self)
+
+ self.read = int(self.read)
+ self.written = int(self.written)
+ self.last_refill = int(self.last_refill)
+
+ self._log_if_unrecognized('bucket', stem.TokenBucket)
+
+
def _parse_cell_type_mapping(mapping):
"""
Parses a mapping of the form...
@@ -1133,6 +1176,7 @@ EVENT_TYPE_TO_CLASS = {
"STATUS_SERVER": StatusEvent,
"STREAM": StreamEvent,
"STREAM_BW": StreamBwEvent,
+ "TB_EMPTY": TokenBucketEmptyEvent,
"TRANSPORT_LAUNCHED": TransportLaunchedEvent,
"WARN": LogEvent,
diff --git a/stem/version.py b/stem/version.py
index ef1f290..b0563d5 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -46,6 +46,7 @@ easily parsed and compared, for instance...
**EVENT_CONN_BW** CONN_BW events
**EVENT_CIRC_BW** CIRC_BW events
**EVENT_CELL_STATS** CELL_STATS events
+ **EVENT_TB_EMPTY** TB_EMPTY events
**EXTENDCIRCUIT_PATH_OPTIONAL** EXTENDCIRCUIT queries can omit the path if the circuit is zero
**FEATURE_EXTENDED_EVENTS** 'EXTENDED_EVENTS' optional feature
**FEATURE_VERBOSE_NAMES** 'VERBOSE_NAMES' optional feature
@@ -347,6 +348,7 @@ Requirement = stem.util.enum.Enum(
("EVENT_CONN_BW", Version('0.2.5.2-alpha')),
("EVENT_CIRC_BW", Version('0.2.5.2-alpha')),
("EVENT_CELL_STATS", Version('0.2.5.2-alpha')),
+ ("EVENT_TB_EMPTY", Version('0.2.5.2-alpha')),
("EXTENDCIRCUIT_PATH_OPTIONAL", Version("0.2.2.9")),
("FEATURE_EXTENDED_EVENTS", Version("0.2.2.1-alpha")),
("FEATURE_VERBOSE_NAMES", Version("0.2.2.1-alpha")),
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index 09fca4f..c3cdf7a 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -357,6 +357,13 @@ CELL_STATS_BAD_1 = "650 CELL_STATS OutboundAdded=create_fast:-1,relay_early:2"
CELL_STATS_BAD_2 = "650 CELL_STATS OutboundAdded=create_fast:arg,relay_early:-2"
CELL_STATS_BAD_3 = "650 CELL_STATS OutboundAdded=create_fast!:1,relay_early:-2"
+TB_EMPTY_1 = "650 TB_EMPTY ORCONN ID=16 READ=0 WRITTEN=0 LAST=100"
+TB_EMPTY_2 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=100"
+TB_EMPTY_3 = "650 TB_EMPTY RELAY READ=93 WRITTEN=93 LAST=100"
+
+TB_EMPTY_BAD_1 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=blarg LAST=100"
+TB_EMPTY_BAD_2 = "650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=-100"
+
def _get_event(content):
controller_event = mocking.get_message(content)
@@ -1282,6 +1289,40 @@ class TestEvents(unittest.TestCase):
self.assertRaises(ProtocolError, _get_event, CELL_STATS_BAD_2)
self.assertRaises(ProtocolError, _get_event, CELL_STATS_BAD_3)
+ def test_token_bucket_empty_event(self):
+ event = _get_event(TB_EMPTY_1)
+
+ self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
+ self.assertEqual(TB_EMPTY_1.lstrip("650 "), str(event))
+ self.assertEqual(stem.TokenBucket.ORCONN, event.bucket)
+ self.assertEqual("16", event.id)
+ self.assertEqual(0, event.read)
+ self.assertEqual(0, event.written)
+ self.assertEqual(100, event.last_refill)
+
+ event = _get_event(TB_EMPTY_2)
+
+ self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
+ self.assertEqual(TB_EMPTY_2.lstrip("650 "), str(event))
+ self.assertEqual(stem.TokenBucket.GLOBAL, event.bucket)
+ self.assertEqual(None, event.id)
+ self.assertEqual(93, event.read)
+ self.assertEqual(93, event.written)
+ self.assertEqual(100, event.last_refill)
+
+ event = _get_event(TB_EMPTY_3)
+
+ self.assertTrue(isinstance(event, stem.response.events.TokenBucketEmptyEvent))
+ self.assertEqual(TB_EMPTY_3.lstrip("650 "), str(event))
+ self.assertEqual(stem.TokenBucket.RELAY, event.bucket)
+ self.assertEqual(None, event.id)
+ self.assertEqual(93, event.read)
+ self.assertEqual(93, event.written)
+ self.assertEqual(100, event.last_refill)
+
+ self.assertRaises(ProtocolError, _get_event, TB_EMPTY_BAD_1)
+ self.assertRaises(ProtocolError, _get_event, TB_EMPTY_BAD_2)
+
def test_unrecognized_enum_logging(self):
"""
Checks that when event parsing gets a value that isn't recognized by stem's
More information about the tor-commits
mailing list