[tor-commits] [stem/master] Notifying status listeners of SIGHUPs

atagar at torproject.org atagar at torproject.org
Wed Jan 16 17:30:07 UTC 2013


commit 1fb3a96c75f5eb6f1706ab7d34d582df3ee2cce7
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Jan 16 09:27:27 2013 -0800

    Notifying status listeners of SIGHUPs
    
    Our status listeners should be notified when three things happen...
    
    * we newly connect to a controller
    * we disconnect from a controller
    * tor's state is reset by a SIGHUP signal
    
    We had implemented the first two, but not the third. Correcting this oversight.
---
 stem/control.py                  |    8 ++++++-
 test/integ/control/controller.py |   42 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 8d6f1b7..10bc667 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -146,7 +146,7 @@ import stem.util.enum
 import stem.util.tor_tools
 import stem.version
 
-from stem import UNDEFINED, CircStatus
+from stem import UNDEFINED, CircStatus, Signal
 from stem.util import log
 
 # state changes a control socket can have
@@ -675,6 +675,12 @@ class Controller(BaseController):
     self._geoip_failure_count = 0
     self._enabled_features = []
 
+    def _sighup_listener(event):
+      if event.signal == Signal.RELOAD:
+        self._notify_status_listeners(State.RESET)
+
+    self.add_event_listener(_sighup_listener, EventType.SIGNAL)
+
   def connect(self):
     super(Controller, self).connect()
     self.clear_cache()
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 4d39a8b..600403b 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -9,6 +9,7 @@ import shutil
 import socket
 import tempfile
 import threading
+import time
 import unittest
 
 import stem.connection
@@ -22,7 +23,8 @@ import test.network
 import test.runner
 import test.util
 
-from stem.control import EventType
+from stem import Signal
+from stem.control import EventType, State
 from stem.exit_policy import ExitPolicy
 from stem.version import Requirement
 
@@ -56,6 +58,44 @@ class TestController(unittest.TestCase):
     else:
       self.assertRaises(stem.SocketError, stem.control.Controller.from_socket_file, test.runner.CONTROL_SOCKET_PATH)
 
+  def test_reset_notification(self):
+    """
+    Checks that a notificiation listener is... well, notified of SIGHUPs.
+    """
+
+    if test.runner.require_control(self):
+      return
+    elif test.runner.require_version(self, stem.version.Requirement.EVENT_SIGNAL):
+      return
+
+    with test.runner.get_runner().get_tor_controller() as controller:
+      received_events = []
+
+      def status_listener(my_controller, state, timestamp):
+        received_events.append((my_controller, state, timestamp))
+
+      controller.add_status_listener(status_listener)
+
+      before = time.time()
+      controller.signal(Signal.HUP)
+
+      # I really hate adding a sleep here, but signal() is non-blocking.
+      while len(received_events) == 0:
+        if (time.time() - before) > 2:
+          self.fail("We've waited a couple seconds for SIGHUP to generate an event, but it didn't come")
+
+        time.sleep(0.1)
+
+      after = time.time()
+
+      self.assertEqual(1, len(received_events))
+
+      state_controller, state_type, state_timestamp = received_events[0]
+
+      self.assertEqual(controller, state_controller)
+      self.assertEqual(State.RESET, state_type)
+      self.assertTrue(state_timestamp > before and state_timestamp < after)
+
   def test_event_handling(self):
     """
     Add a couple listeners for various events and make sure that they receive



More information about the tor-commits mailing list