Commit 2fdb6067 authored by Jérome Perrin's avatar Jérome Perrin

fixup! Propagate cancellation to spawned test jobs

parent 3f3872a2
...@@ -25,6 +25,7 @@ import time ...@@ -25,6 +25,7 @@ import time
from os.path import dirname from os.path import dirname
from golang import chan, select, default, func, defer from golang import chan, select, default, func, defer
from golang import context, sync from golang import context, sync
import psutil
import pytest import pytest
...@@ -165,3 +166,67 @@ TestCase('TEST_WITH_PROCLEAK', ['%s', 'AAA', 'BBB', 'CCC']) ...@@ -165,3 +166,67 @@ TestCase('TEST_WITH_PROCLEAK', ['%s', 'AAA', 'BBB', 'CCC'])
assert "AAA: terminating" in captured.out assert "AAA: terminating" in captured.out
assert "BBB: terminating" in captured.out assert "BBB: terminating" in captured.out
assert "CCC: terminating" in captured.out assert "CCC: terminating" in captured.out
@pytest.fixture
def distributor_with_cancelled_test(mocker):
"""A distributor for a test result with one test result line named TEST1.
test_result.isAlive() will return False after 2 invocations, to simulate
a test_result that was cancelled by distributor.
"""
def _retryRPC(func_id, args=()):
if func_id == 'getProtocolRevision':
return 1
assert False, ('unexpected RPC call', (func_id, args))
mocker.patch(
'erp5.util.taskdistribution.RPCRetry._retryRPC',
side_effect=_retryRPC)
test_result_line_proxy = mocker.patch(
'erp5.util.taskdistribution.TestResultLineProxy',
autospec=True)
type(test_result_line_proxy).name = mocker.PropertyMock(return_value='TEST1')
test_result_proxy = mocker.patch(
'erp5.util.taskdistribution.TestResultProxy',
autospec=True)
test_result_proxy.start.side_effect = [test_result_line_proxy, None]
test_result_proxy.isAlive.side_effect = [True, True, False]
mocked_createTestResult = mocker.patch(
'erp5.util.taskdistribution.TaskDistributor.createTestResult',
return_value=test_result_proxy)
yield
mocked_createTestResult.assert_called_once()
test_result_proxy.start.assert_called()
test_result_proxy.isAlive.assert_called()
test_result_line_proxy.stop.assert_called()
@pytest.mark.timeout(timeout=10)
def test_distributor_timeout(run_nxdtest, capsys, tmp_path, distributor_with_cancelled_test, mocker):
# nxdtest polls every 5 minutes, but in test we don't want to wait so long
mocker.patch('nxdtest.time.minute', 0.05)
slow = "%s/testprog/slow" % (dirname(__file__),)
pidfile = str(tmp_path / 'slow.pid')
run_nxdtest(
"""\
TestCase('TEST1', ['%s', '%s'])
""" % (slow, pidfile),
argv=[
"nxdtest",
"--master_url", "http://localhost",
],
)
captured = capsys.readouterr()
assert "TEST1" in captured.out
assert "# test run canceled" in captured.out
assert captured.err == ''
with open(pidfile) as f:
pid = int(f.read())
assert not psutil.pid_exists(pid)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2021 Nexedi SA and Contributors.
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
"""Program slow helps to verify that nxdtest terminates processes when interrupted."""
from __future__ import print_function, absolute_import
import os
import sys
import time
from setproctitle import setproctitle
def main():
pidfile = sys.argv[1]
with open(pidfile, 'w') as f:
f.write(str(os.getpid()))
setproctitle('slow @%s' % pidfile)
time.sleep(60)
if __name__ == '__main__':
main()
...@@ -15,7 +15,7 @@ setup( ...@@ -15,7 +15,7 @@ setup(
packages = find_packages(), packages = find_packages(),
install_requires = ['erp5.util', 'six', 'pygolang', 'psutil'], install_requires = ['erp5.util', 'six', 'pygolang', 'psutil'],
extras_require = { extras_require = {
'test': ['pytest', 'pytest-timeout', 'setproctitle'], 'test': ['pytest', 'pytest-mock', 'pytest-timeout', 'setproctitle'],
}, },
entry_points= {'console_scripts': ['nxdtest = nxdtest:main']}, entry_points= {'console_scripts': ['nxdtest = nxdtest:main']},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment