commit de97e243e241ee34df6333e5557f4a3fcea9900d Author: Damian Johnson atagar@torproject.org Date: Sun Jun 4 16:52:41 2017 -0700
Parallelize longest process test
I plan to do 'em all but starting with one as a proof of concept. This drops the test runtime from 48s to 36s on my system (25% faster). --- run_tests.py | 9 ++++- test/integ/installation.py | 1 + test/integ/process.py | 99 ++++++++++++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 40 deletions(-)
diff --git a/run_tests.py b/run_tests.py index a174f65..2798fd4 100755 --- a/run_tests.py +++ b/run_tests.py @@ -29,6 +29,7 @@ import stem.version import test import test.arguments import test.integ.installation +import test.integ.process import test.output import test.runner import test.task @@ -232,8 +233,12 @@ def main():
skipped_tests = 0
- if args.run_integ and (not args.specific_test or 'test.integ.installation'.startswith(args.specific_test)): - test.integ.installation.setup() + if args.run_integ: + if not args.specific_test or 'test.integ.installation'.startswith(args.specific_test): + test.integ.installation.setup() + + if not args.specific_test or 'test.integ.process'.startswith(args.specific_test): + test.integ.process.setup(args.tor_path)
if args.run_unit: test.output.print_divider('UNIT TESTS', True) diff --git a/test/integ/installation.py b/test/integ/installation.py index 8b39e9d..2b58e1d 100644 --- a/test/integ/installation.py +++ b/test/integ/installation.py @@ -12,6 +12,7 @@ import unittest
import stem import stem.util.system +import stem.util.test_tools import test
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" diff --git a/test/integ/process.py b/test/integ/process.py index 207d4b4..5677be1 100644 --- a/test/integ/process.py +++ b/test/integ/process.py @@ -18,6 +18,7 @@ import stem.process import stem.socket import stem.util.str_tools import stem.util.system +import stem.util.test_tools import stem.util.tor_tools import stem.version import test.require @@ -38,6 +39,64 @@ PublishServerDescriptor 0 DataDirectory %s """
+TEST_TAKE_OWNERSHIP_BY_PID = None + + +def setup(tor_cmd): + global TEST_TAKE_OWNERSHIP_BY_PID + + TEST_TAKE_OWNERSHIP_BY_PID = stem.util.test_tools.AsyncTestResult(_test_take_ownership_via_pid, tor_cmd) + + +def _test_take_ownership_via_pid(tor_cmd): + """ + Checks that the tor process quits after we do if we set take_ownership. To + test this we spawn a process and trick tor into thinking that it is us. + """ + + if not stem.util.system.is_available('sleep'): + raise stem.util.test_tools.SkipTest('(sleep unavailable)') + elif test.tor_version() < stem.version.Requirement.TAKEOWNERSHIP: + raise stem.util.test_tools.SkipTest('(requires )' % stem.version.Requirement.TAKEOWNERSHIP) + + data_directory = tempfile.mkdtemp() + + try: + sleep_process = subprocess.Popen(['sleep', '60']) + + tor_process = stem.process.launch_tor_with_config( + tor_cmd = tor_cmd, + config = { + 'SocksPort': '2779', + 'ControlPort': '2780', + 'DataDirectory': data_directory, + '__OwningControllerProcess': str(sleep_process.pid), + }, + completion_percent = 5, + ) + + # Kill the sleep command. Tor should quit shortly after. + + sleep_process.kill() + sleep_process.communicate() + + # tor polls for the process every fifteen seconds so this may take a + # while... + # + # https://trac.torproject.org/projects/tor/ticket/21281 + + start_time = time.time() + + while time.time() - start_time < 30: + if tor_process.poll() == 0: + return # tor exited + + time.sleep(0.01) + + raise AssertionError("tor didn't quit after the process that owned it terminated") + finally: + shutil.rmtree(data_directory) +
class TestProcess(unittest.TestCase): def setUp(self): @@ -425,49 +484,13 @@ 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)
- @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): + def test_take_ownership_via_pid(self): """ Checks that the tor process quits after we do if we set take_ownership. To test this we spawn a process and trick tor into thinking that it is us. """
- sleep_process = subprocess.Popen(['sleep', '60']) - getpid_mock.return_value = str(sleep_process.pid) - - tor_process = stem.process.launch_tor_with_config( - tor_cmd = test.runner.get_runner().get_tor_command(), - config = { - 'SocksPort': '2777', - 'ControlPort': '2778', - 'DataDirectory': self.data_directory, - }, - completion_percent = 5, - take_ownership = True, - ) - - # Kill the sleep command. Tor should quit shortly after. - - sleep_process.kill() - sleep_process.communicate() - - # tor polls for the process every fifteen seconds so this may take a - # while... - # - # https://trac.torproject.org/projects/tor/ticket/21281 - - start_time = time.time() - - while time.time() - start_time < 30: - if tor_process.poll() == 0: - return # tor exited - - time.sleep(0.01) - - self.fail("tor didn't quit after the process that owned it terminated") + TEST_TAKE_OWNERSHIP_BY_PID.result(self)
@test.require.only_run_once @test.require.version(stem.version.Requirement.TAKEOWNERSHIP)
tor-commits@lists.torproject.org