Changeset: 4eb82a063311 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/4eb82a063311 Modified Files: testing/Mtest.py.in testing/sqllogictest.py Branch: Aug2024 Log Message:
More timeout cleanup. diffs (truncated from 418 to 300 lines): diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in --- a/testing/Mtest.py.in +++ b/testing/Mtest.py.in @@ -512,28 +512,6 @@ class Comment: def write(self, f, newline = False): f.write(str(self)) -class Timer: - # interface to the threading.Timer function that interprets a - # timeout of 0 as no timeout - def __init__(self, interval, function, args): - self.timer = None - self.function = function - self.args = args - self.interval = interval - - def settimeout(self, interval): - self.interval = interval - - def start(self): - if self.timer is None and self.interval > 0: - self.timer = threading.Timer(self.interval, self.function, args=self.args) - self.timer.start() - - def cancel(self): - if self.timer is not None: - self.timer.cancel() - self.timer = None - REV = '' # revision (output of hg id), default unknown black = 'black' # #000000 @@ -1354,7 +1332,7 @@ def PerformDir(env, testdir, testlist, t crs = dbh.cursor() try: crs.execute("call logging.setcomplevel('SQL_EXECUTION', 'INFO')") - except socket.timeout: + except TimeoutError: print('\nTimeout setting log level.\n') crs.close() dbh.close() @@ -1700,7 +1678,7 @@ def GetBitsAndModsAndThreads(env) : crs = dbh.cursor() try: crs.execute('select distinct module from sys.malfunctions() order by module') - except socket.timeout: + except TimeoutError: pass else: mods = crs.fetchall() @@ -2516,13 +2494,13 @@ def stacktrace(proc, outfile): with process.Popen(['gdb', '-p', str(proc.pid), '-batch', '-ex', 'thread apply all bt full'], stdout=process.PIPE, text=True) as p: try: + out, err = p.communicate(timeout=60) + except TimeoutExpired: # gdb sometimes hangs when trying to get the stack # trace: kill it mercilessly if it does - t = Timer(60, reallyKill, args = [p]) - t.start() - except AttributeError: - t = None - out, err = p.communicate() + p.kill() + p.wait() + out = err = '' if t is not None: t.cancel() except KeyboardInterrupt: @@ -2584,7 +2562,6 @@ class ServerClass: self.inmem = inmem self.dbg = dbg self.dbname = dbname - self.running = None self.lock = threading.Lock() def poll(self): @@ -2596,7 +2573,7 @@ class ServerClass: else: self.proc.terminate() try: - self.proc.wait(timeout=60) + self.proc.wait(timeout=30) except TimeoutExpired: self.proc.kill() self.wait() @@ -2607,14 +2584,15 @@ class ServerClass: self.errfile.close() def start(self, timeout): - self.running = Timer(timeout, self.stopsessions, []) - self.running.start() + if timeout: + self.timer = threading.Timer(timeout, self.stopsessions, []) + self.timer.start() def stop(self): if self.lock.acquire(): - if self.running: - self.running.cancel() - self.running = None + if self.timer: + self.timer.cancel() + self.timer = None self.lock.release() def sendusr1(self): @@ -2631,7 +2609,7 @@ class ServerClass: def stopsessions(self): if self.lock.acquire(blocking=False): try: - if self.running is not None: + if self.timer is not None: self.stacktrace() try: dbh = pymonetdb.connect(username='monetdb', @@ -2651,11 +2629,11 @@ class ServerClass: crs.execute(f'call sys.stopsession({x[0]})') if procdebug and not ids: print('no sessions to stop') - except socket.timeout: + except TimeoutError: self.proc.kill() crs.close() dbh.close() - self.running = None + self.timer = None finally: self.lock.release() @@ -2949,6 +2927,8 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te alltests=CONDITIONALS['KNOWNFAIL']) except KeyboardInterrupt: raise + except TimeoutError: + returncode = 'timeout' except: returncode = 'error' else: @@ -2956,10 +2936,13 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te sql.drop() except KeyboardInterrupt: raise + except TimeoutError: + returncode = 'timeout' except: pass - cmd = [sys.executable, TST + EXT, TST] - returncode = RunIt(cmd, False, '', ClntOut, ClntErr, TIMEOUT, pSrvr) + if returncode is None: + cmd = [sys.executable, TST + EXT, TST] + returncode = RunIt(cmd, False, '', ClntOut, ClntErr, TIMEOUT, pSrvr) elif CALL == 'sqltest' or CALL == 'maltest': issqllogictest = True import MonetDBtesting.sqllogictest as sqllogictest @@ -2979,6 +2962,8 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te alltests=CONDITIONALS['KNOWNFAIL']) except KeyboardInterrupt: raise + except TimeoutError: + returncode = 'timeout' except: returncode = 'error' else: @@ -2987,29 +2972,39 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te sql.drop() except KeyboardInterrupt: raise + except TimeoutError: + returncode = 'timeout' except: pass - defines = [] - if lang == 'sql' and os.path.exists(TST+'.test.in'): - for key in ('TSTDATAPATH', 'TSTSRCBASE', 'TSTSRCDIR', 'TSTTRGDIR', 'UTSTSRCDIR', 'TSTDB', 'MAPIPORT'): - if key in env: - defines.append(f'{key}={env[key]}') - try: - sql.parse(TST+EXT, approve=open(TST+'.newtest','w') if approve else None, defines=defines) - except KeyboardInterrupt: - raise - except sqllogictest.SQLLogicSyntaxError: - pass - except BrokenPipeError: - # server timeout - pass - except ConnectionResetError: - # server crash? - pass - except: - # something went wrong, we don't know what - # print a stack trace and continue - sys.excepthook(*sys.exc_info()) + if returncode is None: + defines = [] + if lang == 'sql' and os.path.exists(TST+'.test.in'): + for key in ('TSTDATAPATH', 'TSTSRCBASE', 'TSTSRCDIR', 'TSTTRGDIR', 'UTSTSRCDIR', 'TSTDB', 'MAPIPORT'): + if key in env: + defines.append(f'{key}={env[key]}') + try: + sql.parse(TST+EXT, approve=open(TST+'.newtest','w') if approve else None, defines=defines) + except KeyboardInterrupt: + raise + except sqllogictest.SQLLogicSyntaxError: + pass + except TimeoutError: + returncode = 'timeout' + except BrokenPipeError: + # server timeout + pass + except ConnectionResetError: + # server crash? + pass + except: + # something went wrong, we don't know what + # print a stack trace and continue + sys.excepthook(*sys.exc_info()) + else: + if sql.seenerr: + returncode = 'error' + elif sql.timedout: + returncode = 'timeout' elif CALL == 'sql': TSTs = [] test = re.compile('^'+TST+EXT+'$', re.MULTILINE) diff --git a/testing/sqllogictest.py b/testing/sqllogictest.py --- a/testing/sqllogictest.py +++ b/testing/sqllogictest.py @@ -50,6 +50,7 @@ import re import sys import platform import importlib +import time import MonetDBtesting.utils as utils from pathlib import Path from typing import Optional @@ -140,7 +141,8 @@ class SQLLogic: self.port = None self.approve = None self.threshold = 100 - self.seenerr = False + self.seenerr = False # there was an error before timeout + self.timedout = False # there was a timeout self.__last = '' self.srcdir = srcdir @@ -150,9 +152,18 @@ class SQLLogic: def __exit__(self, exc_type, exc_value, traceback): self.close() + def _remainingtime(self): + if self.timeout > 0: + t = time.time() + if self.starttime + self.timeout > t: + return self.starttime + self.timeout - t + return 0 + return -1 + def connect(self, username='monetdb', password='monetdb', hostname='localhost', port=None, database='demo', - language='sql', timeout=None, alltests=False): + language='sql', timeout: Optional[int]=0, alltests=False): + self.starttime = time.time() self.language = language self.hostname = hostname self.port = port @@ -162,24 +173,27 @@ class SQLLogic: if language == 'sql': transfer_handler = UnsafeDirectoryHandler(self.srcdir) self.dbh = pymonetdb.connect(username=username, - password=password, - hostname=hostname, - port=port, - database=database, - autocommit=True) + password=password, + hostname=hostname, + port=port, + database=database, + autocommit=True, + connect_timeout=timeout if timeout > 0 else -1) self.dbh.set_uploader(transfer_handler) self.dbh.set_downloader(transfer_handler) self.crs = self.dbh.cursor() else: dbh = malmapi.Connection() - dbh.connect( - database=database, - username=username, - password=password, - language=language, - hostname=hostname, - port=port) + dbh.connect(database=database, + username=username, + password=password, + language=language, + hostname=hostname, + port=port, + connect_timeout=timeout if timeout > 0 else -1) _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org