[tor-commits] [stem/master] Helper constructors for BaseController instances

atagar at torproject.org atagar at torproject.org
Thu Feb 9 03:19:36 UTC 2012


commit 398cbfb93a4982961e1ce27fc05d82265408e78a
Author: Damian Johnson <atagar at torproject.org>
Date:   Mon Feb 6 08:16:59 2012 -0800

    Helper constructors for BaseController instances
    
    A controller is a wrapper around a ControlSocket instance so adding convenience
    methods to construct both the socket and controller at the same time. These
    will belong to the Controller class later.
---
 stem/control.py                       |   47 +++++++++++++++++++++++++++++++++
 test/integ/control/base_controller.py |   23 ++++++++++++++++
 2 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index d1f30ee..c485cb9 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -4,6 +4,11 @@ Classes for interacting with the tor control socket.
 Controllers are a wrapper around a ControlSocket, retaining its low-level
 connection methods (send, recv, is_alive, etc) in addition to providing methods
 for interacting at 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.
+
+BaseController - ControlSocket subclass providing asynchronous message handling.
 """
 
 import stem.socket
@@ -18,6 +23,48 @@ class BaseController(stem.socket.ControlSocket):
     socket - ControlSocket from which this was constructed
   """
   
+  # 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
   
diff --git a/test/integ/control/base_controller.py b/test/integ/control/base_controller.py
index 467c057..e30964c 100644
--- a/test/integ/control/base_controller.py
+++ b/test/integ/control/base_controller.py
@@ -5,6 +5,7 @@ Integration tests for the stem.control.BaseController class.
 import unittest
 
 import stem.control
+import stem.socket
 import test.runner
 import test.mocking as mocking
 import test.integ.socket.control_socket
@@ -16,6 +17,28 @@ class TestBaseController(unittest.TestCase):
   def tearDown(self):
     mocking.revert_mocking()
   
+  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():
+      controller = stem.control.BaseController.from_port(control_port = test.runner.CONTROL_PORT)
+      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():
+      controller = stem.control.BaseController.from_socket_file(test.runner.CONTROL_SOCKET_PATH)
+      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_socket_passthrough(self):
     """
     The BaseController is a passthrough for the socket it is built from, so





More information about the tor-commits mailing list