commit c35a626af19a5d22b8cc1ca1cef5bae212e3a726 Author: Damian Johnson atagar@torproject.org Date: Sun Nov 4 21:06:05 2012 -0800
BandwidthEvent class
Adding a class to handle BW events. This is the easiest type of tor event to test because it's emitted every second. The other event types we'll probably need to go with unit tests. --- stem/control.py | 2 -- stem/response/events.py | 34 +++++++++++++++++++++++++++++++--- test/integ/control/controller.py | 4 ++++ 3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/stem/control.py b/stem/control.py index fdcf972..bfb907c 100644 --- a/stem/control.py +++ b/stem/control.py @@ -1408,8 +1408,6 @@ class Controller(BaseController): return response.entries
def _handle_event(self, event_message): - # TODO: parse the event_message into a stem.response.events.Event class - stem.response.convert("EVENT", event_message, arrived_at=time.time())
with self._event_listeners_lock: diff --git a/stem/response/events.py b/stem/response/events.py index 32dd655..7a2f9da 100644 --- a/stem/response/events.py +++ b/stem/response/events.py @@ -1,6 +1,7 @@ import re
import stem.response +import stem.socket
# Matches keyword=value arguments. This can't be a simple "(.*)=(.*)" pattern # because some positional arguments, like circuit paths, can have an equal @@ -27,6 +28,11 @@ class Event(stem.response.ControlMessage): self.type = fields.pop(0) self.arrived_at = arrived_at
+ # if we're a recognized event type then translate ourselves into that subclass + + if self.type in EVENT_TYPE_TO_CLASS: + self.__class__ = EVENT_TYPE_TO_CLASS[self.type] + # Tor events contain some number of positional arguments followed by # key/value mappings. Parsing keyword arguments from the end until we hit # something that isn't a key/value mapping. The rest are positional. @@ -58,8 +64,30 @@ class Event(stem.response.ControlMessage): for controller_attr_name, attr_name in self._KEYWORD_ARGS.items(): setattr(self, attr_name, self.keyword_args.get(controller_attr_name))
- # if we're a recognized event type then translate ourselves into that subclass + self._parse() + + # method overwritten by our subclasses for special handling that they do + def _parse(self): + pass + +class BandwidthEvent(Event): + """ + Event emitted every second with the bytes sent and received by tor. + + :var long read: bytes received by tor that second + :var long written: bytes sent by tor that second + """ + + _POSITIONAL_ARGS = ("read", "written") + + def _parse(self): + if (self.read and not self.read.isdigit()) or (self.written and not self.written.isdigit()): + raise stem.socket.ProtocolError("A BW event's bytes sent and received values should be numeric, received: %s" % self)
- #self.__class__ = response_class - #self._parse_message() + self.read = long(self.read) + self.written = long(self.written) + +EVENT_TYPE_TO_CLASS = { + "BW": BandwidthEvent, +}
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py index 8f93d53..496028c 100644 --- a/test/integ/control/controller.py +++ b/test/integ/control/controller.py @@ -93,6 +93,10 @@ class TestController(unittest.TestCase): self.assertTrue(isinstance(event, stem.response.events.Event)) self.assertEqual(2, len(event.positional_args)) self.assertEqual({}, event.keyword_args) + + self.assertTrue(isinstance(event, stem.response.events.BandwidthEvent)) + self.assertTrue(hasattr(event, 'read')) + self.assertTrue(hasattr(event, 'written'))
def test_getinfo(self): """
tor-commits@lists.torproject.org