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

atagar at torproject.org atagar at torproject.org
Mon Dec 3 06:32:32 UTC 2012


commit 47f608b05c0085a5acfb76b08a9efe916b1e09e9
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Dec 2 22:31:22 2012 -0800

    Support for SIGNAL events
    
    Implementation and testing for SIGNAL events. This moves tor's signals to an
    enum, which also makes the Controller's signal() method a little nicer.
---
 stem/__init__.py             |   32 ++++++++++++++++++++++++++++++++
 stem/control.py              |   14 ++------------
 stem/response/events.py      |   36 ++++++++++++++++++++++++++++++++++++
 test/unit/response/events.py |    9 +++++++++
 4 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index ea3a5eb..d7ec4f8 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -28,6 +28,22 @@ Library for working with the tor process.
   **DEBUG**   low level runtime information
   =========== ===========
 
+.. data:: Signal (enum)
+  
+  Signals that the tor process will accept.
+  
+  ========================= ===========
+  Signal                    Description
+  ========================= ===========
+  **RELOAD** or **HUP**     reloads our torrc
+  **SHUTDOWN** or **INT**   shut down, waiting ShutdownWaitLength first if we're a relay
+  **DUMP** or **USR1**      dumps information about open connections and circuits to our log
+  **DEBUG** or **USR2**     switch our logging to the DEBUG runlevel
+  **HALT** or **TERM**      exit tor immediately
+  **NEWNYM**                switch to new circuits, so new application requests don't share any circuits with old ones (this also clears our DNS cache)
+  **CLEARDNSCACHE**         clears cached DNS results
+  ========================= ===========
+
 .. data:: CircStatus (enum)
   
   Statuses that a circuit can be in. Tor may provide statuses not in this enum.
@@ -334,6 +350,7 @@ __all__ = [
   "SocketError",
   "SocketClosed",
   "Runlevel",
+  "Signal",
   "CircStatus",
   "CircBuildFlag",
   "CircPurpose",
@@ -412,6 +429,21 @@ Runlevel = stem.util.enum.UppercaseEnum(
   "ERR",
 )
 
+Signal = stem.util.enum.UppercaseEnum(
+  "RELOAD",
+  "HUP",
+  "SHUTDOWN",
+  "INT",
+  "DUMP",
+  "USR1",
+  "DEBUG",
+  "USR2",
+  "HALT",
+  "TERM",
+  "NEWNYM",
+  "CLEARDNSCACHE",
+)
+
 CircStatus = stem.util.enum.UppercaseEnum(
   "LAUNCHED",
   "BUILT",
diff --git a/stem/control.py b/stem/control.py
index a8f7913..ec3273a 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -93,6 +93,7 @@ providing its own for interacting at a higher level.
   **NOTICE**            :class:`stem.response.events.LogEvent`
   **NS**                :class:`stem.response.events.NetworkStatusEvent`
   **ORCONN**            :class:`stem.response.events.ORConnEvent`
+  **SIGNAL**            :class:`stem.response.events.SignalEvent`
   **STATUS_CLIENT**     :class:`stem.response.events.StatusEvent`
   **STATUS_GENERAL**    :class:`stem.response.events.StatusEvent`
   **STATUS_SERVER**     :class:`stem.response.events.StatusEvent`
@@ -1327,18 +1328,7 @@ class Controller(BaseController):
     """
     Sends a signal to the Tor client.
     
-    :param str signal: type of signal to be sent. Must be one of the following...
-    
-      * **RELOAD** or **HUP** - reload configuration
-      * **SHUTDOWN** or **INT** - shut down, waiting ShutdownWaitLength first
-        if we're a relay
-      * **DUMP** or **USR1** - dump log information about open connections and
-        circuits
-      * **DEBUG** or **USR2** - switch logging to the DEBUG runlevel
-      * **HALT** or **TERM** - exit immediately
-      * **NEWNYM** - switch to new circuits, so new application requests don't
-        share any circuits with old ones (this also clears our DNS cache)
-      * **CLEARDNSCACHE** - clears cached DNS results
+    :param stem.Signal signal: type of signal to be sent
     
     :raises: :class:`stem.InvalidArguments` if signal provided wasn't recognized
     """
diff --git a/stem/response/events.py b/stem/response/events.py
index 8e437d9..98e1bf3 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -599,6 +599,41 @@ class ORConnEvent(Event):
       log_id = "event.orconn.unknown_reason.%s" % self.reason
       log.log_once(log_id, log.INFO, unrecognized_msg % ('reason', self.reason))
 
+class SignalEvent(Event):
+  """
+  Event that indicates that tor has received and acted upon a signal being sent
+  to the process. As of tor version 0.2.4.6 the only signals conveyed by this
+  event are...
+  
+  * RELOAD
+  * DUMP
+  * DEBUG
+  * NEWNYM
+  * CLEARDNSCACHE
+  
+  This was introduced in tor version 0.2.3.1.
+  
+  :var stem.Signal signal: signal that tor received
+  """
+  
+  _POSITIONAL_ARGS = ("signal",)
+  
+  def _parse(self):
+    # log if we recieved an unrecognized signal
+    unrecognized_msg = UNRECOGNIZED_ATTR_MSG % ("SIGNAL", self)
+    
+    expected_signals = (
+      stem.Signal.RELOAD,
+      stem.Signal.DUMP,
+      stem.Signal.DEBUG,
+      stem.Signal.NEWNYM,
+      stem.Signal.CLEARDNSCACHE,
+    )
+    
+    if not self.signal in expected_signals:
+      log_id = "event.signal.unknown_signal.%s" % self.signal
+      log.log_once(log_id, log.INFO, unrecognized_msg % ('signal', self.signal))
+
 class StatusEvent(Event):
   """
   Notification of a change in tor's state. These are generally triggered for
@@ -729,6 +764,7 @@ EVENT_TYPE_TO_CLASS = {
   "NOTICE": LogEvent,
   "NS": NetworkStatusEvent,
   "ORCONN": ORConnEvent,
+  "SIGNAL": SignalEvent,
   "STATUS_CLIENT": StatusEvent,
   "STATUS_GENERAL": StatusEvent,
   "STATUS_SERVER": StatusEvent,
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index b74f4ad..6d5f0d3 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -499,6 +499,15 @@ class TestEvents(unittest.TestCase):
     self.assertEqual(ORClosureReason.DONE, event.reason)
     self.assertEqual(None, event.circ_count)
   
+  def test_signal_event(self):
+    event = _get_event("650 SIGNAL DEBUG")
+    self.assertTrue(isinstance(event, stem.response.events.SignalEvent))
+    self.assertEqual("SIGNAL DEBUG", str(event))
+    self.assertEqual(Signal.DEBUG, event.signal)
+    
+    event = _get_event("650 SIGNAL DUMP")
+    self.assertEqual(Signal.DUMP, event.signal)
+  
   def test_status_event_consensus_arrived(self):
     event = _get_event(STATUS_CLIENT_CONSENSUS_ARRIVED)
     



More information about the tor-commits mailing list