Skip to content

Commit 1995640

Browse files
committed
Fix test-run crash when default server is crashed
Before this change, test-run crashed if the default tarantool server had crashed with a segmentation fault error due to a broken tarantool console handshake. Such a situation wasn't properly handled and the server's crash detector failed with the following traceback: Traceback (most recent call last): File "/usr/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap self.run() File "/usr/lib/python3.10/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) File "/tarantool/test-run/dispatcher.py", line 386, in _run_worker worker = self.gen_worker(worker_id) File "/tarantool/test-run/lib/worker.py", line 297, in __init__ self.stop_server(cleanup=False) File "/tarantool/test-run/lib/worker.py", line 301, in stop_server self.suite.stop_server(self.server, self.inspector, silent=silent, File "/tarantool/test-run/lib/test_suite.py", line 249, in stop_server server.stop(silent=silent) File "/tarantool/test-run/lib/tarantool_server.py", line 1092, in stop save_join(self.crash_detector) File "/tarantool/test-run/lib/tarantool_server.py", line 57, in save_join green_obj.get(timeout=timeout) File "src/gevent/greenlet.py", line 829, in gevent._gevent_cgreenlet.Greenlet.get File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception File "/home/tarantool/.local/lib/python3.10/site-packages/gevent/_compat.py", line 65, in reraise raise value.with_traceback(tb) File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run File "/tarantool/test-run/lib/test.py", line 35, in _run self.callable(*self.callable_args, **self.callable_kwargs) File "/tarantool/test-run/lib/tarantool_server.py", line 967, in crash_detect self.kill_current_test() File "/tarantool/test-run/lib/tarantool_server.py", line 1032, in kill_current_test if self.current_test.current_test_greenlet: AttributeError: 'NoneType' object has no attribute 'current_test_greenlet' Now test-run handles segmentation fault errors due to broken tarantool console handshake properly and reports servers' crashes. Fixes #398
1 parent ad43d8f commit 1995640

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

lib/admin_connection.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ def cmd(self, socket, cmd, silent):
8080
return res
8181

8282

83+
class BrokenConsoleHandshake(RuntimeError):
84+
pass
85+
86+
8387
class AdminConnection(TarantoolConnection, ExecMixIn):
8488
def execute_no_reconnect(self, command, silent):
8589
if not command:
@@ -93,7 +97,7 @@ def connect(self):
9397
super(AdminConnection, self).connect()
9498
handshake = get_handshake(self.socket)
9599
if not re.search(r'^Tarantool.*console.*', str(handshake)):
96-
raise RuntimeError('Broken tarantool console handshake')
100+
raise BrokenConsoleHandshake('Broken tarantool console handshake')
97101

98102

99103
class AdminAsyncConnection(TarantoolAsyncConnection, ExecMixIn):

lib/tarantool_server.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# Python 3
2727
from io import StringIO
2828

29-
from lib.admin_connection import AdminConnection, AdminAsyncConnection
29+
from lib.admin_connection import AdminConnection, AdminAsyncConnection, BrokenConsoleHandshake
3030
from lib.box_connection import BoxConnection
3131
from lib.colorer import color_stdout
3232
from lib.colorer import color_log
@@ -421,14 +421,17 @@ def execute(self, server):
421421

422422

423423
class TarantoolStartError(OSError):
424-
def __init__(self, name=None, timeout=None):
424+
def __init__(self, name=None, timeout=None, reason=None):
425425
self.name = name
426426
self.timeout = timeout
427+
self.reason = reason
427428

428429
def __str__(self):
429430
message = '[Instance "{}"] Failed to start'.format(self.name)
430431
if self.timeout:
431-
return "\n{} within {} seconds\n".format(message, self.timeout)
432+
message = "{} within {} seconds".format(message, self.timeout)
433+
if self.reason:
434+
message = "{}: {}".format(message, self.reason)
432435
return "\n{}\n".format(message)
433436

434437

@@ -957,7 +960,7 @@ def crash_detect(self):
957960
if self.process.returncode is None:
958961
gevent.sleep(0.1)
959962

960-
if self.process.returncode in [0, -signal.SIGKILL, -signal.SIGTERM]:
963+
if self.process.returncode in [0, -signal.SIGABRT, -signal.SIGKILL, -signal.SIGTERM]:
961964
return
962965

963966
self.kill_current_test()
@@ -1168,6 +1171,8 @@ def wait_until_started(self, wait_load=True, deadline=None):
11681171
gevent.sleep(0.1)
11691172
continue
11701173
raise
1174+
except BrokenConsoleHandshake as e:
1175+
raise TarantoolStartError(self.name, reason=e)
11711176
else:
11721177
raise TarantoolStartError(
11731178
self.name, Options().args.server_start_timeout)

lib/worker.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from lib.colorer import color_log
1414
from lib.colorer import color_stdout
1515
from lib.tarantool_server import TarantoolServer
16+
from lib.tarantool_server import TarantoolStartError
1617
from lib.test import get_result
1718
from lib.test_suite import TestSuite
1819
from lib.utils import safe_makedirs
@@ -285,6 +286,9 @@ def __init__(self, suite, _id):
285286
except KeyboardInterrupt:
286287
self.report_keyboard_interrupt()
287288
self.stop_server(cleanup=False)
289+
except TarantoolStartError as e:
290+
color_stdout(e, schema='error')
291+
self.stop_server(cleanup=False)
288292
except Exception as e:
289293
color_stdout('Worker "%s" cannot start tarantool server; '
290294
'the tasks will be ignored...\n' % self.name,

0 commit comments

Comments
 (0)