[tor-commits] [stem/master] BandwidthEvent class

atagar at torproject.org atagar at torproject.org
Mon Dec 3 02:35:44 UTC 2012


commit c35a626af19a5d22b8cc1ca1cef5bae212e3a726
Author: Damian Johnson <atagar at 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):
     """





More information about the tor-commits mailing list