[tor-commits] [stem/master] Making explicit checks for tor accessibility
atagar at torproject.org
atagar at torproject.org
Fri Jan 13 17:46:31 UTC 2012
commit 0071fadd8b69eda81cdd9826719037fafdebbb74
Author: Damian Johnson <atagar at torproject.org>
Date: Fri Jan 13 08:28:32 2012 -0800
Making explicit checks for tor accessibility
Several 'test/runner.py' functions query against our tor instance. However, in
some integ tests we don't have any method for doing that. Rather than returning
a default value I'm raising in those cases, and adding an is_accessible method
to make our tests more readable.
---
test/integ/socket/control_message.py | 30 +++++++++--------
test/runner.py | 57 +++++++++++++++++++++++++---------
2 files changed, 58 insertions(+), 29 deletions(-)
diff --git a/test/integ/socket/control_message.py b/test/integ/socket/control_message.py
index d0c44dc..33a54bf 100644
--- a/test/integ/socket/control_message.py
+++ b/test/integ/socket/control_message.py
@@ -20,13 +20,14 @@ class TestControlMessage(unittest.TestCase):
Checks message parsing when we have a valid but unauthenticated socket.
"""
- control_socket = test.runner.get_runner().get_tor_socket(False)
- if not control_socket: self.skipTest("(no control socket)")
+ runner = test.runner.get_runner()
+ if not runner.is_accessible(): self.skipTest("(no control socket)")
# If an unauthenticated connection gets a message besides AUTHENTICATE or
# PROTOCOLINFO then tor will give an 'Authentication required.' message and
# hang up.
+ control_socket = runner.get_tor_socket(False)
control_socket.send("GETINFO version")
auth_required_response = control_socket.recv()
@@ -66,8 +67,9 @@ class TestControlMessage(unittest.TestCase):
Parses the response for a command which doesn't exist.
"""
- control_socket = test.runner.get_runner().get_tor_socket()
- if not control_socket: self.skipTest("(no control socket)")
+ runner = test.runner.get_runner()
+ if not runner.is_accessible(): self.skipTest("(no control socket)")
+ control_socket = runner.get_tor_socket()
control_socket.send("blarg")
unrecognized_command_response = control_socket.recv()
@@ -83,8 +85,9 @@ class TestControlMessage(unittest.TestCase):
Parses the response for a GETINFO query which doesn't exist.
"""
- control_socket = test.runner.get_runner().get_tor_socket()
- if not control_socket: self.skipTest("(no control socket)")
+ runner = test.runner.get_runner()
+ if not runner.is_accessible(): self.skipTest("(no control socket)")
+ control_socket = runner.get_tor_socket()
control_socket.send("GETINFO blarg")
unrecognized_key_response = control_socket.recv()
@@ -102,9 +105,8 @@ class TestControlMessage(unittest.TestCase):
runner = test.runner.get_runner()
torrc_dst = runner.get_torrc_path()
-
+ if not runner.is_accessible(): self.skipTest("(no control socket)")
control_socket = runner.get_tor_socket()
- if not control_socket: self.skipTest("(no control socket)")
control_socket.send("GETINFO config-file")
config_file_response = control_socket.recv()
@@ -122,9 +124,10 @@ class TestControlMessage(unittest.TestCase):
runner = test.runner.get_runner()
req_version = stem.version.Requirement.GETINFO_CONFIG_TEXT
- our_version = runner.get_tor_version()
- if our_version and our_version < req_version:
+ if not runner.is_accessible():
+ self.skipTest("(no control socket)")
+ elif runner.get_tor_version() < req_version:
self.skipTest("(requires %s)" % req_version)
# We can't be certain of the order, and there may be extra config-text
@@ -142,8 +145,6 @@ class TestControlMessage(unittest.TestCase):
torrc_contents.append(line)
control_socket = runner.get_tor_socket()
- if not control_socket: self.skipTest("(no control socket)")
-
control_socket.send("GETINFO config-text")
config_text_response = control_socket.recv()
@@ -169,8 +170,9 @@ class TestControlMessage(unittest.TestCase):
Issues 'SETEVENTS BW' and parses a few events.
"""
- control_socket = test.runner.get_runner().get_tor_socket()
- if not control_socket: self.skipTest("(no control socket)")
+ runner = test.runner.get_runner()
+ if not runner.is_accessible(): self.skipTest("(no control socket)")
+ control_socket = runner.get_tor_socket()
control_socket.send("SETEVENTS BW")
setevents_response = control_socket.recv()
diff --git a/test/runner.py b/test/runner.py
index d5f4a91..5841154 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -10,11 +10,13 @@ Runner - Runtime context for our integration tests.
|- start - prepares and starts a tor instance for our tests to run against
|- stop - stops our tor instance and cleans up any temporary files
|- is_running - checks if our tor test instance is running
+ |- is_accessible - checks if our tor instance can be connected to
|- is_debugging_prevented - checks if DisableDebuggerAttachment is set
|- get_test_dir - testing directory path
|- get_torrc_path - path to our tor instance's torrc
|- get_torrc_contents - contents of our tor instance's torrc
|- get_connection_type - method by which controllers can connect to tor
+ |- get_connection_options - connection related options we're running with
|- get_pid - process id of our tor process
|- get_tor_socket - provides a socket to the tor instance
+- get_tor_version - provides the version of tor we're running against
@@ -129,6 +131,10 @@ class RunnerStopped(Exception):
"Raised when we try to use a Runner that doesn't have an active tor instance"
pass
+class TorInaccessable(Exception):
+ "Raised when information is needed from tor but the instance we have is inaccessable"
+ pass
+
class Runner:
def __init__(self):
self._config = dict(DEFAULT_CONFIG)
@@ -256,6 +262,17 @@ class Runner:
return is_running
+ def is_accessible(self):
+ """
+ Checks if our tor instance has a method of being connected to or not.
+
+ Returns:
+ True if tor has a control socket or port, False otherwise
+ """
+
+ conn_opts = self.get_connection_options()
+ return OPT_PORT in conn_opts or OPT_SOCKET in conn_opts
+
def is_debugging_prevented(self):
"""
Checks if tor's 'DisableDebuggerAttachment' option is set. This feature has
@@ -263,14 +280,14 @@ class Runner:
https://trac.torproject.org/projects/tor/ticket/3313
Returns:
- True if debugger attachment is disallowd, False otherwise, and None if
- tor can't be checked
+ True if debugger attachment is disallowd, False otherwise
+
+ Raises:
+ TorInaccessable if this can't be determined
"""
# TODO: replace higher level GETCONF query when we have a controller class
control_socket = self.get_tor_socket()
- if control_socket == None: return None
-
control_socket.send("GETCONF DisableDebuggerAttachment")
getconf_response = control_socket.recv()
control_socket.close()
@@ -349,6 +366,16 @@ class Runner:
return self._connection_type
+ def get_connection_options(self):
+ """
+ Provides the connection related options we're running with.
+
+ Returns:
+ list of connection contstants (test.runner.OPT_*) we're running with
+ """
+
+ return CONNECTION_OPTS[self.get_connection_type()]
+
def get_pid(self):
"""
Provides the process id of the tor process.
@@ -371,20 +398,19 @@ class Runner:
authenticate (bool) - if True then the socket is authenticated
Returns:
- stem.socket.ControlSocket connected with our testing instance, returning
- None if we either don't have a test instance or it can't be connected to
- """
+ stem.socket.ControlSocket connected with our testing instance
- connection_type, cookie_path = self.get_connection_type(), self.get_auth_cookie_path()
- if connection_type == None: return None
+ Raises:
+ TorInaccessable if tor can't be connected to
+ """
- conn_opts = CONNECTION_OPTS[connection_type]
+ conn_opts = self.get_connection_options()
if OPT_PORT in conn_opts:
control_socket = stem.socket.ControlPort(control_port = CONTROL_PORT)
elif OPT_SOCKET in conn_opts:
control_socket = stem.socket.ControlSocketFile(CONTROL_SOCKET_PATH)
- else: return None
+ else: raise TorInaccessable("Unable to connect to tor")
if authenticate:
stem.connection.authenticate(control_socket, CONTROL_PASSWORD)
@@ -396,15 +422,16 @@ class Runner:
Queries our test instance for tor's version.
Returns:
- stem.version.Version for our test instance, None if we're unable to
- connect to it
+ stem.version.Version for our test instance
+
+ Raises:
+ TorInaccessable if this can't be determined
"""
# TODO: replace with higher level functions when we've completed a basic
# controller class
control_socket = self.get_tor_socket()
- if not control_socket: return None
control_socket.send("GETINFO version")
version_response = control_socket.recv()
@@ -466,7 +493,7 @@ class Runner:
# resides in is only accessable by the tor user (and refuses to finish
# starting if it isn't).
- if OPT_SOCKET in CONNECTION_OPTS[self._connection_type]:
+ if OPT_SOCKET in self.get_connection_options():
try:
socket_dir = os.path.dirname(CONTROL_SOCKET_PATH)
_print_status(" making control socket directory (%s)... " % socket_dir, STATUS_ATTR, quiet)
More information about the tor-commits
mailing list