[tor-commits] [stem/master] Adding Controller class

atagar at torproject.org atagar at torproject.org
Mon May 28 03:56:38 UTC 2012


commit 045a5ec8774074eb92066571dfc661c4098bd77a
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun May 27 14:35:15 2012 -0700

    Adding Controller class
    
    Making a class for the general controller. As a todo comment mentiond, moving
    the from_port/from_socket_file helper functions there and revising the tests to
    reflect that.
---
 run_tests.py                          |    2 +
 stem/control.py                       |   92 +++++++++++++++++---------------
 test/integ/control/__init__.py        |    2 +-
 test/integ/control/base_controller.py |   22 --------
 test/integ/control/controller.py      |   36 +++++++++++++
 5 files changed, 88 insertions(+), 66 deletions(-)

diff --git a/run_tests.py b/run_tests.py
index 85a4f65..d123081 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -32,6 +32,7 @@ import test.integ.connection.authentication
 import test.integ.connection.connect
 import test.integ.connection.protocolinfo
 import test.integ.control.base_controller
+import test.integ.control.controller
 import test.integ.socket.control_message
 import test.integ.socket.control_socket
 import test.integ.descriptor.reader
@@ -118,6 +119,7 @@ INTEG_TESTS = (
   test.integ.connection.authentication.TestAuthenticate,
   test.integ.connection.connect.TestConnect,
   test.integ.control.base_controller.TestBaseController,
+  test.integ.control.controller.TestController,
 )
 
 def load_user_configuration(test_config):
diff --git a/stem/control.py b/stem/control.py
index 9b912e5..e2d3d90 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -8,6 +8,9 @@ a higher level.
 from_port - Provides a Controller based on a port connection.
 from_socket_file - Provides a Controller based on a socket file connection.
 
+Controller - General controller class intended for direct use.
+  +- get_info - issues a GETINFO query
+
 BaseController - Base controller class asynchronous message handling.
   |- msg - communicates with the tor process
   |- is_alive - reports if our connection to tor is open or closed
@@ -37,54 +40,13 @@ class BaseController:
   """
   Controller for the tor process. This is a minimal base class for other
   controllers, providing basic process communication and event listing. Don't
-  use this directly - subclasses provide higher level functionality.
+  use this directly - subclasses like the Controller provide higher level
+  functionality.
   
   Do not continue to directly interacte with the ControlSocket we're
   constructed from - use our wrapper methods instead.
   """
   
-  # TODO: Convenience methods for the BaseController are pointless since
-  # callers generally won't want to make instances of this directly. Move
-  # these to the Controller class once we have one.
-  
-  def from_port(control_addr = "127.0.0.1", control_port = 9051):
-    """
-    Constructs a ControlPort based Controller.
-    
-    Arguments:
-      control_addr (str) - ip address of the controller
-      control_port (int) - port number of the controller
-    
-    Returns:
-      stem.control.Controller attached to the given port
-    
-    Raises:
-      stem.socket.SocketError if we're unable to establish a connection
-    """
-    
-    control_port = stem.socket.ControlPort(control_addr, control_port)
-    return BaseController(control_port)
-  
-  def from_socket_file(socket_path = "/var/run/tor/control"):
-    """
-    Constructs a ControlSocketFile based Controller.
-    
-    Arguments:
-      socket_path (str) - path where the control socket is located
-    
-    Returns:
-      stem.control.Controller attached to the given socket file
-    
-    Raises:
-      stem.socket.SocketError if we're unable to establish a connection
-    """
-    
-    control_socket = stem.socket.ControlSocketFile(socket_path)
-    return BaseController(control_socket)
-  
-  from_port = staticmethod(from_port)
-  from_socket_file = staticmethod(from_socket_file)
-  
   def __init__(self, control_socket):
     self._socket = control_socket
     self._msg_lock = threading.RLock()
@@ -424,3 +386,47 @@ class BaseController:
         self._event_notice.wait()
         self._event_notice.clear()
 
+class Controller(BaseController):
+  """
+  Communicates with a control socket. This is built on top of the
+  BaseController and provides a more user friendly API for library users.
+  """
+  
+  def from_port(control_addr = "127.0.0.1", control_port = 9051):
+    """
+    Constructs a ControlPort based Controller.
+    
+    Arguments:
+      control_addr (str) - ip address of the controller
+      control_port (int) - port number of the controller
+    
+    Returns:
+      stem.control.Controller attached to the given port
+    
+    Raises:
+      stem.socket.SocketError if we're unable to establish a connection
+    """
+    
+    control_port = stem.socket.ControlPort(control_addr, control_port)
+    return Controller(control_port)
+  
+  def from_socket_file(socket_path = "/var/run/tor/control"):
+    """
+    Constructs a ControlSocketFile based Controller.
+    
+    Arguments:
+      socket_path (str) - path where the control socket is located
+    
+    Returns:
+      stem.control.Controller attached to the given socket file
+    
+    Raises:
+      stem.socket.SocketError if we're unable to establish a connection
+    """
+    
+    control_socket = stem.socket.ControlSocketFile(socket_path)
+    return Controller(control_socket)
+  
+  from_port = staticmethod(from_port)
+  from_socket_file = staticmethod(from_socket_file)
+
diff --git a/test/integ/control/__init__.py b/test/integ/control/__init__.py
index 715082f..10c3cf5 100644
--- a/test/integ/control/__init__.py
+++ b/test/integ/control/__init__.py
@@ -2,5 +2,5 @@
 Integration tests for stem.control.
 """
 
-__all__ = ["base_controller"]
+__all__ = ["base_controller", "controller"]
 
diff --git a/test/integ/control/base_controller.py b/test/integ/control/base_controller.py
index 09c68da..32239d2 100644
--- a/test/integ/control/base_controller.py
+++ b/test/integ/control/base_controller.py
@@ -35,28 +35,6 @@ class TestBaseController(unittest.TestCase):
   def setUp(self):
     test.runner.require_control(self)
   
-  def test_from_port(self):
-    """
-    Basic sanity check for the from_port constructor.
-    """
-    
-    if test.runner.Torrc.PORT in test.runner.get_runner().get_options():
-      with stem.control.BaseController.from_port(control_port = test.runner.CONTROL_PORT) as controller:
-        self.assertTrue(isinstance(controller, stem.control.BaseController))
-    else:
-      self.assertRaises(stem.socket.SocketError, stem.control.BaseController.from_port, "127.0.0.1", test.runner.CONTROL_PORT)
-  
-  def test_from_socket_file(self):
-    """
-    Basic sanity check for the from_socket_file constructor.
-    """
-    
-    if test.runner.Torrc.SOCKET in test.runner.get_runner().get_options():
-      with stem.control.BaseController.from_socket_file(socket_path = test.runner.CONTROL_SOCKET_PATH) as controller:
-        self.assertTrue(isinstance(controller, stem.control.BaseController))
-    else:
-      self.assertRaises(stem.socket.SocketError, stem.control.BaseController.from_socket_file, test.runner.CONTROL_SOCKET_PATH)
-  
   def test_connect_repeatedly(self):
     """
     Connects and closes the socket repeatedly. This is a simple attempt to
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
new file mode 100644
index 0000000..4bf8284
--- /dev/null
+++ b/test/integ/control/controller.py
@@ -0,0 +1,36 @@
+"""
+Integration tests for the stem.control.Controller class.
+"""
+
+import unittest
+
+import stem.control
+import stem.socket
+import test.runner
+
+class TestController(unittest.TestCase):
+  def setUp(self):
+    test.runner.require_control(self)
+  
+  def test_from_port(self):
+    """
+    Basic sanity check for the from_port constructor.
+    """
+    
+    if test.runner.Torrc.PORT in test.runner.get_runner().get_options():
+      with stem.control.Controller.from_port(control_port = test.runner.CONTROL_PORT) as controller:
+        self.assertTrue(isinstance(controller, stem.control.Controller))
+    else:
+      self.assertRaises(stem.socket.SocketError, stem.control.Controller.from_port, "127.0.0.1", test.runner.CONTROL_PORT)
+  
+  def test_from_socket_file(self):
+    """
+    Basic sanity check for the from_socket_file constructor.
+    """
+    
+    if test.runner.Torrc.SOCKET in test.runner.get_runner().get_options():
+      with stem.control.Controller.from_socket_file(socket_path = test.runner.CONTROL_SOCKET_PATH) as controller:
+        self.assertTrue(isinstance(controller, stem.control.Controller))
+    else:
+      self.assertRaises(stem.socket.SocketError, stem.control.Controller.from_socket_file, test.runner.CONTROL_SOCKET_PATH)
+





More information about the tor-commits mailing list