Changeset: ce1edf03f7f1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ce1edf03f7f1
Modified Files:
        testing/Mtest.py.in
        testing/sqllogictest.py
Branch: default
Log Message:

Merge with Aug2024 branch.


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()
@@ -1708,7 +1686,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()
@@ -2582,13 +2560,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:
@@ -2650,7 +2628,6 @@ class ServerClass:
         self.inmem = inmem
         self.dbg = dbg
         self.dbname = dbname
-        self.running = None
         self.lock = threading.Lock()
 
     def poll(self):
@@ -2662,7 +2639,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()
@@ -2673,14 +2650,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):
@@ -2697,7 +2675,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',
@@ -2717,11 +2695,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()
 
@@ -3015,6 +2993,8 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te
                                         alltests=CONDITIONALS['KNOWNFAIL'])
                         except KeyboardInterrupt:
                             raise
+                        except TimeoutError:
+                            returncode = 'timeout'
                         except:
                             returncode = 'error'
                         else:
@@ -3022,10 +3002,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
@@ -3045,6 +3028,8 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te
                                     alltests=CONDITIONALS['KNOWNFAIL'])
                     except KeyboardInterrupt:
                         raise
+                    except TimeoutError:
+                        returncode = 'timeout'
                     except:
                         returncode = 'error'
                     else:
@@ -3053,29 +3038,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

Reply via email to