[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Adding separate funtion for launching tor with tmp torrc
commit 4d6c8c8943d9540d5fcc6c39c503ca523e4683d3
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sun May 20 14:49:31 2012 -0700
Adding separate funtion for launching tor with tmp torrc
Like Vidalia, adding a function that creates a torrc, launches tor with it,
then removes it from disk. This is preferable to using the commandline
arguments since the those shouldn't be used for substantial data nor the hashed
password.
This replaces launch_tor()'s options argument, though I added a more genral
args replacement that can be used to do the same if the user wants.
---
stem/process.py | 52 ++++++++++++++++++++++++++++++++++++++++--------
test/integ/process.py | 26 ++++++-----------------
test/runner.py | 2 +
3 files changed, 52 insertions(+), 28 deletions(-)
diff --git a/stem/process.py b/stem/process.py
index 32bf1a7..a65c124 100644
--- a/stem/process.py
+++ b/stem/process.py
@@ -1,7 +1,8 @@
"""
Helper functions for working with tor as a process.
-launch_tor - starts up a tor process
+launch_tor - starts up a tor process
+launch_tor_with_config - starts a tor process with a custom torrc
"""
import re
@@ -18,7 +19,7 @@ DEFAULT_INIT_TIMEOUT = 90
NO_TORRC = "<no torrc>"
-def launch_tor(tor_cmd = "tor", options = None, torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT):
+def launch_tor(tor_cmd = "tor", args = None, torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT):
"""
Initializes a tor process. This blocks until initialization completes or we
error out.
@@ -30,7 +31,7 @@ def launch_tor(tor_cmd = "tor", options = None, torrc_path = None, completion_pe
Arguments:
tor_cmd (str) - command for starting tor
- options (dict) - configuration options, such as ("ControlPort": "9051")
+ args (list) - additional arguments for tor
torrc_path (str) - location of the torrc for us to use
completion_percent (int) - percent of bootstrap completion at which
this'll return
@@ -53,18 +54,15 @@ def launch_tor(tor_cmd = "tor", options = None, torrc_path = None, completion_pe
# starts a tor subprocess, raising an OSError if it fails
runtime_args, temp_file = [tor_cmd], None
+ if args: runtime_args += args
+
if torrc_path:
if torrc_path == NO_TORRC:
- temp_file = tempfile.mkstemp("-empty-torrc", text = True)[1]
+ temp_file = tempfile.mkstemp(prefix = "empty-torrc-", text = True)[1]
runtime_args += ["-f", temp_file]
else:
runtime_args += ["-f", torrc_path]
- if options:
- for key, value in options.items():
- value = value.replace('"', '\\"')
- runtime_args += ["--%s" % key.lower(), value]
-
tor_process = subprocess.Popen(runtime_args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
if timeout:
@@ -112,3 +110,39 @@ def launch_tor(tor_cmd = "tor", options = None, torrc_path = None, completion_pe
if ": " in msg: msg = msg.split(": ")[-1].strip()
last_problem = msg
+def launch_tor_with_config(config, tor_cmd = "tor", completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT):
+ """
+ Initializes a tor process, like launch_tor(), but with a customized
+ configuration. This writes a temporary torrc to disk, launches tor, then
+ deletes the torrc.
+
+ Arguments:
+ config (dict) - configuration options, such as ("ControlPort": "9051")
+ tor_cmd (str) - command for starting tor
+ completion_percent (int) - percent of bootstrap completion at which
+ this'll return
+ init_msg_handler (functor) - optional functor that will be provided with
+ tor's initialization stdout as we get it
+ timeout (int) - time after which the attempt to start tor is
+ aborted, no timeouts are applied if None
+
+ 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
+ """
+
+ torrc_path = tempfile.mkstemp(prefix = "torrc-", text = True)[1]
+
+ try:
+ with open(torrc_path, "w") as torrc_file:
+ for key, value in config.items():
+ torrc_file.write("%s %s\n" % (key, value))
+
+ return launch_tor(tor_cmd, None, torrc_path, completion_percent, init_msg_handler, timeout)
+ finally:
+ try: os.remove(torrc_path)
+ except: pass
+
diff --git a/test/integ/process.py b/test/integ/process.py
index f189f46..b7e5040 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -9,26 +9,19 @@ import stem.socket
import stem.process
import test.runner
-# Tests are target independent. Only run once even if there's multiple targets.
-
-RAN_TESTS = []
-
class TestProcess(unittest.TestCase):
- def test_launch_tor_options(self):
+ def test_launch_tor_with_config(self):
"""
- Runs launch_tor with options specified via the commandline rather than the
- torrc.
+ Exercises launch_tor_with_config.
"""
- test_name = 'test_launch_tor_options'
- if test_name in RAN_TESTS: self.skipTest("(already ran)")
+ test.runner.only_run_once(self, "test_launch_tor_with_config")
# Launch tor without a torrc, but with a control port. Confirms that this
# works by checking that we're still able to access the new instance.
- tor_process = stem.process.launch_tor(
- options = {'SocksPort': '2777', 'ControlPort': '2778'},
- torrc_path = stem.process.NO_TORRC,
+ tor_process = stem.process.launch_tor_with_config(
+ config = {'SocksPort': '2777', 'ControlPort': '2778'},
completion_percent = 5
)
@@ -45,21 +38,16 @@ class TestProcess(unittest.TestCase):
finally:
if control_socket: control_socket.close()
tor_process.kill()
-
- RAN_TESTS.append(test_name)
def test_launch_tor_with_timeout(self):
"""
Runs launch_tor where it times out before completing.
"""
- test_name = 'test_launch_tor_with_timeout'
- if test_name in RAN_TESTS: self.skipTest("(already ran)")
+ test.runner.only_run_once(self, "test_launch_tor_with_timeout")
start_time = time.time()
- self.assertRaises(OSError, stem.process.launch_tor, "tor", {'SocksPort': '2777'}, stem.process.NO_TORRC, 100, None, 2)
+ self.assertRaises(OSError, stem.process.launch_tor_with_config, {'SocksPort': '2777'}, "tor", 100, None, 2)
runtime = time.time() - start_time
self.assertTrue(runtime > 2 and runtime < 3)
-
- RAN_TESTS.append(test_name)
diff --git a/test/runner.py b/test/runner.py
index 2dc0cbb..286d4a8 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -123,6 +123,8 @@ def require_version(test_case, req_version):
def only_run_once(test_case, test_name):
"""
Skips the test if it has ran before. If it hasn't then flags it as being ran.
+ This is useful to prevent lengthy tests that are independent of integ targets
+ from being run repeatedly with RUN_ALL.
Arguments:
test_case (unittest.TestCase) - test being ran
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits