[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Parallelize descriptor cache tests
commit 34eaf109d6610e7fbc887c06df1a20367207c81d
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Mon Jun 5 14:37:42 2017 -0700
Parallelize descriptor cache tests
We have a handful of lengthy tests that read descriptors from our data
directory. Running these in the background.
---
run_tests.py | 19 ++++++++++++++
stem/util/test_tools.py | 17 +++++++------
test/integ/descriptor/extrainfo_descriptor.py | 25 +++++++++++--------
test/integ/descriptor/microdescriptor.py | 16 ++++++------
test/integ/descriptor/networkstatus.py | 36 +++++++++++++++------------
test/integ/descriptor/server_descriptor.py | 23 +++++++++--------
test/integ/installation.py | 2 +-
test/integ/process.py | 8 +++---
test/settings.cfg | 10 ++++----
9 files changed, 94 insertions(+), 62 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 961600c..0a162eb 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -28,6 +28,10 @@ import stem.version
import test
import test.arguments
+import test.integ.descriptor.extrainfo_descriptor
+import test.integ.descriptor.microdescriptor
+import test.integ.descriptor.networkstatus
+import test.integ.descriptor.server_descriptor
import test.integ.installation
import test.integ.process
import test.output
@@ -37,6 +41,7 @@ import test.task
from test.output import STATUS, SUCCESS, ERROR, NO_NL, STDERR, println
CONFIG = stem.util.conf.config_dict('test', {
+ 'integ.test_directory': './test/data',
'test.unit_tests': '',
'test.integ_tests': '',
'target.prereq': {},
@@ -234,6 +239,20 @@ def main():
skipped_tests = 0
if args.run_integ:
+ default_test_dir = stem.util.system.expand_path(CONFIG['integ.test_directory'], test.STEM_BASE)
+
+ if not args.specific_test or 'test.integ.descriptor.extrainfo_descriptor'.startswith(args.specific_test):
+ test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor.run_tests(default_test_dir)
+
+ if not args.specific_test or 'test.integ.descriptor.microdescriptor'.startswith(args.specific_test):
+ test.integ.descriptor.microdescriptor.TestMicrodescriptor.run_tests(default_test_dir)
+
+ if not args.specific_test or 'test.integ.descriptor.networkstatus'.startswith(args.specific_test):
+ test.integ.descriptor.networkstatus.TestNetworkStatus.run_tests(default_test_dir)
+
+ if not args.specific_test or 'test.integ.descriptor.server_descriptor'.startswith(args.specific_test):
+ test.integ.descriptor.server_descriptor.TestServerDescriptor.run_tests(default_test_dir)
+
if not args.specific_test or 'test.integ.installation'.startswith(args.specific_test):
test.integ.installation.TestInstallation.run_tests()
diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py
index 5a5813f..0d167d0 100644
--- a/stem/util/test_tools.py
+++ b/stem/util/test_tools.py
@@ -80,10 +80,10 @@ class AsyncTest(object):
.. versionadded:: 1.6.0
"""
- def __init__(self, test_runner, *test_runner_args):
- def _wrapper(conn, runner, args):
+ def __init__(self, test_runner, args = None, threaded = False):
+ def _wrapper(conn, runner, test_args):
try:
- runner(*args) if args else runner()
+ runner(*test_args) if test_args else runner()
conn.send(('success', None))
except AssertionError as exc:
conn.send(('failure', str(exc)))
@@ -92,14 +92,17 @@ class AsyncTest(object):
finally:
conn.close()
- # method that can be mixed into TestCases
-
- self.method = lambda test: self.result(test)
+ self.method = lambda test: self.result(test) # method that can be mixed into TestCases
self._result_type, self._result_msg = None, None
self._result_lock = threading.RLock()
self._results_pipe, child_pipe = multiprocessing.Pipe()
- self._test_process = multiprocessing.Process(target = _wrapper, args = (child_pipe, test_runner, test_runner_args))
+
+ if threaded:
+ self._test_process = threading.Thread(target = _wrapper, args = (child_pipe, test_runner, args))
+ else:
+ self._test_process = multiprocessing.Process(target = _wrapper, args = (child_pipe, test_runner, args))
+
self._test_process.start()
def pid(self):
diff --git a/test/integ/descriptor/extrainfo_descriptor.py b/test/integ/descriptor/extrainfo_descriptor.py
index eada1d7..e2350ce 100644
--- a/test/integ/descriptor/extrainfo_descriptor.py
+++ b/test/integ/descriptor/extrainfo_descriptor.py
@@ -6,25 +6,28 @@ import os
import unittest
import stem.descriptor
+import stem.util.test_tools
import test
import test.require
-import test.runner
class TestExtraInfoDescriptor(unittest.TestCase):
- @test.require.only_run_once
- def test_cached_descriptor(self):
+ @staticmethod
+ def run_tests(test_dir):
+ TestExtraInfoDescriptor.test_cached_descriptor = stem.util.test_tools.AsyncTest(TestExtraInfoDescriptor.test_cached_descriptor, args = (test_dir,), threaded = True).method
+
+ @staticmethod
+ def test_cached_descriptor(test_dir):
"""
Parses the cached descriptor file in our data directory, checking that it
doesn't raise any validation issues and looking for unrecognized descriptor
additions.
"""
- descriptor_path = test.runner.get_runner().get_test_dir('cached-extrainfo')
+ descriptor_path = os.path.join(test_dir, 'cached-extrainfo')
if not os.path.exists(descriptor_path):
- self.skipTest('(no cached descriptors)')
- return
+ raise stem.util.test_tools.SkipTest('(no cached descriptors)')
with open(descriptor_path, 'rb') as descriptor_file:
for desc in stem.descriptor.parse_file(descriptor_file, 'extra-info 1.0', validate = True):
@@ -32,12 +35,12 @@ class TestExtraInfoDescriptor(unittest.TestCase):
test.register_new_capability('Extra-info Line', line)
if desc.dir_v2_responses_unknown:
- self.fail('Unrecognized statuses on dirreq-v2-resp lines: %s' % desc.dir_v2_responses_unknown)
+ raise AssertionError('Unrecognized statuses on dirreq-v2-resp lines: %s' % desc.dir_v2_responses_unknown)
elif desc.dir_v3_responses_unknown:
- self.fail('Unrecognized statuses on dirreq-v3-resp lines: %s' % desc.dir_v3_responses_unknown)
+ raise AssertionError('Unrecognized statuses on dirreq-v3-resp lines: %s' % desc.dir_v3_responses_unknown)
elif desc.dir_v2_direct_dl_unknown:
- self.fail('Unrecognized stats on dirreq-v2-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
+ raise AssertionError('Unrecognized stats on dirreq-v2-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
elif desc.dir_v3_direct_dl_unknown:
- self.fail('Unrecognized stats on dirreq-v3-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
+ raise AssertionError('Unrecognized stats on dirreq-v3-direct-dl lines: %s' % desc.dir_v2_direct_dl_unknown)
elif desc.dir_v2_tunneled_dl_unknown:
- self.fail('Unrecognized stats on dirreq-v2-tunneled-dl lines: %s' % desc.dir_v2_tunneled_dl_unknown)
+ raise AssertionError('Unrecognized stats on dirreq-v2-tunneled-dl lines: %s' % desc.dir_v2_tunneled_dl_unknown)
diff --git a/test/integ/descriptor/microdescriptor.py b/test/integ/descriptor/microdescriptor.py
index a38917a..cc48fce 100644
--- a/test/integ/descriptor/microdescriptor.py
+++ b/test/integ/descriptor/microdescriptor.py
@@ -6,25 +6,27 @@ import os
import unittest
import stem.descriptor
+import stem.util.test_tools
import test
-import test.require
-import test.runner
class TestMicrodescriptor(unittest.TestCase):
- @test.require.only_run_once
- def test_cached_microdescriptors(self):
+ @staticmethod
+ def run_tests(test_dir):
+ TestMicrodescriptor.test_cached_microdescriptors = stem.util.test_tools.AsyncTest(TestMicrodescriptor.test_cached_microdescriptors, args = (test_dir,), threaded = True).method
+
+ @staticmethod
+ def test_cached_microdescriptors(test_dir):
"""
Parses the cached microdescriptor file in our data directory, checking that
it doesn't raise any validation issues and looking for unrecognized
descriptor additions.
"""
- descriptor_path = test.runner.get_runner().get_test_dir('cached-microdescs')
+ descriptor_path = os.path.join(test_dir, 'cached-microdescs')
if not os.path.exists(descriptor_path):
- self.skipTest('(no cached microdescriptors)')
- return
+ raise stem.util.test_tools.SkipTest('(no cached descriptors)')
with open(descriptor_path, 'rb') as descriptor_file:
for desc in stem.descriptor.parse_file(descriptor_file, 'microdescriptor 1.0', validate = True):
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py
index 83383fd..46d7654 100644
--- a/test/integ/descriptor/networkstatus.py
+++ b/test/integ/descriptor/networkstatus.py
@@ -8,6 +8,7 @@ import unittest
import stem
import stem.descriptor
import stem.descriptor.remote
+import stem.util.test_tools
import stem.version
import test
import test.require
@@ -15,6 +16,11 @@ import test.runner
class TestNetworkStatus(unittest.TestCase):
+ @staticmethod
+ def run_tests(test_dir):
+ TestNetworkStatus.test_cached_consensus = stem.util.test_tools.AsyncTest(TestNetworkStatus.test_cached_consensus, args = (test_dir,), threaded = True).method
+ TestNetworkStatus.test_cached_microdesc_consensus = stem.util.test_tools.AsyncTest(TestNetworkStatus.test_cached_microdesc_consensus, args = (test_dir,), threaded = True).method
+
@test.require.only_run_once
@test.require.online
@test.require.cryptography
@@ -26,23 +32,21 @@ class TestNetworkStatus(unittest.TestCase):
stem.descriptor.remote.get_consensus(document_handler = stem.descriptor.DocumentHandler.DOCUMENT, validate = True).run()
- @test.require.only_run_once
- def test_cached_consensus(self):
+ @staticmethod
+ def test_cached_consensus(test_dir):
"""
Parses the cached-consensus file in our data directory.
"""
- consensus_path = test.runner.get_runner().get_test_dir('cached-consensus')
+ consensus_path = os.path.join(test_dir, 'cached-consensus')
if not os.path.exists(consensus_path):
- self.skipTest('(no cached-consensus)')
- return
+ raise stem.util.test_tools.SkipTest('(no cached-consensus)')
elif stem.util.system.is_windows():
# Unable to check memory usage on windows, so can't prevent hanging the
# system if things go bad.
- self.skipTest('(unavailable on windows)')
- return
+ raise stem.util.test_tools.SkipTest('(unavailable on windows)')
count, reported_flags = 0, []
@@ -61,22 +65,21 @@ class TestNetworkStatus(unittest.TestCase):
# Sanity test that there's at least a hundred relays. If that's not the
# case then this probably isn't a real, complete tor consensus.
- self.assertTrue(count > 100)
+ if count < 100:
+ raise AssertionError('%s only included %s relays' % (consensus_path, count))
- @test.require.only_run_once
- def test_cached_microdesc_consensus(self):
+ @staticmethod
+ def test_cached_microdesc_consensus(test_dir):
"""
Parses the cached-microdesc-consensus file in our data directory.
"""
- consensus_path = test.runner.get_runner().get_test_dir('cached-microdesc-consensus')
+ consensus_path = os.path.join(test_dir, 'cached-microdesc-consensus')
if not os.path.exists(consensus_path):
- self.skipTest('(no cached-microdesc-consensus)')
- return
+ raise stem.util.test_tools.SkipTest('(no cached-microdesc-consensus)')
elif stem.util.system.is_windows():
- self.skipTest('(unavailable on windows)')
- return
+ raise stem.util.test_tools.SkipTest('(unavailable on windows)')
count, reported_flags = 0, []
@@ -92,4 +95,5 @@ class TestNetworkStatus(unittest.TestCase):
for line in router.get_unrecognized_lines():
test.register_new_capability('Microdescriptor Consensus Line', line, suppression_token = line.split()[0])
- self.assertTrue(count > 100)
+ if count < 100:
+ raise AssertionError('%s only included %s relays' % (consensus_path, count))
diff --git a/test/integ/descriptor/server_descriptor.py b/test/integ/descriptor/server_descriptor.py
index 7a234e3..0726c35 100644
--- a/test/integ/descriptor/server_descriptor.py
+++ b/test/integ/descriptor/server_descriptor.py
@@ -6,33 +6,34 @@ import os
import unittest
import stem.descriptor
+import stem.util.test_tools
import test
-import test.require
-import test.runner
class TestServerDescriptor(unittest.TestCase):
- @test.require.only_run_once
- def test_cached_descriptor(self):
+ @staticmethod
+ def run_tests(test_dir):
+ TestServerDescriptor.test_cached_descriptor = stem.util.test_tools.AsyncTest(TestServerDescriptor.test_cached_descriptor, args = (test_dir,), threaded = True).method
+
+ @staticmethod
+ def test_cached_descriptor(test_dir):
"""
Parses the cached descriptor file in our data directory, checking that it
doesn't raise any validation issues and looking for unrecognized descriptor
additions.
"""
- descriptor_path = test.runner.get_runner().get_test_dir('cached-descriptors')
+ descriptor_path = os.path.join(test_dir, 'cached-descriptors')
if not os.path.exists(descriptor_path):
- self.skipTest('(no cached descriptors)')
- return
+ raise stem.util.test_tools.SkipTest('(no cached descriptors)')
with open(descriptor_path, 'rb') as descriptor_file:
for desc in stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0', validate = True):
# the following attributes should be deprecated, and not appear in the wild
- self.assertEqual(None, desc.read_history_end)
- self.assertEqual(None, desc.write_history_end)
- self.assertEqual(None, desc.eventdns)
- self.assertEqual(None, desc.socks_port)
+
+ if desc.read_history_end or desc.write_history_end or desc.eventdns or desc.socks_port:
+ raise AssertionError('deprecated attribute appeared on: %s' % desc)
for line in desc.get_unrecognized_lines():
test.register_new_capability('Server Descriptor Line', line)
diff --git a/test/integ/installation.py b/test/integ/installation.py
index 7cf5346..0253efd 100644
--- a/test/integ/installation.py
+++ b/test/integ/installation.py
@@ -58,7 +58,7 @@ class TestInstallation(unittest.TestCase):
def run_tests():
test_install = stem.util.test_tools.AsyncTest(TestInstallation.test_install)
TestInstallation.test_install = test_install.method
- TestInstallation.test_sdist = stem.util.test_tools.AsyncTest(TestInstallation.test_sdist, test_install.pid()).method
+ TestInstallation.test_sdist = stem.util.test_tools.AsyncTest(TestInstallation.test_sdist, args = (test_install.pid(),)).method
@staticmethod
def test_install():
diff --git a/test/integ/process.py b/test/integ/process.py
index 33e3927..09c51ed 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -48,10 +48,10 @@ def random_port():
class TestProcess(unittest.TestCase):
@staticmethod
def run_tests(tor_cmd):
- TestProcess.test_launch_tor_with_config_via_file = stem.util.test_tools.AsyncTest(TestProcess.test_launch_tor_with_config_via_file, tor_cmd).method
- TestProcess.test_launch_tor_with_config_via_stdin = stem.util.test_tools.AsyncTest(TestProcess.test_launch_tor_with_config_via_stdin, tor_cmd).method
- TestProcess.test_take_ownership_via_pid = stem.util.test_tools.AsyncTest(TestProcess.test_take_ownership_via_pid, tor_cmd).method
- TestProcess.test_take_ownership_via_controller = stem.util.test_tools.AsyncTest(TestProcess.test_take_ownership_via_controller, tor_cmd).method
+ TestProcess.test_launch_tor_with_config_via_file = stem.util.test_tools.AsyncTest(TestProcess.test_launch_tor_with_config_via_file, args = (tor_cmd,)).method
+ TestProcess.test_launch_tor_with_config_via_stdin = stem.util.test_tools.AsyncTest(TestProcess.test_launch_tor_with_config_via_stdin, args = (tor_cmd,)).method
+ TestProcess.test_take_ownership_via_pid = stem.util.test_tools.AsyncTest(TestProcess.test_take_ownership_via_pid, args = (tor_cmd,)).method
+ TestProcess.test_take_ownership_via_controller = stem.util.test_tools.AsyncTest(TestProcess.test_take_ownership_via_controller, args = (tor_cmd,)).method
def setUp(self):
self.data_directory = tempfile.mkdtemp()
diff --git a/test/settings.cfg b/test/settings.cfg
index 4ba2f12..52bd013 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -227,11 +227,6 @@ test.integ_tests
|test.integ.util.proc.TestProc
|test.integ.util.system.TestSystem
|test.integ.interpreter.TestInterpreter
-|test.integ.descriptor.remote.TestDescriptorDownloader
-|test.integ.descriptor.server_descriptor.TestServerDescriptor
-|test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor
-|test.integ.descriptor.microdescriptor.TestMicrodescriptor
-|test.integ.descriptor.networkstatus.TestNetworkStatus
|test.integ.version.TestVersion
|test.integ.manual.TestManual
|test.integ.response.protocolinfo.TestProtocolInfo
@@ -241,6 +236,11 @@ test.integ_tests
|test.integ.connection.connect.TestConnect
|test.integ.control.base_controller.TestBaseController
|test.integ.control.controller.TestController
+|test.integ.descriptor.remote.TestDescriptorDownloader
+|test.integ.descriptor.server_descriptor.TestServerDescriptor
+|test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor
+|test.integ.descriptor.microdescriptor.TestMicrodescriptor
+|test.integ.descriptor.networkstatus.TestNetworkStatus
|test.integ.installation.TestInstallation
|test.integ.process.TestProcess
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits