Update of /cvsroot/monetdb/MonetDB/src/testing
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv2710/src/testing
Modified Files:
Mtest.py.in difflib.c subprocess26.py
Log Message:
propagated changes of Monday Oct 22 2007 - Wednesday Oct 24 2007
from the MonetDB_1-20 branch to the development trunk
Index: Mtest.py.in
===================================================================
RCS file: /cvsroot/monetdb/MonetDB/src/testing/Mtest.py.in,v
retrieving revision 1.316
retrieving revision 1.317
diff -u -d -r1.316 -r1.317
--- Mtest.py.in 22 Oct 2007 12:23:30 -0000 1.316
+++ Mtest.py.in 24 Oct 2007 08:00:41 -0000 1.317
@@ -106,11 +106,8 @@
if os.environ.has_key('PYTHONPATH'):
p = p + os.pathsep + os.environ['PYTHONPATH']
os.environ['PYTHONPATH'] = p
-try:
- import subprocess
-except ImportError:
- # use private copy for old Python versions
- import MonetDB.subprocess26 as subprocess
+import MonetDB.subprocess26 as subprocess
+import threading, signal
randomPortRepeat = 9
@@ -1157,31 +1154,39 @@
def GetBitsAndOIDsAndModsAndStatic(env) :
rtrn = 0
TSTPREF = env['TSTPREF']
- cmd = '%s%s --dbname=%s' % (env['exe']['Mtimeout'][1],
env['exe']['Mserver'][1], TSTPREF)
+ cmd = '%s --dbname=%s' % (env['exe']['Mserver'][1], TSTPREF)
proc = subprocess.Popen(cmd, shell = True, stdin = subprocess.PIPE, stdout
= subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
- if par['M5']:
- input = '''\
- clients.quit();
- '''
- else:
- input = '''\
- help("kunion");
- {
- # print a list of all modules found
- # "Modules: mod1, mod2, ..."
- var MODs :=
kunion(bat("monet_mod_nme").reverse().mark(oid(nil)),view_modules().reverse().mark(oid(nil))).kunique();
- printf("\\nModules: ");
- var x := "";
- [EMAIL PROTECTED](){
- printf("%s\'%s\'",x,$h);
- x:=",";
+ t = threading.Timer(float(par['TIMEOUT']), killProc, args = [proc,
proc.stderr, cmd])
+ try:
+ t.start()
+ if par['M5']:
+ input = '''\
+ clients.quit();
+ '''
+ else:
+ input = '''\
+ help("kunion");
+ {
+ # print a list of all modules found
+ # "Modules: mod1, mod2, ..."
+ var MODs :=
kunion(bat("monet_mod_nme").reverse().mark(oid(nil)),view_modules().reverse().mark(oid(nil))).kunique();
+ printf("\\nModules: ");
+ var x := "";
+ [EMAIL PROTECTED](){
+ printf("%s\'%s\'",x,$h);
+ x:=",";
+ }
+ printf("\\n");
}
- printf("\\n");
- }
- quit();
- '''
- ##module("NoModule");
- qOut, qErr = proc.communicate(input = input)
+ quit();
+ '''
+ ##module("NoModule");
+ qOut, qErr = proc.communicate(input = input)
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(proc, proc.stderr, cmd)
+ raise
env['TST_MODS'] = []
env['TST_BITS'] = ""
env['TST_OIDS'] = ""
@@ -1280,23 +1285,31 @@
# Warn("Monet5: Check, whether required BATs do exist, is not
possible, yet!")
return missing
- cmd = '%s%s --dbname=%s' % (env['exe']['Mtimeout'][1],
env['exe']['Mserver'][1], TSTDB)
+ cmd = '%s --dbname=%s' % (env['exe']['Mserver'][1], TSTDB)
proc = subprocess.Popen(cmd, shell = True, stdin = subprocess.PIPE, stdout
= subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
- qOut, qErr = proc.communicate('''\
- {
- # print a list of all persistent BATs
- # "BATs: bat1, bat2, ..."
- var BATs := view_bbp_name();
- printf("\\nBATs: ");
- var x := "";
- [EMAIL PROTECTED](){
- printf("%s\'%s\'",x,$t);
- x:=",";
+ t = threading.Timer(float(par['TIMEOUT']), killProc, args = [proc,
proc.stderr, cmd])
+ try:
+ t.start()
+ qOut, qErr = proc.communicate('''\
+ {
+ # print a list of all persistent BATs
+ # "BATs: bat1, bat2, ..."
+ var BATs := view_bbp_name();
+ printf("\\nBATs: ");
+ var x := "";
+ [EMAIL PROTECTED](){
+ printf("%s\'%s\'",x,$t);
+ x:=",";
+ }
+ printf("\\n");
}
- printf("\\n");
- }
- quit();
- ''')
+ quit();
+ ''')
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(proc, proc.stderr, cmd)
+ raise
TST_BATS = []
if qOut:
tb = re.compile("^BATs: (.*)$", re.MULTILINE)
@@ -1681,7 +1694,10 @@
TestErr.close()
t0 = time.time()
- DoIt (env, SERVER, CALL, TST, EXT, PRELUDE, TestOutFile, TestErrFile,
STIMEOUT, CTIMEOUT, TIMEOUT, MkillUsersAT, ME, MAPIsockets, XRPCsockets)
+ if DoIt(env, SERVER, CALL, TST, EXT, PRELUDE, TestOutFile,
TestErrFile, STIMEOUT, CTIMEOUT, TIMEOUT, MkillUsersAT, ME, MAPIsockets,
XRPCsockets):
+ timeout = F_TIME
+ else:
+ timeout = F_OK
t1 = time.time()
TX = t1 - t0
if not quiet:
@@ -1734,12 +1750,6 @@
##rm -f .new.left-over.tmp.bats.
$TSTTRGBASE/Tests/.old.left-over.tmp.bats.
##if [ -f .all.left-over.tmp.bats. ] ; then mv -f
.all.left-over.tmp.bats. $TSTTRGBASE/Tests/.old.left-over.tmp.bats. ; fi
- timeout = F_OK
- mto = re.compile("^!(Mtimeout:)? Timeout:", re.MULTILINE)
- for l in open(TestErr.name):
- if mto.match(l):
- timeout = F_TIME
-
if timeout == F_TIME:
if quiet:
STDOUT.write("\n%s : Timeout!\n" % TST)
@@ -1792,11 +1802,6 @@
MDIFF0 = env['exe']['Mdiff'][1]
MDIFF1 = MDIFF0+' -d'
- if env['exe']['Mtimeout'][0]:
- if quiet:
- MDIFF1 = env['exe']['Mtimeout'][1]+' -q '+MDIFF1
- else:
- MDIFF1 = env['exe']['Mtimeout'][1]+' '+MDIFF1
#TODO:
#timedout = 1
@@ -1828,13 +1833,26 @@
# filesizes differ significantly => expect major
differences!
ACCURACYout = -1
while timedout and MDIFF == MDIFF1:
+ cmd = ['Mdiff']
if ACCURACYout == -1:
MDIFF = MDIFF0
ACCURACYout = 0
- if not quiet:
- timedout = os.system('%s -I"%s" "%s" -A%d -r"%s"
"%s%s.FILTERED" "%s.test.out.FILTERED" "%s.out.diff.html"' % (MDIFF,
par['IGNORE'], par['CONTEXT'], ACCURACYout, REVe, TST, STABLEout, TST, TST))
else:
- timedout = os.system('%s -q -I"%s" "%s" -A%d -r"%s"
"%s%s.FILTERED" "%s.test.out.FILTERED" "%s.out.diff.html"' % (MDIFF,
par['IGNORE'], par['CONTEXT'], ACCURACYout, REVe, TST, STABLEout, TST, TST))
+ cmd.append('-d')
+ if quiet:
+ cmd.append('-q')
+ proc = subprocess.Popen(cmd + ['-I%s' % par['IGNORE'],
par['CONTEXT'], '-A%d' % ACCURACYout, '-r%s' % REVe, '%s%s.FILTERED' % (TST,
STABLEout), '%s.test.out.FILTERED' % TST, '%s.out.diff.html' % TST])
+ proc.killed = False
+ t = threading.Timer(float(par['TIMEOUT']), killProc, args =
[proc])
+ try:
+ t.start()
+ proc.wait()
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(proc)
+ raise
+ timedout = proc.killed
ACCURACYout = ACCURACYout - 1
#TODO:
@@ -2006,6 +2024,15 @@
return prmpt+prmpt+cmd+prmpt+"\n\n"
### Prompt(cmd) #
+def killProc(proc, outfile = None, cmd = None):
+ try:
+ os.kill(-proc.pid, signal.SIGTERM)
+ except AttributeError:
+ subprocess.Popen(['pskill','-t',str(proc.pid)])
+ if outfile is not None and cmd is not None:
+ outfile.write('\n!Mtimeout: Timeout: %s\n' % cmd)
+ proc.killed = True
+
def LaunchIt(cmd, TestInput, TestOut, TestErr) :
TestOut.write(Prompt(cmd))
TestOut.flush()
@@ -2033,7 +2060,7 @@
TestOut.write(buf)
### CollectIt(pOut, pErr, TestOut, TestErr) #
-def RunIt(cmd, TestIn, TestOut, TestErr) :
+def RunIt(cmd, TestIn, TestOut, TestErr, TimeOut) :
if type(TestIn) is type(''):
TestInput = TestIn
TestIn = subprocess.PIPE
@@ -2044,9 +2071,19 @@
TestErr.write(Prompt(cmd))
TestErr.flush()
proc = subprocess.Popen(cmd, shell = True, stdin = TestIn, stdout =
TestOut, stderr = TestErr, universal_newlines = True)
- # since both stdout and stderr are redirected to files,
- # communicate will not return any useful data
- proc.communicate(input = TestInput)
+ proc.killed = False
+ t = threading.Timer(TimeOut, killProc, args = [proc, TestErr, cmd])
+ try:
+ t.start()
+ # since both stdout and stderr are redirected to files,
+ # communicate will not return any useful data
+ proc.communicate(input = TestInput)
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(proc, TestErr, cmd)
+ raise
+ return proc.killed
### RunIt(cmd, TestIn, TestOut, TestErr) #
def Log() :
@@ -2095,16 +2132,6 @@
Warn("Flushing STDOUT in DoIt failed with #%d: '%s'." % (IOerrNo,
IOerrStr))
TSTDB = env['TSTDB']
exe = env['exe']
- if exe['Mtimeout'][0]:
- MTO = "Mtimeout -timeout "
- TOT = TIMEOUT
- STO = STIMEOUT
- CTO = CTIMEOUT
- else:
- MTO = ""
- TOT = ""
- STO = ""
- CTO = ""
LOCAL_CONF = ""
if os.path.isfile(TST+".conf"):
@@ -2140,7 +2167,7 @@
if os.path.isfile(TST+".prologue5") and par['M5']:
PROLOGUE = " "+TST+".prologue5"
- Srvr = '%s%s %s%s "--dbname=%s"' % (MTO, str(STO), exe['Mserver'][1],
LOCAL_CONF, TSTDB)
+ Srvr = '%s%s "--dbname=%s"' % (exe['Mserver'][1], LOCAL_CONF, TSTDB)
DBINIT=""
if os.path.isfile(TST+".dbinit") and par['M4']:
@@ -2194,15 +2221,16 @@
ClntOut = open(TestOutFile, 'a')
ClntErr = open(TestErrFile, 'a')
+ killed = False
if ServerReady:
if CALL == "other":
- cmd = MTO+str(CTO)+" "+os.path.join(".",TST+EXT)+" "+TST+"
"+PRELUDE
- RunIt(cmd, "", ClntOut, ClntErr)
+ cmd = os.path.join(".",TST+EXT)+" "+TST+" "+PRELUDE
+ killed = RunIt(cmd, "", ClntOut, ClntErr, CTIMEOUT)
elif CALL == "python":
- cmd = MTO+str(CTO)+" "+exe['python'][1]+" "+TST+EXT+" "+TST+"
"+PRELUDE
- RunIt(cmd, "", ClntOut, ClntErr)
+ cmd = exe['python'][1]+" "+TST+EXT+" "+TST+" "+PRELUDE
+ killed = RunIt(cmd, "", ClntOut, ClntErr, CTIMEOUT)
elif CALL in ["mal", "malXs", "milS", "milSXs"]:
- cmd = '%s%s %s%s --dbname=%s %s ' % (MTO, str(TOT),
exe['Mserver'][1], LOCAL_CONF, TSTDB, PRELUDE)
+ cmd = '%s%s --dbname=%s %s ' % (exe['Mserver'][1], LOCAL_CONF,
TSTDB, PRELUDE)
if CALL in ["mal", "milS"]:
X=""
else:
@@ -2213,11 +2241,13 @@
for f in d:
if test.match(f):
if CALL == "mal":
- RunIt(cmd + f, open(devnull), ClntOut, ClntErr)
+ killed = RunIt(cmd + f, open(devnull), ClntOut,
ClntErr, TIMEOUT)
elif par['M5']:
- RunIt(cmd+" --dbinit=\"include mil_scenario; mil();\"
"+f, open(devnull), ClntOut, ClntErr)
+ killed = RunIt(cmd+" --dbinit=\"include mil_scenario;
mil();\" "+f, open(devnull), ClntOut, ClntErr, TIMEOUT)
else:
- RunIt(cmd, open(f), ClntOut, ClntErr)
+ killed = RunIt(cmd, open(f), ClntOut, ClntErr, TIMEOUT)
+ if killed:
+ break
elif CALL in ["milC", "milCXs", "malC", "malCXs"]:
TSTs = []
if CALL in ("milC", "malC"):
@@ -2231,13 +2261,16 @@
if test.match(f):
TSTs.append(f)
- Clnt = MTO+str(TOT)+" "
if CALL[:3] == "mil":
- Clnt = Clnt+exe['MIL_Client'][1]
- if CALL[:3] == "mal":
- Clnt = Clnt+exe['MAL_Client'][1]
+ Clnt = exe['MIL_Client'][1]
+ elif CALL[:3] == "mal":
+ Clnt = exe['MAL_Client'][1]
+ else:
+ Clnt = '' # cannot happen
for f in TSTs:
- RunIt(Clnt, open(f), ClntOut, ClntErr)
+ killed = RunIt(Clnt, open(f), ClntOut, ClntErr, TIMEOUT)
+ if killed:
+ break
#TODO
#elif CALL == "milCXp":
@@ -2254,9 +2287,11 @@
if test.match(f):
TSTs.append(f)
- Clnt = MTO+str(TOT)+" "+exe['SQL_Client'][1]
+ Clnt = exe['SQL_Client'][1]
for f in TSTs:
- RunIt(Clnt, open(f), ClntOut, ClntErr)
+ killed = RunIt(Clnt, open(f), ClntOut, ClntErr, TIMEOUT)
+ if killed:
+ break
elif CALL in ["xq", "xqXs"]:
TSTs = []
if CALL == "xq":
@@ -2270,9 +2305,11 @@
if test.match(f):
TSTs.append(f)
- Clnt = MTO+str(TOT)+" "+exe['XQuery_Client'][1]+" "
+ Clnt = exe['XQuery_Client'][1]+" "
for f in TSTs:
- RunIt(Clnt+f, "", ClntOut, ClntErr)
+ killed = RunIt(Clnt+f, "", ClntOut, ClntErr, TIMEOUT)
+ if killed:
+ break
elif CALL in ["x100", "x100Xs"]:
TSTs = []
if CALL == "x100":
@@ -2286,9 +2323,11 @@
if test.match(f):
TSTs.append(f)
- Clnt = MTO+str(TOT)+" "+exe['X100_Client'][1]
+ Clnt = exe['X100_Client'][1]
for f in TSTs:
- RunIt(Clnt, open(f), ClntOut, ClntErr)
+ killed = RunIt(Clnt, open(f), ClntOut, ClntErr, TIMEOUT)
+ if killed:
+ break
else:
for fp in ClntOut,ClntErr:
fp.write('\n\n! Server not ready; skipping attempt to start
client!\n\n')
@@ -2335,7 +2374,17 @@
if MkillUsersAT:
ATJOB2 = StartAt(MkillUsersAT)
- CollectIt(pSrvr.stdout, SrvrOut)
+ pSrvr.killed = False
+ t = threading.Timer(TIMEOUT, killProc, args = [pSrvr, SrvrErr, Srvr])
+ try:
+ t.start()
+ CollectIt(pSrvr.stdout, SrvrOut)
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(pSrvr, SrvrErr, Srvr)
+ raise
+ killed = killed or pSrvr.killed
if MkillUsersAT:
StopAt(ATJOB2,ME)
@@ -2378,15 +2427,26 @@
if TestErr is not None:
TestErr.write(Prompt('Done.'))
TestErr.close()
+ return killed
### DoIt(env, SERVER, CALL, TST, EXT, PRELUDE, TestOut, TestErr, STIMEOUT,
CTIMEOUT, TIMEOUT, MkillUsersAT, ME, MAPIsockets, XRPCsockets) #
def Check(command, input) :
- proc = subprocess.Popen(command+" || echo ! Exit 1", shell = True, stdin =
subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE,
universal_newlines = True)
- qOut, qErr = proc.communicate(input = input)
+ proc = subprocess.Popen(command, shell = True, stdin = subprocess.PIPE,
stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
+ t = threading.Timer(float(par['TIMEOUT']), killProc, args = [proc])
+ try:
+ t.start()
+ qOut, qErr = proc.communicate(input = input)
+ t.cancel()
+ except KeyboardInterrupt:
+ t.cancel()
+ killProc(proc)
+ raise
qOut = qOut.split('\n')
qErr = qErr.split('\n')
+ if proc.returncode:
+ qOut.append('! Exit 1')
test = re.compile( r"^!WARNING: BATpropcheck: "
"|"
r"^!WARNING: monet_checkbat: "
"|"
r"^!WARNING: GDKlockHome: ignoring empty or invalid
.gdk_lock." "|"
@@ -2871,12 +2931,9 @@
if THISFILE == "Mtest.py":
par['IGNORE'] = opts.get('ignore', dftIGNORE)
par['CONTEXT'] = '-C%d' % int(opts.get('context', 1))
- a = int(opts.get('accuracy', (os.name != 'nt' and 1) or 0))
+ a = int(opts.get('accuracy', 1))
if a not in (-1,0,1,2):
ErrExit('Accuracy for diff (-A) must be one of: 0=lines, 1=words,
2=chars !')
- if os.name == "nt" and a != 0:
- Warn("Currently only '-A0` is supported on WindowsNT!")
- a = 0
par['ACCURACY'] = a
par['TIMEOUT'] = int(opts.get('timeout', 60))
a = opts.get('debug')
@@ -3288,7 +3345,7 @@
QUIT = 'quit();\n'
if par['PACKAGE'] not in ('monetdb', 'monetdb-clients'):
- if Check('%s%s --dbname=%s' % (env['exe']['Mtimeout'][1],
env['exe']['Mserver'][1], TSTPREF), QUIT):
+ if Check('%s --dbname=%s' % (env['exe']['Mserver'][1], TSTPREF),
QUIT):
sys.exit(1)
if GetBitsAndOIDsAndModsAndStatic(env):
sys.exit(1)
Index: difflib.c
===================================================================
RCS file: /cvsroot/monetdb/MonetDB/src/testing/difflib.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- difflib.c 9 Sep 2007 11:36:22 -0000 1.47
+++ difflib.c 24 Oct 2007 08:00:42 -0000 1.48
@@ -147,27 +147,10 @@
stat(new_fn, &new_fstat);
if ((old_fstat.st_size != 0) && (new_fstat.st_size != 0)) {
-#ifdef NATIVE_WIN32
- sprintf(command, "%s %s %s.cp > nul", COPY, old_fn, old_fn);
- SYSTEM(command);
- sprintf(command, "%s %s %s.cp > nul", COPY, new_fn, new_fn);
- SYSTEM(command);
-
- sprintf(command, "%s %s -a %s -U%d %s.cp %s.cp > %s", DIFF,
ignore, _d, context, old_fn, new_fn, u_diff_fn);
-#else
sprintf(command, "%s %s -a %s -U%d %s %s > %s", DIFF,
ignore, _d, context, old_fn, new_fn, u_diff_fn);
-#endif
SYSTEM(command);
-#ifdef NATIVE_WIN32
-#ifdef DEBUG
- sprintf(command, "dir %s* %s* %s*", old_fn, new_fn, u_diff_fn);
- SYSTEM(command);
-#endif
- sprintf(command, "del %s.cp %s.cp", old_fn, new_fn);
- SYSTEM(command);
-#endif
} else {
u_diff_fp = Wfopen(u_diff_fn);
fprintf(u_diff_fp, "--- %s\t%s", old_fn,
ctime(&old_fstat.st_mtime));
@@ -348,27 +331,10 @@
SYSTEM(command);
*/
-#ifdef NATIVE_WIN32
- sprintf(command, "%s %s %s.cp > nul", COPY, fn[0], fn[0]);
- SYSTEM(command);
- sprintf(command, "%s %s %s.cp > nul", COPY, fn[1], fn[1]);
- SYSTEM(command);
-
- sprintf(command, "%s -a %s -U%d %s.cp %s.cp > %s", DIFF, _d,
MAX(l[0], l[1]), fn[0], fn[1], pipe_fn);
-#else
sprintf(command, "%s -a %s -U%d %s %s > %s", DIFF, _d,
MAX(l[0], l[1]), fn[0], fn[1], pipe_fn);
-#endif
SYSTEM(command);
-#ifdef NATIVE_WIN32
-#ifdef DEBUG
- sprintf(command, "dir %s* %s* %s*", fn[0], fn[1], pipe_fn);
- SYSTEM(command);
-#endif
- sprintf(command, "del %s.cp %s.cp", fn[0], fn[1]);
- SYSTEM(command);
-#endif
pipe_fp = Rfopen(pipe_fn);
wc_diff_fp = Afopen(wc_diff_fn);
@@ -678,12 +644,6 @@
*old_time++ = '\0';
new_time = strchr(new, '\t') + 1;
*new_time++ = '\0';
-#ifdef NATIVE_WIN32
- if (!strcmp(strrchr(old, '.'), ".cp"))
- *strrchr(old, '.') = '\0';
- if (!strcmp(strrchr(new, '.'), ".cp"))
- *strrchr(new, '.') = '\0';
-#endif
fprintf(html_fp, "<TR><TH COLSPAN=3 ALIGN=CENTER><FONT SIZE=3
COLOR=#0000ff><CODE><A HREF='%s'>%s%s</A>\t%s</CODE></FONT></TH>",
filename(old), filename(old_fn), revision, old_time);
fprintf(html_fp, "<TH> </TH>");
fprintf(html_fp, "<TH COLSPAN=3 ALIGN=CENTER><FONT SIZE=3
COLOR=#ff0000><CODE><A HREF='%s'>%s</A>\t%s</CODE></FONT></TH></TR>\n", new,
new_fn, new_time);
Index: subprocess26.py
===================================================================
RCS file: /cvsroot/monetdb/MonetDB/src/testing/subprocess26.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- subprocess26.py 2 Apr 2007 20:40:17 -0000 1.2
+++ subprocess26.py 24 Oct 2007 08:00:42 -0000 1.3
@@ -1007,6 +1007,13 @@
if self.pid == 0:
# Child
try:
+ os.setpgrp()
+ except AttributeError:
+ try:
+ os.setpgid(0, 0)
+ except AttributeError:
+ pass
+ try:
# Close parent's pipe ends
if p2cwrite is not None:
os.close(p2cwrite)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Monetdb-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-checkins