[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Move test requirements to its own module
commit a29627184ea7d50dc4072dfc4115e68372c52d5f
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Thu May 18 15:35:32 2017 -0700
Move test requirements to its own module
Moving the @require_* annotations to its own dedicated module. Besides the
obvious breakup of test.util this provides namespacing so we can truncate the
function names and use a standard import.
---
test/integ/connection/authentication.py | 25 ++--
test/integ/connection/connect.py | 9 +-
test/integ/control/base_controller.py | 20 ++-
test/integ/control/controller.py | 153 +++++++++++-----------
test/integ/descriptor/extrainfo_descriptor.py | 8 +-
test/integ/descriptor/microdescriptor.py | 8 +-
test/integ/descriptor/networkstatus.py | 18 +--
test/integ/descriptor/remote.py | 46 +++----
test/integ/descriptor/server_descriptor.py | 9 +-
test/integ/installation.py | 8 +-
test/integ/interpreter.py | 8 +-
test/integ/process.py | 37 +++---
test/integ/response/protocolinfo.py | 11 +-
test/integ/socket/control_message.py | 21 ++-
test/integ/socket/control_socket.py | 17 +--
test/integ/util/connection.py | 4 +-
test/integ/util/proc.py | 20 ++-
test/integ/util/system.py | 64 ++++-----
test/integ/version.py | 10 +-
test/require.py | 106 +++++++++++++++
test/unit/descriptor/certificate.py | 8 +-
test/unit/descriptor/hidden_service_descriptor.py | 7 +-
test/unit/manual.py | 9 +-
test/util.py | 101 +-------------
24 files changed, 341 insertions(+), 386 deletions(-)
diff --git a/test/integ/connection/authentication.py b/test/integ/connection/authentication.py
index 007042f..f43a61d 100644
--- a/test/integ/connection/authentication.py
+++ b/test/integ/connection/authentication.py
@@ -9,9 +9,10 @@ import unittest
import stem.connection
import stem.socket
import stem.version
+import test.require
import test.runner
-from test.util import require_controller, tor_version
+from test.util import tor_version
# Responses given by tor for various authentication failures. These may change
# in the future and if they do then this test should be updated.
@@ -106,7 +107,7 @@ class TestAuthenticate(unittest.TestCase):
if tor_version() >= stem.version.Requirement.AUTH_SAFECOOKIE:
self.cookie_auth_methods.append(stem.connection.AuthMethod.SAFECOOKIE)
- @require_controller
+ @test.require.controller
def test_authenticate_general_socket(self):
"""
Tests that the authenticate function can authenticate to our socket.
@@ -118,7 +119,7 @@ class TestAuthenticate(unittest.TestCase):
stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
test.runner.exercise_controller(self, control_socket)
- @require_controller
+ @test.require.controller
def test_authenticate_general_controller(self):
"""
Tests that the authenticate function can authenticate via a Controller.
@@ -130,7 +131,7 @@ class TestAuthenticate(unittest.TestCase):
stem.connection.authenticate(controller, test.runner.CONTROL_PASSWORD, runner.get_chroot())
test.runner.exercise_controller(self, controller)
- @require_controller
+ @test.require.controller
def test_authenticate_general_example(self):
"""
Tests the authenticate function with something like its pydoc example.
@@ -166,7 +167,7 @@ class TestAuthenticate(unittest.TestCase):
finally:
control_socket.close()
- @require_controller
+ @test.require.controller
def test_authenticate_general_password(self):
"""
Tests the authenticate function's password argument.
@@ -201,7 +202,7 @@ class TestAuthenticate(unittest.TestCase):
stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
test.runner.exercise_controller(self, control_socket)
- @require_controller
+ @test.require.controller
def test_authenticate_general_cookie(self):
"""
Tests the authenticate function with only cookie authentication methods.
@@ -226,7 +227,7 @@ class TestAuthenticate(unittest.TestCase):
protocolinfo_response.auth_methods = (method, )
stem.connection.authenticate(control_socket, chroot_path = runner.get_chroot(), protocolinfo_response = protocolinfo_response)
- @require_controller
+ @test.require.controller
def test_authenticate_none(self):
"""
Tests the authenticate_none function.
@@ -239,7 +240,7 @@ class TestAuthenticate(unittest.TestCase):
else:
self.assertRaises(stem.connection.OpenAuthRejected, self._check_auth, auth_type)
- @require_controller
+ @test.require.controller
def test_authenticate_password(self):
"""
Tests the authenticate_password function.
@@ -267,7 +268,7 @@ class TestAuthenticate(unittest.TestCase):
self.assertRaises(exc_type, self._check_auth, auth_type, auth_value)
- @require_controller
+ @test.require.controller
def test_authenticate_cookie(self):
"""
Tests the authenticate_cookie function.
@@ -289,7 +290,7 @@ class TestAuthenticate(unittest.TestCase):
else:
self.assertRaises(stem.connection.CookieAuthRejected, self._check_auth, auth_type, auth_value, False)
- @require_controller
+ @test.require.controller
def test_authenticate_cookie_invalid(self):
"""
Tests the authenticate_cookie function with a properly sized but incorrect
@@ -326,7 +327,7 @@ class TestAuthenticate(unittest.TestCase):
os.remove(auth_value)
- @require_controller
+ @test.require.controller
def test_authenticate_cookie_missing(self):
"""
Tests the authenticate_cookie function with a path that really, really
@@ -337,7 +338,7 @@ class TestAuthenticate(unittest.TestCase):
auth_value = "/if/this/exists/then/they're/asking/for/a/failure"
self.assertRaises(stem.connection.UnreadableCookieFile, self._check_auth, auth_type, auth_value, False)
- @require_controller
+ @test.require.controller
def test_authenticate_cookie_wrong_size(self):
"""
Tests the authenticate_cookie function with our torrc as an auth cookie.
diff --git a/test/integ/connection/connect.py b/test/integ/connection/connect.py
index d50b3af..fd08742 100644
--- a/test/integ/connection/connect.py
+++ b/test/integ/connection/connect.py
@@ -11,10 +11,9 @@ except ImportError:
from io import StringIO
import stem.connection
+import test.require
import test.runner
-from test.util import require_controller
-
class TestConnect(unittest.TestCase):
def setUp(self):
@@ -25,7 +24,7 @@ class TestConnect(unittest.TestCase):
def tearDown(self):
sys.stdout = self.original_stdout
- @require_controller
+ @test.require.controller
def test_connect(self):
"""
Basic sanity checks for the connect function.
@@ -42,7 +41,7 @@ class TestConnect(unittest.TestCase):
test.runner.exercise_controller(self, control_socket)
- @require_controller
+ @test.require.controller
def test_connect_port(self):
"""
Basic sanity checks for the connect_port function.
@@ -62,7 +61,7 @@ class TestConnect(unittest.TestCase):
else:
self.assertEqual(control_socket, None)
- @require_controller
+ @test.require.controller
def test_connect_socket_file(self):
"""
Basic sanity checks for the connect_socket_file function.
diff --git a/test/integ/control/base_controller.py b/test/integ/control/base_controller.py
index 1e64445..4c618e3 100644
--- a/test/integ/control/base_controller.py
+++ b/test/integ/control/base_controller.py
@@ -10,12 +10,10 @@ import unittest
import stem.control
import stem.socket
import stem.util.system
-
+import test.require
import test.runner
import test.util
-from test.util import require_controller
-
class StateObserver(object):
"""
@@ -39,7 +37,7 @@ class StateObserver(object):
class TestBaseController(unittest.TestCase):
- @require_controller
+ @test.require.controller
def test_connect_repeatedly(self):
"""
Connects and closes the socket repeatedly. This is a simple attempt to
@@ -57,7 +55,7 @@ class TestBaseController(unittest.TestCase):
controller.connect()
controller.close()
- @require_controller
+ @test.require.controller
def test_msg(self):
"""
Tests a basic query with the msg() method.
@@ -67,7 +65,7 @@ class TestBaseController(unittest.TestCase):
controller = stem.control.BaseController(control_socket)
test.runner.exercise_controller(self, controller)
- @require_controller
+ @test.require.controller
def test_msg_invalid(self):
"""
Tests the msg() method against an invalid controller command.
@@ -78,7 +76,7 @@ class TestBaseController(unittest.TestCase):
response = controller.msg('invalid')
self.assertEqual('Unrecognized command "invalid"', str(response))
- @require_controller
+ @test.require.controller
def test_msg_invalid_getinfo(self):
"""
Tests the msg() method against a non-existant GETINFO option.
@@ -89,7 +87,7 @@ class TestBaseController(unittest.TestCase):
response = controller.msg('GETINFO blarg')
self.assertEqual('Unrecognized key "blarg"', str(response))
- @require_controller
+ @test.require.controller
def test_msg_repeatedly(self):
"""
Connects, sends a burst of messages, and closes the socket repeatedly. This
@@ -127,7 +125,7 @@ class TestBaseController(unittest.TestCase):
for msg_thread in message_threads:
msg_thread.join()
- @require_controller
+ @test.require.controller
def test_asynchronous_event_handling(self):
"""
Check that we can both receive asynchronous events while hammering our
@@ -181,7 +179,7 @@ class TestBaseController(unittest.TestCase):
self.assertTrue(conf_changed_event.raw_content().startswith('650-CONF_CHANGED\r\n650-NodeFamily='))
self.assertEqual(('650', '-'), conf_changed_event.content()[0][:2])
- @require_controller
+ @test.require.controller
def test_get_latest_heartbeat(self):
"""
Basic check for get_latest_heartbeat().
@@ -193,7 +191,7 @@ class TestBaseController(unittest.TestCase):
controller.msg('GETINFO version')
self.assertTrue((time.time() - controller.get_latest_heartbeat()) < 5)
- @require_controller
+ @test.require.controller
def test_status_notifications(self):
"""
Checks basic functionality of the add_status_listener() and
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 2445221..32ce047 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -19,6 +19,7 @@ import stem.socket
import stem.util.str_tools
import stem.version
import test.network
+import test.require
import test.runner
from stem import Flag, Signal
@@ -26,15 +27,7 @@ from stem.control import EventType, Listener, State
from stem.exit_policy import ExitPolicy
from stem.version import Requirement
-from test.util import (
- register_new_capability,
- random_fingerprint,
- tor_version,
- only_run_once,
- require_controller,
- require_version,
- require_online,
-)
+from test.util import register_new_capability, random_fingerprint, tor_version
# Router status entry for a relay with a nickname other than 'Unnamed'. This is
# used for a few tests that need to look up a relay.
@@ -43,8 +36,8 @@ TEST_ROUTER_STATUS_ENTRY = None
class TestController(unittest.TestCase):
- @only_run_once
- @require_controller
+ @test.require.only_run_once
+ @test.require.controller
def test_missing_capabilities(self):
"""
Check to see if tor supports any events, signals, or features that we
@@ -88,8 +81,8 @@ class TestController(unittest.TestCase):
else:
self.assertRaises(stem.SocketError, stem.control.Controller.from_socket_file, test.runner.CONTROL_SOCKET_PATH)
- @require_controller
- @require_version(Requirement.EVENT_SIGNAL)
+ @test.require.controller
+ @test.require.version(Requirement.EVENT_SIGNAL)
def test_reset_notification(self):
"""
Checks that a notificiation listener is... well, notified of SIGHUPs.
@@ -125,7 +118,7 @@ class TestController(unittest.TestCase):
controller.reset_conf('__OwningControllerProcess')
- @require_controller
+ @test.require.controller
def test_event_handling(self):
"""
Add a couple listeners for various events and make sure that they receive
@@ -183,7 +176,7 @@ class TestController(unittest.TestCase):
controller.reset_conf('NodeFamily')
- @require_controller
+ @test.require.controller
def test_reattaching_listeners(self):
"""
Checks that event listeners are re-attached when a controller disconnects
@@ -224,7 +217,7 @@ class TestController(unittest.TestCase):
controller.reset_conf('NodeFamily')
- @require_controller
+ @test.require.controller
def test_getinfo(self):
"""
Exercises GETINFO with valid and invalid queries.
@@ -262,7 +255,7 @@ class TestController(unittest.TestCase):
self.assertEqual({}, controller.get_info([]))
self.assertEqual({}, controller.get_info([], {}))
- @require_controller
+ @test.require.controller
def test_get_version(self):
"""
Test that the convenient method get_version() works.
@@ -275,7 +268,7 @@ class TestController(unittest.TestCase):
self.assertTrue(isinstance(version, stem.version.Version))
self.assertEqual(version, tor_version())
- @require_controller
+ @test.require.controller
def test_get_exit_policy(self):
"""
Sanity test for get_exit_policy(). We have the default policy (no
@@ -318,7 +311,7 @@ class TestController(unittest.TestCase):
policy_str = policy_str[:public_addr_start] + policy_str[public_addr_end:]
self.assertEqual(str(expected), policy_str)
- @require_controller
+ @test.require.controller
def test_authenticate(self):
"""
Test that the convenient method authenticate() works.
@@ -330,7 +323,7 @@ class TestController(unittest.TestCase):
controller.authenticate(test.runner.CONTROL_PASSWORD)
test.runner.exercise_controller(self, controller)
- @require_controller
+ @test.require.controller
def test_protocolinfo(self):
"""
Test that the convenient method protocolinfo() works.
@@ -360,7 +353,7 @@ class TestController(unittest.TestCase):
self.assertEqual(tuple(auth_methods), protocolinfo.auth_methods)
- @require_controller
+ @test.require.controller
def test_getconf(self):
"""
Exercises GETCONF with valid and invalid queries.
@@ -423,7 +416,7 @@ class TestController(unittest.TestCase):
self.assertEqual({}, controller.get_conf_map('', 'la-di-dah'))
self.assertEqual({}, controller.get_conf_map([], 'la-di-dah'))
- @require_controller
+ @test.require.controller
def test_is_set(self):
"""
Exercises our is_set() method.
@@ -450,7 +443,7 @@ class TestController(unittest.TestCase):
controller.reset_conf('ConnLimit')
self.assertFalse(controller.is_set('ConnLimit'))
- @require_controller
+ @test.require.controller
def test_hidden_services_conf(self):
"""
Exercises the hidden service family of methods (get_hidden_service_conf,
@@ -557,8 +550,8 @@ class TestController(unittest.TestCase):
except:
pass
- @require_controller
- @require_version(Requirement.ADD_ONION)
+ @test.require.controller
+ @test.require.version(Requirement.ADD_ONION)
def test_without_ephemeral_hidden_services(self):
"""
Exercises ephemeral hidden service methods when none are present.
@@ -569,8 +562,8 @@ class TestController(unittest.TestCase):
self.assertEqual([], controller.list_ephemeral_hidden_services(detached = True))
self.assertEqual(False, controller.remove_ephemeral_hidden_service('gfzprpioee3hoppz'))
- @require_controller
- @require_version(Requirement.ADD_ONION)
+ @test.require.controller
+ @test.require.version(Requirement.ADD_ONION)
def test_with_ephemeral_hidden_services(self):
"""
Exercises creating ephemeral hidden services and methods when they're
@@ -620,8 +613,8 @@ class TestController(unittest.TestCase):
self.assertEqual(2, len(controller.list_ephemeral_hidden_services()))
self.assertEqual(0, len(second_controller.list_ephemeral_hidden_services()))
- @require_controller
- @require_version(Requirement.ADD_ONION_BASIC_AUTH)
+ @test.require.controller
+ @test.require.version(Requirement.ADD_ONION_BASIC_AUTH)
def test_with_ephemeral_hidden_services_basic_auth(self):
"""
Exercises creating ephemeral hidden services that uses basic authentication.
@@ -640,8 +633,8 @@ class TestController(unittest.TestCase):
self.assertEqual(True, controller.remove_ephemeral_hidden_service(response.service_id))
self.assertEqual([], controller.list_ephemeral_hidden_services())
- @require_controller
- @require_version(Requirement.ADD_ONION_BASIC_AUTH)
+ @test.require.controller
+ @test.require.version(Requirement.ADD_ONION_BASIC_AUTH)
def test_with_ephemeral_hidden_services_basic_auth_no_credentials(self):
"""
Exercises creating ephemeral hidden services when attempting to use basic
@@ -654,8 +647,8 @@ class TestController(unittest.TestCase):
exc_msg = "ADD_ONION response didn't have an OK status: No auth clients specified"
self.assertRaisesRegexp(stem.ProtocolError, exc_msg, controller.create_ephemeral_hidden_service, 4567, basic_auth = {})
- @require_controller
- @require_version(Requirement.ADD_ONION)
+ @test.require.controller
+ @test.require.version(Requirement.ADD_ONION)
def test_with_detached_ephemeral_hidden_services(self):
"""
Exercises creating detached ephemeral hidden services and methods when
@@ -690,7 +683,7 @@ class TestController(unittest.TestCase):
self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services(detached = True))
controller.remove_ephemeral_hidden_service(response.service_id)
- @require_controller
+ @test.require.controller
def test_set_conf(self):
"""
Exercises set_conf(), reset_conf(), and set_options() methods with valid
@@ -763,8 +756,8 @@ class TestController(unittest.TestCase):
shutil.rmtree(tmpdir)
- @require_controller
- @require_version(Requirement.LOADCONF)
+ @test.require.controller
+ @test.require.version(Requirement.LOADCONF)
def test_loadconf(self):
"""
Exercises Controller.load_conf with valid and invalid requests.
@@ -801,7 +794,7 @@ class TestController(unittest.TestCase):
controller.load_conf(oldconf)
controller.reset_conf('__OwningControllerProcess')
- @require_controller
+ @test.require.controller
def test_saveconf(self):
runner = test.runner.get_runner()
@@ -821,7 +814,7 @@ class TestController(unittest.TestCase):
controller.save_conf()
controller.reset_conf('__OwningControllerProcess')
- @require_controller
+ @test.require.controller
def test_get_ports(self):
"""
Test Controller.get_ports against a running tor instance.
@@ -842,7 +835,7 @@ class TestController(unittest.TestCase):
else:
self.assertEqual([], controller.get_ports(Listener.CONTROL))
- @require_controller
+ @test.require.controller
def test_get_listeners(self):
"""
Test Controller.get_listeners against a running tor instance.
@@ -863,7 +856,7 @@ class TestController(unittest.TestCase):
else:
self.assertEqual([], controller.get_listeners(Listener.CONTROL))
- @require_controller
+ @test.require.controller
def test_get_socks_listeners(self):
"""
Test Controller.get_socks_listeners against a running tor instance.
@@ -872,9 +865,9 @@ class TestController(unittest.TestCase):
with test.runner.get_runner().get_tor_controller() as controller:
self.assertEqual([('127.0.0.1', 1112)], controller.get_socks_listeners())
- @require_controller
- @require_online
- @require_version(stem.version.Version('0.1.2.2-alpha'))
+ @test.require.controller
+ @test.require.online
+ @test.require.version(stem.version.Version('0.1.2.2-alpha'))
def test_enable_feature(self):
"""
Test Controller.enable_feature with valid and invalid inputs.
@@ -895,7 +888,7 @@ class TestController(unittest.TestCase):
else:
self.fail()
- @require_controller
+ @test.require.controller
def test_signal(self):
"""
Test controller.signal with valid and invalid signals.
@@ -908,7 +901,7 @@ class TestController(unittest.TestCase):
# invalid signals
self.assertRaises(stem.InvalidArguments, controller.signal, 'FOOBAR')
- @require_controller
+ @test.require.controller
def test_newnym_availability(self):
"""
Test the is_newnym_available and get_newnym_wait methods.
@@ -923,9 +916,9 @@ class TestController(unittest.TestCase):
self.assertEqual(False, controller.is_newnym_available())
self.assertTrue(controller.get_newnym_wait() > 9.0)
- @require_controller
- @require_online
- @require_version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
def test_extendcircuit(self):
with test.runner.get_runner().get_tor_controller() as controller:
circuit_id = controller.extend_circuit('0')
@@ -939,9 +932,9 @@ class TestController(unittest.TestCase):
self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', 'thisroutershouldntexistbecausestemexists!@##$%#')
self.assertRaises(stem.InvalidRequest, controller.extend_circuit, '0', 'thisroutershouldntexistbecausestemexists!@##$%#', 'foo')
- @require_controller
- @require_online
- @require_version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
def test_repurpose_circuit(self):
"""
Tests Controller.repurpose_circuit with valid and invalid input.
@@ -962,9 +955,9 @@ class TestController(unittest.TestCase):
self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, 'f934h9f3h4', 'fooo')
self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, '4', 'fooo')
- @require_controller
- @require_online
- @require_version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
def test_close_circuit(self):
"""
Tests Controller.close_circuit with valid and invalid input.
@@ -989,8 +982,8 @@ class TestController(unittest.TestCase):
self.assertRaises(stem.InvalidArguments, controller.close_circuit, circuit_id + '1024')
self.assertRaises(stem.InvalidRequest, controller.close_circuit, '')
- @require_controller
- @require_online
+ @test.require.controller
+ @test.require.online
def test_get_streams(self):
"""
Tests Controller.get_streams().
@@ -1014,8 +1007,8 @@ class TestController(unittest.TestCase):
self.assertTrue('%s:%s' % (host, port) in [stream.target for stream in streams])
- @require_controller
- @require_online
+ @test.require.controller
+ @test.require.online
def test_close_stream(self):
"""
Tests Controller.close_stream with valid and invalid input.
@@ -1053,8 +1046,8 @@ class TestController(unittest.TestCase):
self.assertRaises(stem.InvalidArguments, controller.close_stream, 'blarg')
- @require_controller
- @require_online
+ @test.require.controller
+ @test.require.online
def test_mapaddress(self):
runner = test.runner.get_runner()
@@ -1091,9 +1084,9 @@ class TestController(unittest.TestCase):
ip_addr = response[response.find(b'\r\n\r\n'):].strip()
self.assertTrue(stem.util.connection.is_valid_ipv4_address(stem.util.str_tools._to_unicode(ip_addr)), "'%s' isn't an address" % ip_addr)
- @require_controller
- @require_online
- @require_version(Requirement.MICRODESCRIPTOR_IS_DEFAULT)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.MICRODESCRIPTOR_IS_DEFAULT)
def test_get_microdescriptor(self):
"""
Basic checks for get_microdescriptor().
@@ -1116,7 +1109,7 @@ class TestController(unittest.TestCase):
self.assertEqual(md_by_fingerprint, md_by_nickname)
- @require_controller
+ @test.require.controller
def test_get_microdescriptors(self):
"""
Fetches a few descriptors via the get_microdescriptors() method.
@@ -1138,7 +1131,7 @@ class TestController(unittest.TestCase):
if count > 10:
break
- @require_controller
+ @test.require.controller
def test_get_server_descriptor(self):
"""
Basic checks for get_server_descriptor().
@@ -1168,7 +1161,7 @@ class TestController(unittest.TestCase):
self.assertEqual(desc_by_fingerprint, desc_by_nickname)
- @require_controller
+ @test.require.controller
def test_get_server_descriptors(self):
"""
Fetches a few descriptors via the get_server_descriptors() method.
@@ -1195,8 +1188,8 @@ class TestController(unittest.TestCase):
if count > 10:
break
- @require_controller
- @require_online
+ @test.require.controller
+ @test.require.online
def test_get_network_status(self):
"""
Basic checks for get_network_status().
@@ -1219,8 +1212,8 @@ class TestController(unittest.TestCase):
self.assertEqual(desc_by_fingerprint, desc_by_nickname)
- @require_controller
- @require_online
+ @test.require.controller
+ @test.require.online
def test_get_network_statuses(self):
"""
Fetches a few descriptors via the get_network_statuses() method.
@@ -1242,9 +1235,9 @@ class TestController(unittest.TestCase):
if count > 10:
break
- @require_controller
- @require_online
- @require_version(Requirement.HSFETCH)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.HSFETCH)
def test_get_hidden_service_descriptor(self):
"""
Fetches a few descriptors via the get_hidden_service_descriptor() method.
@@ -1268,9 +1261,9 @@ class TestController(unittest.TestCase):
self.assertEqual('pop goes the weasel', controller.get_hidden_service_descriptor('m4cfuk6qp4lpu2g5', 'pop goes the weasel'))
self.assertEqual(None, controller.get_hidden_service_descriptor('m4cfuk6qp4lpu2g5', await_result = False))
- @require_controller
- @require_online
- @require_version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
def test_attachstream(self):
host = socket.gethostbyname('www.torproject.org')
port = 80
@@ -1309,9 +1302,9 @@ class TestController(unittest.TestCase):
self.assertEqual(our_stream.circ_id, circuit_id)
- @require_controller
- @require_online
- @require_version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
+ @test.require.controller
+ @test.require.online
+ @test.require.version(Requirement.EXTENDCIRCUIT_PATH_OPTIONAL)
def test_get_circuits(self):
"""
Fetches circuits via the get_circuits() method.
@@ -1322,7 +1315,7 @@ class TestController(unittest.TestCase):
circuits = controller.get_circuits()
self.assertTrue(new_circ in [circ.id for circ in circuits])
- @require_controller
+ @test.require.controller
def test_transition_to_relay(self):
"""
Transitions Tor to turn into a relay, then back to a client. This helps to
diff --git a/test/integ/descriptor/extrainfo_descriptor.py b/test/integ/descriptor/extrainfo_descriptor.py
index 6ea2b16..205b917 100644
--- a/test/integ/descriptor/extrainfo_descriptor.py
+++ b/test/integ/descriptor/extrainfo_descriptor.py
@@ -6,16 +6,14 @@ import os
import unittest
import stem.descriptor
+import test.require
import test.runner
-from test.util import (
- register_new_capability,
- only_run_once,
-)
+from test.util import register_new_capability
class TestExtraInfoDescriptor(unittest.TestCase):
- @only_run_once
+ @test.require.only_run_once
def test_cached_descriptor(self):
"""
Parses the cached descriptor file in our data directory, checking that it
diff --git a/test/integ/descriptor/microdescriptor.py b/test/integ/descriptor/microdescriptor.py
index 97127d6..c6fa80e 100644
--- a/test/integ/descriptor/microdescriptor.py
+++ b/test/integ/descriptor/microdescriptor.py
@@ -6,16 +6,14 @@ import os
import unittest
import stem.descriptor
+import test.require
import test.runner
-from test.util import (
- register_new_capability,
- only_run_once,
-)
+from test.util import register_new_capability
class TestMicrodescriptor(unittest.TestCase):
- @only_run_once
+ @test.require.only_run_once
def test_cached_microdescriptors(self):
"""
Parses the cached microdescriptor file in our data directory, checking that
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py
index 59dca00..96fec77 100644
--- a/test/integ/descriptor/networkstatus.py
+++ b/test/integ/descriptor/networkstatus.py
@@ -9,20 +9,16 @@ import stem
import stem.descriptor
import stem.descriptor.remote
import stem.version
+import test.require
import test.runner
-from test.util import (
- register_new_capability,
- only_run_once,
- require_cryptography,
- require_online,
-)
+from test.util import register_new_capability
class TestNetworkStatus(unittest.TestCase):
- @require_online
- @require_cryptography
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
+ @test.require.cryptography
def test_signature_validation(self):
"""
The full consensus is pretty sizable so rather than storing a copy of it
@@ -31,7 +27,7 @@ class TestNetworkStatus(unittest.TestCase):
stem.descriptor.remote.get_consensus(document_handler = stem.descriptor.DocumentHandler.DOCUMENT, validate = True).run()
- @only_run_once
+ @test.require.only_run_once
def test_cached_consensus(self):
"""
Parses the cached-consensus file in our data directory.
@@ -68,7 +64,7 @@ class TestNetworkStatus(unittest.TestCase):
self.assertTrue(count > 100)
- @only_run_once
+ @test.require.only_run_once
def test_cached_microdesc_consensus(self):
"""
Parses the cached-microdesc-consensus file in our data directory.
diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py
index b873b96..3123ef0 100644
--- a/test/integ/descriptor/remote.py
+++ b/test/integ/descriptor/remote.py
@@ -10,16 +10,12 @@ import stem.descriptor.networkstatus
import stem.descriptor.remote
import stem.descriptor.router_status_entry
import stem.descriptor.server_descriptor
-
-from test.util import (
- only_run_once,
- require_online,
-)
+import test.require
class TestDescriptorDownloader(unittest.TestCase):
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_shorthand_aliases(self):
"""
Quick sanity test that we can call our shorthand aliases for getting
@@ -35,8 +31,8 @@ class TestDescriptorDownloader(unittest.TestCase):
consensus = list(stem.descriptor.remote.get_consensus())
self.assertTrue(len(consensus) > 50)
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_authorities_are_up_to_date(self):
"""
Check that our hardcoded directory authority data matches the present
@@ -62,8 +58,8 @@ class TestDescriptorDownloader(unittest.TestCase):
if getattr(auth, attr) != getattr(stem_auth, attr):
self.fail('%s has %s %s, but we expected %s' % (auth.nickname, attr, getattr(auth, attr), getattr(stem_auth, attr)))
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_using_authorities(self):
"""
Fetches a descriptor from each of the directory authorities. This is
@@ -94,8 +90,8 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(1, len(descriptors))
self.assertEqual('moria1', descriptors[0].nickname)
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_use_directory_mirrors(self):
"""
Checks that we can fetch and use a list of directory mirrors.
@@ -105,8 +101,8 @@ class TestDescriptorDownloader(unittest.TestCase):
downloader.use_directory_mirrors()
self.assertTrue(len(downloader._endpoints) > 50)
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_get_server_descriptors(self):
"""
Exercises the downloader's get_server_descriptors() method.
@@ -138,8 +134,8 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(2, len(list(multiple_query)))
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_get_extrainfo_descriptors(self):
"""
Exercises the downloader's get_extrainfo_descriptors() method.
@@ -164,8 +160,8 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(2, len(list(multiple_query)))
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_get_consensus(self):
"""
Exercises the downloader's get_consensus() method.
@@ -180,8 +176,8 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertTrue(len(consensus) > 50)
self.assertTrue(isinstance(consensus[0], stem.descriptor.router_status_entry.RouterStatusEntryV3))
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_get_microdescriptor_consensus(self):
"""
Exercises the downloader's get_consensus() method for fetching a
@@ -197,8 +193,8 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertTrue(len(consensus) > 50)
self.assertTrue(isinstance(consensus[0], stem.descriptor.router_status_entry.RouterStatusEntryMicroV3))
- @require_online
- @only_run_once
+ @test.require.only_run_once
+ @test.require.online
def test_get_key_certificates(self):
"""
Exercises the downloader's get_key_certificates() method.
@@ -223,7 +219,7 @@ class TestDescriptorDownloader(unittest.TestCase):
self.assertEqual(2, len(list(multiple_query)))
- @require_online
+ @test.require.online
def test_that_cache_is_up_to_date(self):
"""
Check if the cached fallback directories bundled with Stem are up to date
@@ -236,7 +232,7 @@ class TestDescriptorDownloader(unittest.TestCase):
if cached_fallback_directories != latest_fallback_directories:
self.fail("Stem's cached fallback directories are out of date. Please run 'cache_fallback_directories.py'...\n\n%s" % stem.descriptor.remote._fallback_directory_differences(cached_fallback_directories, latest_fallback_directories))
- @require_online
+ @test.require.online
def test_fallback_directory_reachability(self):
"""
Fetch information from each fallback directory to confirm that it's
diff --git a/test/integ/descriptor/server_descriptor.py b/test/integ/descriptor/server_descriptor.py
index bd61e70..2a3d897 100644
--- a/test/integ/descriptor/server_descriptor.py
+++ b/test/integ/descriptor/server_descriptor.py
@@ -6,17 +6,14 @@ import os
import unittest
import stem.descriptor
-
+import test.require
import test.runner
-from test.util import (
- register_new_capability,
- only_run_once,
-)
+from test.util import register_new_capability
class TestServerDescriptor(unittest.TestCase):
- @only_run_once
+ @test.require.only_run_once
def test_cached_descriptor(self):
"""
Parses the cached descriptor file in our data directory, checking that it
diff --git a/test/integ/installation.py b/test/integ/installation.py
index 4d68988..3f37df3 100644
--- a/test/integ/installation.py
+++ b/test/integ/installation.py
@@ -12,11 +12,9 @@ import unittest
import stem
import stem.util.system
-
+import test.require
import test.util
-from test.util import only_run_once
-
INSTALL_MISMATCH_MSG = "Running 'python setup.py sdist' doesn't match our git contents in the following way. The manifest in our setup.py may need to be updated...\n\n"
BASE_INSTALL_PATH = '/tmp/stem_test'
@@ -110,7 +108,7 @@ def _assert_has_all_files(path):
class TestInstallation(unittest.TestCase):
- @only_run_once
+ @test.require.only_run_once
def test_install(self):
"""
Installs with 'python setup.py install' and checks we can use what we
@@ -126,7 +124,7 @@ class TestInstallation(unittest.TestCase):
self.assertEqual(stem.__version__, stem.util.system.call([sys.executable, '-c', "import sys;sys.path.insert(0, '%s');import stem;print(stem.__version__)" % INSTALL_PATH])[0])
_assert_has_all_files(INSTALL_PATH)
- @only_run_once
+ @test.require.only_run_once
def test_sdist(self):
"""
Creates a source distribution tarball with 'python setup.py sdist' and
diff --git a/test/integ/interpreter.py b/test/integ/interpreter.py
index 5e7c94b..42dd01a 100644
--- a/test/integ/interpreter.py
+++ b/test/integ/interpreter.py
@@ -7,12 +7,10 @@ import tempfile
import unittest
import stem.util.system
-
+import test.require
import test.runner
import test.util
-from test.util import require_controller
-
PROMPT_CMD = os.path.join(test.util.STEM_BASE, 'tor-prompt')
@@ -24,7 +22,7 @@ def _run_prompt(*args):
class TestInterpreter(unittest.TestCase):
- @require_controller
+ @test.require.controller
def test_running_command(self):
# We'd need to provide the password to stdin. Fine test to add later but
# not gonna hassle for now.
@@ -36,7 +34,7 @@ class TestInterpreter(unittest.TestCase):
expected = ['250-config-file=%s' % test.runner.get_runner().get_torrc_path(), '250 OK']
self.assertEqual(expected, _run_prompt('--run', 'GETINFO config-file'))
- @require_controller
+ @test.require.controller
def test_running_file(self):
if test.runner.Torrc.PASSWORD in test.runner.get_runner().get_options():
self.skipTest('password auth unsupported')
diff --git a/test/integ/process.py b/test/integ/process.py
index 79797ac..1ca0f70 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -20,16 +20,9 @@ import stem.util.str_tools
import stem.util.system
import stem.util.tor_tools
import stem.version
+import test.require
import test.runner
-from test.util import (
- require_command,
- require_controller,
- require_version,
-)
-
-from test.util import only_run_once
-
try:
# added in python 3.3
from unittest.mock import patch, Mock
@@ -53,7 +46,7 @@ class TestProcess(unittest.TestCase):
def tearDown(self):
shutil.rmtree(self.data_directory)
- @require_controller
+ @test.require.controller
def test_version_argument(self):
"""
Check that 'tor --version' matches 'GETINFO version'.
@@ -199,7 +192,7 @@ class TestProcess(unittest.TestCase):
self.assertTrue('UseBridges' in output)
self.assertTrue('SocksPort' in output)
- @require_command('sleep')
+ @test.require.command('sleep')
@patch('re.compile', Mock(side_effect = KeyboardInterrupt('nope')))
def test_no_orphaned_process(self):
"""
@@ -255,7 +248,7 @@ class TestProcess(unittest.TestCase):
self.assertEqual(expected, result)
- @require_version(stem.version.Requirement.TORRC_VIA_STDIN)
+ @test.require.version(stem.version.Requirement.TORRC_VIA_STDIN)
def test_torrc_arguments_via_stdin(self):
"""
Pass configuration options via stdin.
@@ -278,7 +271,7 @@ class TestProcess(unittest.TestCase):
self.assertTrue('[notice] Configuration file "/path/that/really/shouldnt/exist" not present, using reasonable defaults.' in output)
self.assertTrue('Configuration was valid' in output)
- @only_run_once
+ @test.require.only_run_once
def test_can_run_multithreaded(self):
"""
Our launch_tor() function uses signal to support its timeout argument.
@@ -321,7 +314,7 @@ class TestProcess(unittest.TestCase):
self.assertEqual(None, launch_async_with_timeout(None))
self.assertEqual(None, launch_async_with_timeout(stem.process.DEFAULT_INIT_TIMEOUT))
- @only_run_once
+ @test.require.only_run_once
@patch('stem.version.get_system_tor_version', Mock(return_value = stem.version.Version('0.0.0.1')))
def test_launch_tor_with_config_via_file(self):
"""
@@ -359,8 +352,8 @@ class TestProcess(unittest.TestCase):
tor_process.kill()
tor_process.wait()
- @only_run_once
- @require_version(stem.version.Requirement.TORRC_VIA_STDIN)
+ @test.require.only_run_once
+ @test.require.version(stem.version.Requirement.TORRC_VIA_STDIN)
def test_launch_tor_with_config_via_stdin(self):
"""
Exercises launch_tor_with_config when we provide our torrc via stdin.
@@ -394,7 +387,7 @@ class TestProcess(unittest.TestCase):
tor_process.kill()
tor_process.wait()
- @only_run_once
+ @test.require.only_run_once
def test_with_invalid_config(self):
"""
Spawn a tor process with a configuration that should make it dead on arrival.
@@ -417,7 +410,7 @@ class TestProcess(unittest.TestCase):
},
)
- @only_run_once
+ @test.require.only_run_once
def test_launch_tor_with_timeout(self):
"""
Runs launch_tor where it times out before completing.
@@ -432,9 +425,9 @@ class TestProcess(unittest.TestCase):
if not (runtime > 0.05 and runtime < 1):
self.fail('Test should have taken 0.05-1 seconds, took %0.1f instead' % runtime)
- @require_command('sleep')
- @require_version(stem.version.Requirement.TAKEOWNERSHIP)
- @only_run_once
+ @test.require.only_run_once
+ @test.require.command('sleep')
+ @test.require.version(stem.version.Requirement.TAKEOWNERSHIP)
@patch('os.getpid')
def test_take_ownership_via_pid(self, getpid_mock):
"""
@@ -476,8 +469,8 @@ class TestProcess(unittest.TestCase):
self.fail("tor didn't quit after the process that owned it terminated")
- @require_version(stem.version.Requirement.TAKEOWNERSHIP)
- @only_run_once
+ @test.require.only_run_once
+ @test.require.version(stem.version.Requirement.TAKEOWNERSHIP)
def test_take_ownership_via_controller(self):
"""
Checks that the tor process quits after the controller that owns it
diff --git a/test/integ/response/protocolinfo.py b/test/integ/response/protocolinfo.py
index 8563cf0..1a00671 100644
--- a/test/integ/response/protocolinfo.py
+++ b/test/integ/response/protocolinfo.py
@@ -9,10 +9,11 @@ import stem.connection
import stem.socket
import stem.util.system
import stem.version
+import test.require
import test.runner
from test.integ.util.system import filter_system_call
-from test.util import require_controller, tor_version
+from test.util import tor_version
try:
# added in python 3.3
@@ -22,7 +23,7 @@ except ImportError:
class TestProtocolInfo(unittest.TestCase):
- @require_controller
+ @test.require.controller
def test_parsing(self):
"""
Makes a PROTOCOLINFO query and processes the response for our control
@@ -44,7 +45,7 @@ class TestProtocolInfo(unittest.TestCase):
self.assert_matches_test_config(protocolinfo_response)
- @require_controller
+ @test.require.controller
@patch('stem.util.proc.is_available', Mock(return_value = False))
@patch('stem.util.system.is_available', Mock(return_value = True))
def test_get_protocolinfo_path_expansion(self):
@@ -87,7 +88,7 @@ class TestProtocolInfo(unittest.TestCase):
self.assertTrue(control_socket.is_alive())
control_socket.close()
- @require_controller
+ @test.require.controller
def test_multiple_protocolinfo_calls(self):
"""
Tests making repeated PROTOCOLINFO queries. This use case is interesting
@@ -100,7 +101,7 @@ class TestProtocolInfo(unittest.TestCase):
protocolinfo_response = stem.connection.get_protocolinfo(control_socket)
self.assert_matches_test_config(protocolinfo_response)
- @require_controller
+ @test.require.controller
def test_pre_disconnected_query(self):
"""
Tests making a PROTOCOLINFO query when previous use of the socket had
diff --git a/test/integ/socket/control_message.py b/test/integ/socket/control_message.py
index 646f732..6d16f48 100644
--- a/test/integ/socket/control_message.py
+++ b/test/integ/socket/control_message.py
@@ -7,17 +7,14 @@ import unittest
import stem.socket
import stem.version
+import test.require
import test.runner
-from test.util import (
- require_controller,
- require_version,
- random_fingerprint,
-)
+from test.util import random_fingerprint
class TestControlMessage(unittest.TestCase):
- @require_controller
+ @test.require.controller
def test_unestablished_socket(self):
"""
Checks message parsing when we have a valid but unauthenticated socket.
@@ -58,7 +55,7 @@ class TestControlMessage(unittest.TestCase):
self.assertRaises(stem.SocketClosed, control_socket.send, 'GETINFO version')
self.assertRaises(stem.SocketClosed, control_socket.recv)
- @require_controller
+ @test.require.controller
def test_invalid_command(self):
"""
Parses the response for a command which doesn't exist.
@@ -72,7 +69,7 @@ class TestControlMessage(unittest.TestCase):
self.assertEqual('510 Unrecognized command "blarg"\r\n', unrecognized_command_response.raw_content())
self.assertEqual([('510', ' ', 'Unrecognized command "blarg"')], unrecognized_command_response.content())
- @require_controller
+ @test.require.controller
def test_invalid_getinfo(self):
"""
Parses the response for a GETINFO query which doesn't exist.
@@ -86,7 +83,7 @@ class TestControlMessage(unittest.TestCase):
self.assertEqual('552 Unrecognized key "blarg"\r\n', unrecognized_key_response.raw_content())
self.assertEqual([('552', ' ', 'Unrecognized key "blarg"')], unrecognized_key_response.content())
- @require_controller
+ @test.require.controller
def test_getinfo_config_file(self):
"""
Parses the 'GETINFO config-file' response.
@@ -103,8 +100,8 @@ class TestControlMessage(unittest.TestCase):
self.assertEqual('250-config-file=%s\r\n250 OK\r\n' % torrc_dst, config_file_response.raw_content())
self.assertEqual([('250', '-', 'config-file=%s' % torrc_dst), ('250', ' ', 'OK')], config_file_response.content())
- @require_controller
- @require_version(stem.version.Requirement.GETINFO_CONFIG_TEXT)
+ @test.require.controller
+ @test.require.version(stem.version.Requirement.GETINFO_CONFIG_TEXT)
def test_getinfo_config_text(self):
"""
Parses the 'GETINFO config-text' response.
@@ -145,7 +142,7 @@ class TestControlMessage(unittest.TestCase):
self.assertTrue('%s\r\n' % torrc_entry in config_text_response.raw_content())
self.assertTrue('%s' % torrc_entry in config_text_response.content()[0][2])
- @require_controller
+ @test.require.controller
def test_setconf_event(self):
"""
Issues 'SETEVENTS CONF_CHANGED' and parses an events.
diff --git a/test/integ/socket/control_socket.py b/test/integ/socket/control_socket.py
index a4da321..8e2658a 100644
--- a/test/integ/socket/control_socket.py
+++ b/test/integ/socket/control_socket.py
@@ -14,13 +14,14 @@ import unittest
import stem.connection
import stem.control
import stem.socket
+import test.require
import test.runner
-from test.util import require_controller, tor_version
+from test.util import tor_version
class TestControlSocket(unittest.TestCase):
- @require_controller
+ @test.require.controller
def test_connection_time(self):
"""
Checks that our connection_time method tracks when our state's changed.
@@ -54,7 +55,7 @@ class TestControlSocket(unittest.TestCase):
reconnection_time = control_socket.connection_time()
self.assertTrue(disconnection_time < reconnection_time <= time.time())
- @require_controller
+ @test.require.controller
def test_send_buffered(self):
"""
Sends multiple requests before receiving back any of the replies.
@@ -71,7 +72,7 @@ class TestControlSocket(unittest.TestCase):
self.assertTrue(str(response).startswith('version=%s' % tor_version()))
self.assertTrue(str(response).endswith('\nOK'))
- @require_controller
+ @test.require.controller
def test_send_closed(self):
"""
Sends a message after we've closed the connection.
@@ -84,7 +85,7 @@ class TestControlSocket(unittest.TestCase):
self.assertRaises(stem.SocketClosed, control_socket.send, 'blarg')
- @require_controller
+ @test.require.controller
def test_send_disconnected(self):
"""
Sends a message to a socket that has been disconnected by the other end.
@@ -110,7 +111,7 @@ class TestControlSocket(unittest.TestCase):
self.assertRaises(stem.SocketClosed, control_socket.send, 'blarg')
self.assertFalse(control_socket.is_alive())
- @require_controller
+ @test.require.controller
def test_recv_closed(self):
"""
Receives a message after we've closed the connection.
@@ -123,7 +124,7 @@ class TestControlSocket(unittest.TestCase):
self.assertRaises(stem.SocketClosed, control_socket.recv)
- @require_controller
+ @test.require.controller
def test_recv_disconnected(self):
"""
Receives a message from a socket that has been disconnected by the other
@@ -142,7 +143,7 @@ class TestControlSocket(unittest.TestCase):
self.assertRaises(stem.SocketClosed, control_socket.recv)
self.assertFalse(control_socket.is_alive())
- @require_controller
+ @test.require.controller
def test_connect_repeatedly(self):
"""
Checks that we can reconnect, use, and disconnect a socket repeatedly.
diff --git a/test/integ/util/connection.py b/test/integ/util/connection.py
index f641a37..1fc08c4 100644
--- a/test/integ/util/connection.py
+++ b/test/integ/util/connection.py
@@ -5,14 +5,14 @@ that we're running.
import unittest
+import test.require
import test.runner
from stem.util.connection import Resolver, get_connections, system_resolvers
-from test.util import require_ptrace
class TestConnection(unittest.TestCase):
- @require_ptrace
+ @test.require.ptrace
def check_resolver(self, resolver):
runner = test.runner.get_runner()
diff --git a/test/integ/util/proc.py b/test/integ/util/proc.py
index ef3a7c0..da4d6ef 100644
--- a/test/integ/util/proc.py
+++ b/test/integ/util/proc.py
@@ -6,19 +6,15 @@ we're running.
import os
import unittest
+import test.require
import test.runner
from stem.util import proc
-from test.util import (
- require_proc,
- require_ptrace,
-)
-
class TestProc(unittest.TestCase):
- @require_proc
- @require_ptrace
+ @test.require.proc
+ @test.require.ptrace
def test_cwd(self):
"""
Checks that stem.util.proc.cwd matches our tor instance's cwd.
@@ -28,7 +24,7 @@ class TestProc(unittest.TestCase):
runner_pid, tor_cwd = runner.get_pid(), runner.get_tor_cwd()
self.assertEqual(tor_cwd, proc.cwd(runner_pid))
- @require_proc
+ @test.require.proc
def test_uid(self):
"""
Checks that stem.util.proc.uid matches our tor instance's uid.
@@ -37,7 +33,7 @@ class TestProc(unittest.TestCase):
tor_pid = test.runner.get_runner().get_pid()
self.assertEqual(os.geteuid(), proc.uid(tor_pid))
- @require_proc
+ @test.require.proc
def test_memory_usage(self):
"""
Checks that stem.util.proc.memory_usage looks somewhat reasonable.
@@ -50,7 +46,7 @@ class TestProc(unittest.TestCase):
self.assertTrue(res_size > 1024)
self.assertTrue(vir_size > 1024)
- @require_proc
+ @test.require.proc
def test_stats(self):
"""
Checks that stem.util.proc.stats looks somewhat reasonable.
@@ -65,8 +61,8 @@ class TestProc(unittest.TestCase):
self.assertTrue(float(stime) >= 0)
self.assertTrue(float(start_time) > proc.system_start_time())
- @require_proc
- @require_ptrace
+ @test.require.proc
+ @test.require.ptrace
def test_connections(self):
"""
Checks for our control port in the stem.util.proc.connections output if
diff --git a/test/integ/util/system.py b/test/integ/util/system.py
index 88a5529..912251b 100644
--- a/test/integ/util/system.py
+++ b/test/integ/util/system.py
@@ -10,15 +10,9 @@ import unittest
import stem.util.proc
import stem.util.system
+import test.require
import test.runner
-from test.util import (
- require,
- require_command,
- require_proc,
- require_ptrace,
-)
-
try:
# added in python 3.3
from unittest.mock import Mock, patch
@@ -68,10 +62,10 @@ def _has_port():
return test.runner.Torrc.PORT in test.runner.get_runner().get_options()
-require_single_tor_instance = require(_is_single_tor_running, 'multiple tor instances')
-require_control_port = require(_has_port, 'test instance has no port')
-require_linux = require(_is_linux, 'linux only')
-require_bsd = require(stem.util.system.is_bsd, 'bsd only')
+require_single_tor_instance = test.require.needs(_is_single_tor_running, 'multiple tor instances')
+require_control_port = test.require.needs(_has_port, 'test instance has no port')
+require_linux = test.require.needs(_is_linux, 'linux only')
+require_bsd = test.require.needs(stem.util.system.is_bsd, 'bsd only')
class TestSystem(unittest.TestCase):
@@ -91,7 +85,7 @@ class TestSystem(unittest.TestCase):
self.assertFalse(stem.util.system.is_available('blarg_and_stuff'))
- @require_command('ps')
+ @test.require.command('ps')
def test_is_running(self):
"""
Checks the stem.util.system.is_running function.
@@ -117,8 +111,8 @@ class TestSystem(unittest.TestCase):
self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
self.assertEqual(None, stem.util.system.pid_by_name('blarg_and_stuff'))
- @require_command('pgrep')
@require_single_tor_instance
+ @test.require.command('pgrep')
def test_pid_by_name_pgrep(self):
"""
Tests the pid_by_name function with a pgrep response.
@@ -134,8 +128,8 @@ class TestSystem(unittest.TestCase):
tor_cmd = test.runner.get_runner().get_tor_command(True)
self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
- @require_command('pidof')
@require_single_tor_instance
+ @test.require.command('pidof')
def test_pid_by_name_pidof(self):
"""
Tests the pid_by_name function with a pidof response.
@@ -152,8 +146,8 @@ class TestSystem(unittest.TestCase):
self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
@require_linux
- @require_command('ps')
@require_single_tor_instance
+ @test.require.command('ps')
def test_pid_by_name_ps_linux(self):
"""
Tests the pid_by_name function with the linux variant of ps.
@@ -170,8 +164,8 @@ class TestSystem(unittest.TestCase):
self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
@require_bsd
- @require_command('ps')
@require_single_tor_instance
+ @test.require.command('ps')
def test_pid_by_name_ps_bsd(self):
"""
Tests the pid_by_name function with the bsd variant of ps.
@@ -187,9 +181,9 @@ class TestSystem(unittest.TestCase):
tor_cmd = test.runner.get_runner().get_tor_command(True)
self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
- @require_ptrace
- @require_command('lsof')
@require_single_tor_instance
+ @test.require.ptrace
+ @test.require.command('lsof')
def test_pid_by_name_lsof(self):
"""
Tests the pid_by_name function with a lsof response.
@@ -208,8 +202,8 @@ class TestSystem(unittest.TestCase):
if len(all_tor_pids) == 1:
self.assertEqual(our_tor_pid, all_tor_pids[0])
- @require_command('tasklist')
@require_single_tor_instance
+ @test.require.command('tasklist')
def test_pid_by_name_tasklist(self):
"""
Tests the pid_by_name function with a tasklist response.
@@ -218,8 +212,8 @@ class TestSystem(unittest.TestCase):
runner = test.runner.get_runner()
self.assertEqual(runner.get_pid(), stem.util.system.pid_by_name(runner.get_tor_command(True)))
- @require_ptrace
@require_control_port
+ @test.require.ptrace
def test_pid_by_port(self):
"""
Checks general usage of the stem.util.system.pid_by_port function.
@@ -243,9 +237,9 @@ class TestSystem(unittest.TestCase):
self.assertEqual(None, stem.util.system.pid_by_port(99999))
@require_linux
- @require_ptrace
@require_control_port
- @require_command('netstat')
+ @test.require.ptrace
+ @test.require.command('netstat')
def test_pid_by_port_netstat(self):
"""
Tests the pid_by_port function with a netstat response.
@@ -266,9 +260,9 @@ class TestSystem(unittest.TestCase):
self.assertEqual(tor_pid, stem.util.system.pid_by_port(test.runner.CONTROL_PORT))
@require_bsd
- @require_ptrace
@require_control_port
- @require_command('sockstat')
+ @test.require.ptrace
+ @test.require.command('sockstat')
def test_pid_by_port_sockstat(self):
"""
Tests the pid_by_port function with a sockstat response.
@@ -283,9 +277,9 @@ class TestSystem(unittest.TestCase):
tor_pid = test.runner.get_runner().get_pid()
self.assertEqual(tor_pid, stem.util.system.pid_by_port(test.runner.CONTROL_PORT))
- @require_ptrace
@require_control_port
- @require_command('lsof')
+ @test.require.ptrace
+ @test.require.command('lsof')
def test_pid_by_port_lsof(self):
"""
Tests the pid_by_port function with a lsof response.
@@ -328,7 +322,7 @@ class TestSystem(unittest.TestCase):
pids = stem.util.system.pids_by_user(getpass.getuser())
self.assertTrue(os.getpid() in pids)
- @require_ptrace
+ @test.require.ptrace
def test_cwd(self):
"""
Checks general usage of the stem.util.system.cwd function.
@@ -343,8 +337,8 @@ class TestSystem(unittest.TestCase):
self.assertEqual(tor_cwd, stem.util.system.cwd(runner_pid))
self.assertEqual(None, stem.util.system.cwd(99999))
- @require_ptrace
- @require_command('pwdx')
+ @test.require.ptrace
+ @test.require.command('pwdx')
def test_cwd_pwdx(self):
"""
Tests the pid_by_cwd function with a pwdx response.
@@ -363,8 +357,8 @@ class TestSystem(unittest.TestCase):
runner_pid, tor_cwd = runner.get_pid(), runner.get_tor_cwd()
self.assertEqual(tor_cwd, stem.util.system.cwd(runner_pid))
- @require_ptrace
- @require_command('lsof')
+ @test.require.ptrace
+ @test.require.command('lsof')
def test_cwd_lsof(self):
"""
Tests the pid_by_cwd function with a lsof response.
@@ -392,7 +386,7 @@ class TestSystem(unittest.TestCase):
self.assertEqual(None, stem.util.system.user(-5))
self.assertEqual(None, stem.util.system.start_time(98765))
- @require_proc
+ @test.require.proc
def test_user_proc(self):
"""
Tests the user function with a proc response.
@@ -408,7 +402,7 @@ class TestSystem(unittest.TestCase):
pid = test.runner.get_runner().get_pid()
self.assertTrue(getpass.getuser(), stem.util.system.user(pid))
- @require_command('ps')
+ @test.require.command('ps')
@patch('stem.util.proc.is_available', Mock(return_value = False))
def test_user_ps(self):
"""
@@ -427,7 +421,7 @@ class TestSystem(unittest.TestCase):
self.assertEqual(None, stem.util.system.start_time(-5))
self.assertEqual(None, stem.util.system.start_time(98765))
- @require_proc
+ @test.require.proc
def test_start_time_proc(self):
"""
Tests the start_time function with a proc response.
@@ -441,7 +435,7 @@ class TestSystem(unittest.TestCase):
pid = test.runner.get_runner().get_pid()
self.assertTrue(stem.util.system.start_time(pid) >= 0)
- @require_command('ps')
+ @test.require.command('ps')
@patch('stem.util.proc.is_available', Mock(return_value = False))
def test_start_time_ps(self):
"""
diff --git a/test/integ/version.py b/test/integ/version.py
index 3cef9b2..b28ee86 100644
--- a/test/integ/version.py
+++ b/test/integ/version.py
@@ -7,16 +7,12 @@ import unittest
import stem.prereq
import stem.version
+import test.require
import test.runner
-from test.util import (
- require_command,
- require_controller,
-)
-
class TestVersion(unittest.TestCase):
- @require_command('tor')
+ @test.require.command('tor')
def test_get_system_tor_version(self):
"""
Basic verification checks for the get_system_tor_version() function.
@@ -34,7 +30,7 @@ class TestVersion(unittest.TestCase):
# try running against a command that doesn't exist
self.assertRaises(IOError, stem.version.get_system_tor_version, 'blarg')
- @require_controller
+ @test.require.controller
def test_getinfo_version_parsing(self):
"""
Issues a 'GETINFO version' query to our test instance and makes sure that
diff --git a/test/require.py b/test/require.py
new file mode 100644
index 0000000..a0735d8
--- /dev/null
+++ b/test/require.py
@@ -0,0 +1,106 @@
+# Copyright 2012-2017, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
+"""
+Testing requirements. This provides annotations to skip tests that shouldn't be
+run.
+
+::
+
+ Test Requirements
+ |- only_run_once - skip test if it has been ran before
+ |- needs - skips the test unless a requirement is met
+ |
+ |- cryptography - skips test unless the cryptography module is present
+ |- pynacl - skips test unless the pynacl module is present
+ |- command - requires a command to be on the path
+ |- proc - requires the platform to have recognized /proc contents
+ |
+ |- controller - skips test unless tor provides a controller endpoint
+ |- version - skips test unless we meet a tor version requirement
+ |- ptrace - requires 'DisableDebuggerAttachment' to be set
+ +- online - skips unless targets allow for online tests
+"""
+
+import stem.util.system
+import stem.version
+import test.runner
+import test.util
+
+RAN_TESTS = []
+
+
+def only_run_once(func):
+ """
+ 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``.
+ """
+
+ def wrapped(self, *args, **kwargs):
+ if self.id() not in RAN_TESTS:
+ RAN_TESTS.append(self.id())
+ return func(self, *args, **kwargs)
+ else:
+ self.skipTest('(already ran)')
+
+ return wrapped
+
+
+def needs(condition, message):
+ """
+ Skips teh test unless the conditional evaluates to 'true'.
+ """
+
+ def decorator(func):
+ def wrapped(self, *args, **kwargs):
+ if condition():
+ return func(self, *args, **kwargs)
+ else:
+ self.skipTest('(%s)' % message)
+
+ return wrapped
+
+ return decorator
+
+
+def _can_access_controller():
+ return test.runner.get_runner().is_accessible()
+
+
+def _can_ptrace():
+ # If we're running a tor version where ptrace is disabled and we didn't
+ # set 'DisableDebuggerAttachment=1' then we can infer that it's disabled.
+
+ has_option = test.util.tor_version() >= stem.version.Requirement.TORRC_DISABLE_DEBUGGER_ATTACHMENT
+ return not has_option or test.runner.Torrc.PTRACE in test.runner.get_runner().get_options()
+
+
+def _is_online():
+ return test.util.Target.ONLINE in test.runner.get_runner().attribute_targets
+
+
+def command(cmd):
+ """
+ Skips the test unless a command is available on the path.
+ """
+
+ return needs(lambda: stem.util.system.is_available(cmd), '%s unavailable' % cmd)
+
+
+def version(req_version):
+ """
+ Skips the test unless we meet the required version.
+
+ :param stem.version.Version req_version: required tor version for the test
+ """
+
+ return needs(lambda: test.util.tor_version() >= req_version, 'requires %s' % req_version)
+
+
+cryptography = needs(stem.prereq.is_crypto_available, 'requires cryptography')
+pynacl = needs(stem.prereq._is_pynacl_available, 'requires pynacl module')
+proc = needs(stem.util.proc.is_available, 'proc unavailable')
+controller = needs(_can_access_controller, 'no connection')
+ptrace = needs(_can_ptrace, 'DisableDebuggerAttachment is set')
+online = needs(_is_online, 'requires online target')
diff --git a/test/unit/descriptor/certificate.py b/test/unit/descriptor/certificate.py
index 0cef45a..19d7c64 100644
--- a/test/unit/descriptor/certificate.py
+++ b/test/unit/descriptor/certificate.py
@@ -10,10 +10,10 @@ import unittest
import stem.descriptor.certificate
import stem.util.str_tools
import stem.prereq
+import test.require
from stem.descriptor.certificate import ED25519_SIGNATURE_LENGTH, CertType, ExtensionType, ExtensionFlag, Ed25519Certificate, Ed25519CertificateV1, Ed25519Extension
from test.unit.descriptor import get_resource
-from test.util import require_pynacl
ED25519_CERT = """
AQQABhtZAaW2GoBED1IjY3A6f6GNqBEl5A83fD2Za9upGke51JGqAQAgBABnprVR
@@ -147,7 +147,7 @@ class TestEd25519Certificate(unittest.TestCase):
self.assert_raises(certificate(extension_data = [b'\x00\x02\x04\x07\11\12']), "Ed25519 HAS_SIGNING_KEY extension must be 32 bytes, but was 2.")
- @require_pynacl
+ @test.require.pynacl
def test_validation_with_descriptor_key(self):
"""
Validate a descriptor signature using the ed25519 master key within the
@@ -159,7 +159,7 @@ class TestEd25519Certificate(unittest.TestCase):
desc.certificate.validate(desc)
- @require_pynacl
+ @test.require.pynacl
def test_validation_with_embedded_key(self):
"""
Validate a descriptor signature using the signing key within the ed25519
@@ -172,7 +172,7 @@ class TestEd25519Certificate(unittest.TestCase):
desc.ed25519_master_key = None
desc.certificate.validate(desc)
- @require_pynacl
+ @test.require.pynacl
def test_validation_with_invalid_descriptor(self):
"""
Validate a descriptor without a valid signature.
diff --git a/test/unit/descriptor/hidden_service_descriptor.py b/test/unit/descriptor/hidden_service_descriptor.py
index 48f1d29..2f8427f 100644
--- a/test/unit/descriptor/hidden_service_descriptor.py
+++ b/test/unit/descriptor/hidden_service_descriptor.py
@@ -8,8 +8,7 @@ import unittest
import stem.descriptor
import stem.prereq
-
-from test.util import require_cryptography
+import test.require
from stem.descriptor.hidden_service_descriptor import (
REQUIRED_FIELDS,
@@ -274,7 +273,7 @@ class TestHiddenServiceDescriptor(unittest.TestCase):
self.assertEqual(datetime.datetime(2014, 10, 31, 23, 0, 0), desc.published)
self.assertEqual([2, 3], desc.protocol_versions)
- @require_cryptography
+ @test.require.cryptography
def test_with_basic_auth(self):
"""
Parse a descriptor with introduction-points encrypted with basic auth.
@@ -321,7 +320,7 @@ class TestHiddenServiceDescriptor(unittest.TestCase):
self.assertTrue('MIGJAoGBAM7B/cymp' in point.service_key)
self.assertEqual([], point.intro_authentication)
- @require_cryptography
+ @test.require.cryptography
def test_with_stealth_auth(self):
"""
Parse a descriptor with introduction-points encrypted with stealth auth.
diff --git a/test/unit/manual.py b/test/unit/manual.py
index 6bfcbe7..28a8a8b 100644
--- a/test/unit/manual.py
+++ b/test/unit/manual.py
@@ -11,8 +11,7 @@ import unittest
import stem.prereq
import stem.manual
import stem.util.system
-
-from test.util import require_command
+import test.require
try:
# account for urllib's change between python 2.x and 3.x
@@ -138,7 +137,7 @@ class TestManual(unittest.TestCase):
self.assertEqual('', blank.summary)
self.assertEqual('', blank.description)
- @require_command('man')
+ @test.require.command('man')
def test_parsing_with_example(self):
"""
Read a trimmed copy of tor's man page. This gives a good exercise of our
@@ -160,7 +159,7 @@ class TestManual(unittest.TestCase):
self.assertEqual(EXPECTED_FILES, manual.files)
self.assertEqual(EXPECTED_CONFIG_OPTIONS, manual.config_options)
- @require_command('man')
+ @test.require.command('man')
def test_parsing_with_unknown_options(self):
"""
Check that we can read a local mock man page that contains unrecognized
@@ -189,7 +188,7 @@ class TestManual(unittest.TestCase):
self.assertEqual('', option.summary)
self.assertEqual('Description of this new option.', option.description)
- @require_command('man')
+ @test.require.command('man')
def test_saving_manual(self):
"""
Check that we can save and reload manuals.
diff --git a/test/util.py b/test/util.py
index e8af8e1..47d90fd 100644
--- a/test/util.py
+++ b/test/util.py
@@ -12,24 +12,6 @@ Helper functions for our test framework.
get_prereq - provides the tor version required to run the given target
get_torrc_entries - provides the torrc entries for a given target
-This module also provides generally useful test helpers...
-
-::
-
- Test Requirements
- |- only_run_once - skip test if it has been ran before
- |- require - skips the test unless a requirement is met
- |
- |- require_cryptography - skips test unless the cryptography module is present
- |- require_pynacl - skips test unless the pynacl module is present
- |- require_command - requires a command to be on the path
- |- require_proc - requires the platform to have recognized /proc contents
- |
- |- require_controller - skips test unless tor provides a controller endpoint
- |- require_version - skips test unless we meet a tor version requirement
- |- require_ptrace - requires 'DisableDebuggerAttachment' to be set
- +- require_online - skips unless targets allow for online tests
-
get_message - provides a ControlMessage instance
get_protocolinfo_response - provides a ProtocolInfoResponse instance
get_all_combinations - provides all combinations of attributes
@@ -43,14 +25,10 @@ import re
import os
import stem
-import stem.prereq
import stem.util.conf
-import stem.util.system
-import stem.util.test_tools
+import stem.util.enum
import stem.version
-import test.output
-
CONFIG = stem.util.conf.config_dict('test', {
'target.prereq': {},
'target.torrc': {},
@@ -83,7 +61,6 @@ Target = stem.util.enum.UppercaseEnum(
'RUN_ALL',
)
-RAN_TESTS = []
TOR_VERSION = None
# We make some paths relative to stem's base directory (the one above us)
@@ -211,82 +188,6 @@ def get_new_capabilities():
return NEW_CAPABILITIES
-def only_run_once(func):
- """
- 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``.
- """
-
- def wrapped(self, *args, **kwargs):
- if self.id() not in RAN_TESTS:
- RAN_TESTS.append(self.id())
- return func(self, *args, **kwargs)
- else:
- self.skipTest('(already ran)')
-
- return wrapped
-
-
-def require(condition, message):
- """
- Skips teh test unless the conditional evaluates to 'true'.
- """
-
- def decorator(func):
- def wrapped(self, *args, **kwargs):
- if condition():
- return func(self, *args, **kwargs)
- else:
- self.skipTest('(%s)' % message)
-
- return wrapped
-
- return decorator
-
-
-def _can_access_controller():
- return test.runner.get_runner().is_accessible()
-
-
-def _can_ptrace():
- # If we're running a tor version where ptrace is disabled and we didn't
- # set 'DisableDebuggerAttachment=1' then we can infer that it's disabled.
-
- has_option = tor_version() >= stem.version.Requirement.TORRC_DISABLE_DEBUGGER_ATTACHMENT
- return not has_option or test.runner.Torrc.PTRACE in test.runner.get_runner().get_options()
-
-
-def _is_online():
- return Target.ONLINE in test.runner.get_runner().attribute_targets
-
-
-require_cryptography = require(stem.prereq.is_crypto_available, 'requires cryptography')
-require_pynacl = require(stem.prereq._is_pynacl_available, 'requires pynacl module')
-require_proc = require(stem.util.proc.is_available, 'proc unavailable')
-require_controller = require(_can_access_controller, 'no connection')
-require_ptrace = require(_can_ptrace, 'DisableDebuggerAttachment is set')
-require_online = require(_is_online, 'requires online target')
-
-
-def require_command(cmd):
- """
- Skips the test unless a command is available on the path.
- """
-
- return require(lambda: stem.util.system.is_available(cmd), '%s unavailable' % cmd)
-
-
-def require_version(req_version):
- """
- Skips the test unless we meet the required version.
-
- :param stem.version.Version req_version: required tor version for the test
- """
-
- return require(lambda: tor_version() >= req_version, 'requires %s' % req_version)
-
-
def register_new_capability(capability_type, msg, suppression_token = None):
"""
Register new capability found during the tests.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits