[tor-commits] [stem/master] Moving tor launcher into stem function

atagar at torproject.org atagar at torproject.org
Thu Oct 20 17:11:24 UTC 2011


commit 3a913b6b92796f2195c28e55ead532a0fef906e6
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Oct 20 09:58:37 2011 -0700

    Moving tor launcher into stem function
    
    In writing the stem integ tests I needed a function for starting tor then
    blocking for its bootstraping to complete. Yesterday Jake mentioned that he
    could use a launch_tor() function in TorCtl so I'm generalizing this code and
    moving it into the stem lib.
---
 stem/__init__.py |    2 +-
 stem/process.py  |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/runner.py   |   48 ++++++++++-------------------------------
 3 files changed, 74 insertions(+), 37 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 01c350c..5ac77ed 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -2,5 +2,5 @@
 Library for working with the tor process.
 """
 
-__all__ = ["types"]
+__all__ = ["process", "types"]
 
diff --git a/stem/process.py b/stem/process.py
new file mode 100644
index 0000000..f049610
--- /dev/null
+++ b/stem/process.py
@@ -0,0 +1,61 @@
+"""
+Helper functions for working with tor as a process. These are mostly os
+dependent, only working on linux, osx, and bsd.
+"""
+
+import os
+import signal
+import subprocess
+
+# number of seconds before we time out our attempt to start a tor instance
+TOR_INIT_TIMEOUT = 90
+
+def launch_tor(torrc_path, init_msg_handler = None):
+  """
+  Initializes a tor process. This blocks until initialization completes or we
+  error out.
+  
+  Arguments:
+    torrc_path (str)           - location of the torrc for us to use
+    init_msg_handler (functor) - optional functor that will be provided with
+                                 tor's initialization stdout as we get it
+  
+  Returns:
+    subprocess.Popen instance for the tor subprocess
+  
+  Raises:
+    OSError if we either fail to create the tor process or reached a timeout
+    without success
+  """
+  
+  # double check that we have a torrc to work with
+  if not os.path.exists(torrc_path):
+    raise OSError("torrc doesn't exist (%s)" % torrc_path)
+  
+  # starts a tor subprocess, raising an OSError if it fails
+  tor_process = subprocess.Popen(["tor", "-f", torrc_path], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
+  
+  # time ourselves out if we reach TOR_INIT_TIMEOUT
+  def timeout_handler(signum, frame):
+    # terminates the uninitialized tor process and raise on timeout
+    tor_process.kill()
+    raise OSError("reached a %i second timeout without success" % TOR_INIT_TIMEOUT)
+  
+  signal.signal(signal.SIGALRM, timeout_handler)
+  signal.alarm(TOR_INIT_TIMEOUT)
+  
+  while True:
+    init_line = tor_process.stdout.readline().strip()
+    
+    # this will provide empty results if the process is terminated
+    if not init_line:
+      tor_process.kill() # ... but best make sure
+      raise OSError("process terminated")
+    
+    # provide the caller with the initialization message if they want it
+    if init_msg_handler: init_msg_handler(init_line)
+    
+    # return the process if we're done with bootstrapping
+    if init_line.endswith("Bootstrapped 100%: Done."):
+      return tor_process
+
diff --git a/test/runner.py b/test/runner.py
index 6f76d01..c795ea8 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -6,9 +6,9 @@ import os
 import sys
 import time
 import shutil
-import signal
 import tempfile
-import subprocess
+
+import stem.process
 
 from stem.util import term
 
@@ -87,44 +87,20 @@ class Runner:
       without success
     """
     
+    def print_init_line(init_line):
+      """
+      Prints output from tor's stdout while it starts up.
+      """
+      
+      print term.format("  %s" % init_line, term.Color.BLUE)
+    
     print term.format("Starting tor...", term.Color.BLUE, term.Attr.BOLD)
     start_time = time.time()
     
     try:
-      # terminate our previous instance before continuing if we had one
-      if self._tor_process: self._tor_process.kill()
-      
-      # double check that we have a torrc to work with
-      torrc_dst = self.get_torrc_path()
-      if not os.path.exists(torrc_dst):
-        raise OSError("torrc doesn't exist (%s)" % torrc_dst)
-      
-      # starts a tor subprocess, raising an OSError if it fails
-      self._tor_process = subprocess.Popen(["tor", "-f", torrc_dst], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
-      
-      # time ourselves out if we reach TOR_INIT_TIMEOUT
-      def timeout_handler(signum, frame):
-        # terminates the uninitialized tor process and raise on timeout
-        self._tor_process.kill()
-        raise OSError("reached a %i second timeout without success" % TOR_INIT_TIMEOUT)
-      
-      signal.signal(signal.SIGALRM, timeout_handler)
-      signal.alarm(TOR_INIT_TIMEOUT)
-      
-      while True:
-        init_line = self._tor_process.stdout.readline().strip()
-        
-        # this will provide empty results if the process is terminated
-        if not init_line:
-          self._tor_process.kill() # ... but best make sure
-          raise OSError("process terminated")
-        
-        print term.format("  %s" % init_line, term.Color.BLUE)
-        
-        # return the process if we're done with bootstrapping
-        if init_line.endswith("Bootstrapped 100%: Done."):
-          print term.format("  done (%i seconds)" % (time.time() - start_time), term.Color.BLUE, term.Attr.BOLD)
-          return
+      self._tor_process = stem.process.launch_tor(self.get_torrc_path(), print_init_line)
+      print term.format("  done (%i seconds)" % (time.time() - start_time), term.Color.BLUE, term.Attr.BOLD)
+      return
     except OSError, exc:
       print term.format("  failed to start tor: %s" % exc, term.Color.RED, term.Attr.BOLD)
       raise exc





More information about the tor-commits mailing list